C/C++教程

C++初阶---C++基础入门(未写完)

本文主要是介绍C++初阶---C++基础入门(未写完),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

C++基础入门

  • 1)前言
  • 2)C++关键字
  • 3)命名空间(namespace)
      • 1.namespace的使用
      • 2.命名空间的使用方式
  • 4)cout 与 cin
  • 5) 缺省参数
      • 1.全缺省参数
      • 2.半缺省参数
  • 6)函数重载
      • 1. 为什么C++支持函数重载,而C语言不支持函数重载?

1)前言

1979年,贝尔实验室的本贾尼等人试图分析unix内核的时候,试图将内核模块化,于是在C语言的基础上进行扩展,增加了类的机制,完成了一个可以运行的预处理程序,称之为C with classes

C++98C++标准第一个版本,绝大多数编译器都支持,得到了国际标准化组织(ISO)和美国标准化协会认可,以模板方式重写C++标准库,引入了STL(标准模板库)


C++11增加了许多特性,使得C++更像一种新语言,比如:正则表达式、基于范围for循环、auto关键字、新容器、列表初始化、标准线程库等


C++14对C++11的扩展,主要是修复C++11中漏洞以及改进,比如:泛型的lambda表达式,auto的返回值类型推导,二进制字面常量等


除此之外还有C++1.0,2.0,03,05,17,20等,但都不是那么重要


2)C++关键字

C++共有63个关键字相对于C的32个相当于翻倍兼容C关键字

asmdoifreturntrycontinue
autodoubleinlineshorttypedeffor
booldynamic_castintsignedtypeidpublic
breakelselongsizeoftypenamethrow
caseenummutablestaticunionwchar_t
catchexplicitnamespacestatic_castunsigneddefault
charexportnewstructusingfriend
classexternoperatorswitchvirtualregister
constfalseprivatetemplatevoidtrue
const_castfloatprotectedthisvolatilewhile
deletegotoreinterpret_cast

3)命名空间(namespace)

许多相同的变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题

1.namespace的使用

下面是常规命名空间使用

namespace My_Space // My_Space为命名空间的名称
{
	// 命名空间中的内容,既可以定义变量,也可以定义函数
	int a;
	int Add(int left, int right)
	{
		return left + right;
	}
}

注意1命名空间可以嵌套

namespace My_Space1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}
	namespace My_Space2//嵌套
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}

注意2同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中

namespace My_Space // My_Space为命名空间的名称
{
	// 命名空间中的内容,既可以定义变量,也可以定义函数
	int a;
	int Add(int left, int right)
	{
		return left + right;
	}
}
namespace My_Space // My_Space为命名空间的名称
{
	// 命名空间中的内容,既可以定义变量,也可以定义函数
	int b;
	int Mul(int left, int right)
	{
		return left * right;
	}
}

相当于

namespace My_Space // My_Space为命名空间的名称
{
	//上
	int a;
	int Add(int left, int right)
	{
		return left + right;
	}
	//下
	int b;
	int Mul(int left, int right)
	{
		return left * right;
	}
}

2.命名空间的使用方式

1.加命名空间名称及作用域限定符’::'

int main()
{
	printf("%d\n", My_Space::a);
	return 0;
}

2.使用using将命名空间中成员引入

using My_Space::b;
int main()
{
	printf("%d\n", b);
	return 0;
}

3.使用using namespace 命名空间名称引入

using namespce My_Space;
int main()
{
	printf("%d\n", My_Space::a);//可以这样
	printf("%d\n", b);//也可以直接使用
	Add(10, 20);
	return 0;
}

4)cout 与 cin

注意
使用cout标准输出(控制台)和cin标准输入(键盘)时必须包含< iostream >头文件以及std标准命名空间

关于C++中没有‘.h’的解释
早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中。后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h 旧编译器(vc 6.0)中还支持iostream.h格式,后续编译器已不支持,所以应使用<iostream>+std的方式

基本使用方法(粗略了解)


cout相当于printf
cin相当于scanf
endl相当于换行符\n

#include <iostream>
using namespace std;
int main()
{
	int a;
	double b;
	char c;
	cin>>a;
	cin>>b>>c;
	cout<<a<<endl;
	cout<<b<<" "<<c<<endl;
	//不像printf,这里必须要用 输出流符号<< 来连接
	return 0;
}

5) 缺省参数

定义调用函数时可传参可不传,不传时使用函数自己指定的实参,如例子所示

void TestFunc(int a = 0)
{
	cout<<a<<endl;
}
int main()
{
	TestFunc(); // 没有传参时,使用参数的默认值
	TestFunc(10); // 传参时,使用指定的实参
}

1.全缺省参数

void TestFunc(int a = 10, int b = 20, int c = 30);

2.半缺省参数

void TestFunc(int a, int b = 10, int c = 20);

注意

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现
    如果声明与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用哪个缺省值
  3. 缺省值必须是常量或者全局变量
  4. C语言不支持(编译器不支持

6)函数重载

定义函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题

以下是函数重载

int Add(int left, int right)
{
	return left+right;
}
double Add(double left, double right)
{
	return left+right;
}
long Add(long left, long right)
{
	return left+right;
}
int main()
{
	Add(10, 20);
	Add(10.0, 20.0);
	Add(10L, 20L);
	return 0;
}

以下不是函数重载

short Add(short left, short right)
{
	return left+right;
}
int Add(short left, short right)
{
	return left+right;
}

1. 为什么C++支持函数重载,而C语言不支持函数重载?

程序的运行,需要经历预处理、编译、汇编、链接
参考:C语言----程序编译(预处理)

在Linux下:(假设a.cpp中调用了b.cpp中定义的Add函数)
链接阶段,链接器看到a.o(二进制文件)调用Add,但是没有Add的地址,就会到b.o(二进制文件)的符号表中找Add的地址,然后链接到一起


在调用函数时一般会使用汇编指令call
参见:函数栈帧的创建和销毁(详细)
形如80489bc: e8 73 ff ff ff call <?>问号也就是函数签名

每个编译器都有自己的函数名修饰规则
gcc编译器
使用objdump工具,键入objdump -S 源文件
在这里插入图片描述
函数签名依然是Add


g++编译器
同样的操作显示出的函数签名变为了<_Z3Addii>而不是原函数名Add

这里我们已经可以得出结论
在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中,构成函数签名


回到链接阶段
如果b.cpp中有两个Add函数,由于在gcc编译器下会发现符号表中有两个重名的函数签名,所以会直接报错,因为不知道该拿出哪个地址。但g++就很明确了,两个相同函数名的函数签名不一样,所以可以轻松取出目标地址


这样一来,也可以说明上面不是函数重载的情况(与返回值无关


在Windows下
对于C语言来说

这篇关于C++初阶---C++基础入门(未写完)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!