C++入门
一、C++关键字
在C++98标准下,有63个关键字,到C++11已经有80多个关键字了。其中也包含C的32个。
二、命名空间
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字 污染,namespace 关键字的出现就是针对这种问题的。
1.命名空间的定义
定义命名空间,需要使用到namespace 关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名 空间的成员
namespace ant
{
int a;
int b;
}
那么为什么要使用namespace 去定义一个命名空间呢?
主要是为了解决C语言命名冲突的问题
如:
int main()
{
int scanf = 10;
int strlen = 20;
}
看上面程序我们定义了与函数名重名的变量,这样我们在使用scanf 函数和strlen 函数就会出现问题。
因为编译器在辨别scanf 和strlen 采用的是就近原则,先从局部域开始找,这样编译器就以为其是我们定义的变量。
这样就会发生命名冲突
但这样的问题在C++中就迎刃而解
C++用命名空间,将不同域的相同名字的变量进行隔离。
如:
namespace ant
{
int scanf = 10;
int strlen = 20;
}
int main()
{
printf("%x\n",ant::scanf);
printf("%x\n",ant::strlen);
//指定访问ant命名空间的scanf和strlen,这样和库函数中的scanf和strlen就不冲突了
//当然没有指定,默认访问的局部或全局
printf("%x\n",::scanf);
//这样前面是空白又是什么意思呢,它代表访问全局的scanf,::这个符号表示访问左边指定的域的数据。
}
2.命名空间的嵌套使用
命名空间当然也可嵌套使用,如:两个公司合作,公司下面有不同的部门,我们要合并两个工程时,就需要每个公司每个部门的数据,这样先写两个空间分别代表两个公司,其中再嵌套不同部门即可。
如:
namespace ant
{
int a=10;
namespace a
{
int b = 20;
}
}
//那么嵌套的命名空间该如何访问呢?
int main()
{
printf("ant::a::b");
//还是一样,只是需要多写一层
}
3.命名空间中还可以定义函数
如:
namespace ant
{
int Add(int a,int b)
{
return a+b;
}
}
int main(void)
{
int a = 10,b = 20;
int c = ant::Add(a,b);
//调用时一样需要加上ant::。
}
总:
对于命名空间,不同的命名空间,就相当于不同的域,其中可以定义结构体函数等其他东西。这样就可以很好的解决重名的问题,更好的进行开发。
注:同一个工程中允许存在多个相同的命名空间,编译器最后会合成同一个命名空间
4.using namespace std的作用
因为C++库为了防止命名冲突,把自己库里面的东西都定义在一个std的命名空间中。所以如果我们要使用cout,endl 等函数时,就需要引入std 命名空间。
那么怎么引入std 命名空间呢
-
指定命名空间: 如: int main()
{
std::cout << a << std::endl;
}
这样的命名比较标准,是最规范的方式。 缺陷 :麻烦,并且每个地方都要指定。 -
把std 整个展开 using namespace std;
//这就是我们平常最常用的方法
看起来方便了,适合平常使用,但不适合工程使用。 缺陷 :如果我们自己定义的东西跟库冲突就没办法解决。 -
对部分常用的库里面的东西展开 using std::cout;
using std::endl;
//要用什么就展开什么,针对前两种方法,项目中也会经常使用
//但要注意,只能一行一行引入。
总: 自己定义的也可用以上三种方法,其他标准库的东西都可以用以上三种方法
5.关于引入头文件的使用
C++的头文件都不用带.h,这是为什么呢?
- 跟老的C++编译器和C进行区分。
三、C++输入和输出
C++的输入为cin ,而输出为cout 。那就有人要问了,那endl 是干嘛的,它相当于一个全局的换行符。
对比C语言,cin 对比scanf ,cout 对比printf ,endl 对比\n 。
那么就有人要说了,C++不是兼容C么,为啥不用之前的,两个有什么区别呢?
当然有区别了,cout 和cin 自动识别类型
如:
int main()
{
int a = 10;
printf("%d",a);//printf打印a需要前面加格式化输出符号。
cout << a << endl;//C++只需写上它即可。
}
那么为什么不用printf 和scanf 呢。当然要用呢,可以混用,哪个好用用哪个。
注:cin有着和scanf一样的缺点,无法读取空格
四、缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。
如:
void Test(int a = 0)
{
cout << a << endl;
}
int main()
{
Test();//没有传参时,使用参数的默认值
Test(10);//传参时,使用指定的实参
}
1.缺省参数分类
-
全缺省参数 void Test1(int a = 0,int b = 1,int c = 2)
{
//这样里面所有参数都是缺省参数的,即为全缺省参数
}
void Test2(int a,int b = 0, int c = 1)
{
//这种里面有没有缺省参数的,即为半缺省参数
}
2.缺省参数的应用
比如:栈的初始化时,我们需要栈的空间不一样,增容需要代价,太大又浪费空间,这时用缺省参数,即可控制其需要大小
注:
- 半缺省参数必须从右往左依次来给出,不能间隔着给
- 缺省参数不能在函数声明和定义中同时出现。因为当声明或定义时的默认值不同时,编译器就无法确定到底该用哪个缺省值。
- 缺省值必须是常量或者全局变量
五、函数重载
是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题。
1.函数重载的应用
常处理功能类似数据类型不同的函数
如:
int Add(int a,int b)
{
return a+b;
}
double Add(double a,double b)
{
return a+b;
}
这样我们调用Add时,就不用担心其时整型还是浮点型了,因为编译器会自己选择调整。
2.函数重载的问题
如:
void test(int a,int b,int c = 1)
{
.......
}
void test(int a,int b)
{
}
//这两个函数虽然构成函数重载。
//但f(1,2)这样两个函数的调用会出现问题,因为编译器不知道使用哪个。所以在使用函数重载时,要注意这方面的问题。
b) { return a+b; }
这样我们调用Add时,就不用担心其时整型还是浮点型了,因为编译器会自己选择调整。
##### 2.函数重载的问题
如:
```c++
void test(int a,int b,int c = 1)
{
.......
}
void test(int a,int b)
{
}
//这两个函数虽然构成函数重载。
//但f(1,2)这样两个函数的调用会出现问题,因为编译器不知道使用哪个。所以在使用函数重载时,要注意这方面的问题。
|