C++新手向
一、C++关键字
- C++中关键字一共63关键字如图:
二、命名空间
-
假设这样一种情况,当一个班上有两个名叫 Zara 的学生时,为了明确区分它们,我们在使用名字之外,不得不使用一些额外的信息,比如他们的家庭住址,或者他们父母的名字等等。 同样的情况也出现在 C++ 应用程序中。例如,您可能会写一个名为 xyz() 的函数,在另一个可用的库中也存在一个相同的函数 xyz()。这样,编译器就无法判断您所使用的是哪一个 xyz() 函数。 因此,引入了命名空间这个概念,专门用于解决上面的问题,它可作为附加信息来区分不同库中相同名称的函数、类、变量等。使用了命名空间即定义了上下文。本质上,命名空间就是定义了一个范围。
1.命名空间定义
- 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名 空间的成员。
代码如下(示例):
namespace A{
int a;
int sum(int a,int b)
{
return a+b;
}
}
- 命名空间可以嵌套
namespace N
{
int a;
namespace N1
{
int c;
}
}
- 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
并且C++中using namespace std;就是在用std.C++标准库的命名空间. C++标准程序库中的所有标识符都被定义于一个名为std的namespace中
2.命名空间的三种使用方式
- 加命名空间名称及作用域限定符
代码如下(示例):
int main()
{
std::cout << 10 ;
return 0;
}
- 使用using将命名空间中成员引入
而此刻直接调用b会报错因为编译器无法识别b不知道b在那个空间里。
- 使用using namespace 命名空间名称引入
三、C++输入&输出
- C++中输入输出分别用的是cin(l流插入)和cout(流输出)函数
- 使用cout标准输出(控制台)和cin标准输入(键盘)时,必须包含< iostream >头文件以及std标准命名空间。
注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。 - 使用C++输入输出更方便,不需增加数据格式控制,比如:整形–%d,字符–%c
一、标准输出流(cout) 预定义的对象 cout 是 iostream 类的一个实例。cout 对象"连接"到标准输出设备,通常是显示屏。cout 是与流插入运算符 << 结合使用的,如下所示:
#include <iostream>
using namespace std;
int main( )
{
char str[] = "Hello C++";
cout << "Value of str is : " << str << endl;
}
流插入运算符 << 在一个语句中可以多次使用,如上面实例中所示,endl 用于在行末添加一个换行符。
二、流插入运算符 << 在一个语句中可以多次使用,如上面实例中所示,endl 用于在行末添加一个换行符。 C++ 编译器根据要输入值的数据类型,选择合适的流提取运算符来提取值,并把它存储在给定的变量中。流提取运算符 >> 在一个语句中可以多次使用
四、缺省参数
概念
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定的实参。举例:
#include<iostream>
using namespace std;
void fuc(int a=0)
{
cout << "a=" << a << endl;
}
int main()
{
fuc();
fuc(5);
return 0;
}
结果如下:
分类
全缺省参数
void fuc(int a=0,int b=1,int c=2)
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
- 但是要注意此时在函数调用时候实参只能从左到右按顺序给形参传值。
void fuc(int a,int b=1,int c=2)
{
cout << "a=" << a << endl;
cout << "b=" << b << endl;
cout << "c=" << c << endl;
}
注意:
-
半缺省参数必须从右往左依次来给出,不能间隔着给 -
缺省参数不能在函数声明和定义中同时出现 -
缺省值必须是常量或者全局变量 -
C语言不支持(编译器不支持)
五、函数重载
- 概念:函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的 形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
注意:返回类型不同不算函数重载
short Add(short left, short right) {
return left+right;
}
int Add(short left, short right) {
return left+right;
}
这样编译器会报错
六、引用
概念
:引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它 引用的变量共用同一块内存空间。
使用规则:
类型& 引用变量名(对象名) = 引用实体;引用类型必须和引用实体是同种类型的
int a = 0;
int& b = a;
而通过反汇编我们可以看到a和b其实是指向一样的空间,我们可以通过b或者a来改变对应的值都是同样效果
引用特性
- 引用在定义时必须初始化
- 一个变量可以有多个引用,但是没有多级引用
- 引用一旦引用一个实体,再不能引用其他实体
int a = 0;
int& b = a;
int& c = b;
printf("%p\n%p\n%p", &a, &b, &c);
结果:
const int a = 10;
const int& ra = a;
const int& b = 10;
double d = 12.34;
const int& rd = d;
- 1.对于第一个a为const int权限不可修改,因此你的引用权限只可缩小不能放大必须是const int&,否则就可能会通过引用修改值。
- 2.对于第二个b由于10是常量,常量是必不可能被修改的因此要const int&
- 3.对于第三个我们要考虑整形转换,第一步double类型的d的值会发生整形转换并且把这个新的值存放在寄存器里,而const int&实际上是那个寄存器的值(常量)的一个引用,因此要const int&
使用场景
- 做参数
int sum(int& a, int& b)
{
return a + b;
}
- 做返回值
int& sum(int a, int b)
{
static int c = a + b;
return c;
}
要注意如果函数返回时,出了函数作用域,如果返回对象还未还给系统,则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。否则如下图所示:
七、内联函数
- inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。
- .inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联。
- inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
- C++ 内联函数是通常与类一起使用。如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方。
如果想把一个函数定义为内联函数,则需要在函数名前面放置关键字 inline,在调用函数之前需要对函数进行定义。如果已定义的函数多于一行,编译器会忽略 inline 限定符。 在类定义中的定义的函数都是内联函数,即使没有使用 inline 说明符。
八、auto关键字(C++11)
- 在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,C++11中,标准委员会赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
九、基于范围的for循环(C++11)
int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array)
{
x *= 2;
cout << x << endl;
}
for (auto &x : my_array) {
x *= 2;
cout << x << endl;
}
- 上面for述句的第一部分定义被用来做范围迭代的变量,就像被声明在一般for循环的变量一样,其作用域仅只于循环的范围。而在":"之后的第二区块,代表将被迭代的范围。
int my_array[5] = { 1, 2, 3, 4, 5 };
for (int x : my_array)
{
x *= 2;
cout << x << endl;
}
for (int& x : my_array)
{
x *= 2;
cout << x << endl;
}
for (int x : { 1, 2, 3, 4, 5 })
{
x *= 2;
cout << x << endl;
}
十、指针空值—nullptr(C++11)
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量.但是有时候却使用不尽人意:
void f(int) {
cout<<"f(int)"<<endl;
}
void f(int*) {
cout<<"f(int*)"<<endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);
return 0;
}
结果如下: 在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void *)0。
注意:
- 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。.
- 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
- 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr
总结
|