C++关键字
asm | do | if | return | typedef |
---|
auto | double | inline | short | typeid | bool | dynamic_cast | int | signed | typename | break | else | long | sizeof | union | case | enum | mutable | static | unsigned | catch | explicit | namespace | static_cast | using | char | export | new | struct | virtual | class | extern | operator | switch | void | const | false | private | template | volatile | const_cast | float | protected | this | wchar_t | continue | for | public | throw | while | default | friend | register | true | | delete | goto | reinterpret_cast | try | |
C++关键字共有63个关键字,32个C语言保留关键字和31个C++关键字
命名空间
在一个较大的项目里难免会遇到重名的问题,namespace关键字就是用来解决命名冲突的问题,namspace是用来创建一个空间域,这个空间域里面定义的变量名和函数名不会与全局域或mian函数的有任何冲突。
命名空间的定义
#include <iostring>
namespace zs
{
int a = 10;
}
int main()
{
int a = 100;
printf("a:%d\n", a);
printf("a:%d\n", zs::a);
return 0;
}
命名空间域内可嵌套创建命名空间,每次使用命名空间的时候都需要加上限定符:: ,如果不想加又想用空间域内的成员那只需加上using namespace zs 即可全部展开,但是如果这样做的话又出现一个问题,全部展开的话不就会出现命名冲突吗?
确实,会出现老问题,所以我们可以不全部展开,展开部分不会发生命名冲突的内容,这时候我们就需要使用using 这个关键字。
#include <iostream>
namespace zs
{
int a = 10;
void print()
{
printf("print\n");
}
}
using zs::print();
int main()
{
print();
return 0;
}
标准输入&输出
就像一开始学习C语言一样我们先用这个语言的标准输出流,向这个世界打声招呼吧!
#include <iostream>
using namespace std;
int main()
{
a = 10;
cout << “Hello World” << endl;
cin >> a;
return 0;
}
使用cout 需要包含iostream 这个库函数,cin 也是,cout 类似C语言的printf 函数,而cin 则类似scanf 函数,不过C++的输入和输出比C语言的更智能了点,它能自动识别变量的类型。所以使用cin 的时候不用像scanf 还有取地址了。
缺省参数
缺省参数一般是在函数声明或定义的时候使用,如果不给函数名参数它就会使用默认的参数,这样的函数我们叫缺省函数,缺省函数又分全缺省和半缺省。
全缺省如果一个参数不传就使用你默认给的,而半缺省则需要把没给默认参数的形参传参。
注意:缺省参数只能从右往左缺省并且连续,不然不构成缺省函数,从右往左缺省是因为传参时是从左往右传参的!
缺省参数使用案例:
#include <iostream>
using namespace std;
int Add(int a = 10, int b = 20)
{
return a + b;
}
int mainI()
{
cout << add() << endl;
cout << add(1) << endl;
cout << add(1, 2) << endl;
return 0;
}
#include <iostream>
using namespace std;
int Add(int a, int b = 20)
{
return a + b;
}
int mainI()
{
cout << add(1) << endl;
cout << add(1, 2) << endl;
return 0;
}
函数重载
函数重载的概念:函数重载能使不同功能的函数能重名,但是有要求,函数参数类型不同或参数个数不同这样才能构成函数重载;
使用案列:
#include <iostream>
namespace std;
int add(int a, int b)
{
return a + b;
}
double add(double a, double b)
{
return a + b;
}
int main()
{
cout << add(1, 1) << endl;
cout << add(1.1, 1.1) << endl;
return 0;
}
不知道大家有没有想过,为什么C++能函数重载而C语言而不能?
为此我特意的取研究了一下,经过多伦测试发现C++有个函数名修饰规则,这个规则则造就了函数重载,我测试的时候发现C语言的函数名是和定义的函数名一样,而C++的函数名则不同。
以下均为Linux环境下测试取得的数据:
我们可以发现C++的函数名修饰规则是_Z3Addii,_Z是开头,3则是函数名的长度,而Add是函数名而ii是参数类型的首字母个数,double的也是一样,
接下来我们看看C语言的
我们可以看到C语言的函数名就是它本身没有任何的修饰
引用
引用的概念
在C++中引用类似typoedef 不过引用是给变量名取别名用这个引用的变量相当于用这个变量名本身,引用本质就是一个指针,当然这是从底层的角度来看,如果从语法层来看引用和指针没有任何关系。
引用的定义
指针和引用不通点
- 引用定义的时候必须初始化,而指针变量可以不初始化。
- 引用不能像指针变量一样任意更改指向的地址,如果像更改指针变量那样更改只会造成,引用里面的变量的值更改。
- 引用只是名字看起来不同了,看底层的话引用的变量和变量本身都是同一个地址。
- 多个引用可以引用同一个变量。
- 有多级指针,但没多级引用
- 引用相比于指针更安全
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int& x = a;
cout << &x << endl;
cout << &a << endl;
return 0;
}
那引用可不可以引用const 修饰的变量呢?
答:可以,但是必须引用也是const 属性的,如果不是const 引用const 变量这是属于一种越级操作,就像这是我买的房子有一天,我把房子卖出去了,我自己不能住了,但是你拿着我之前的钥匙去住现在不属于我的房子,这个行为不就是违法行为吗?
引用可以用做函数形参,也可以作为返回值。当引用作返回值的时候返回的引用必须是栈销毁了还存在的,虽然不存在也能用但是这是一个非法行为。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int& test(int& a)
{
static int b = a;
return b;
}
int main()
{
int a = 90;
int& ret = test1(90);
ret = 20;
return 0;
}
内联函数
内联函数inline是用来修饰函数的,被它修饰过的函数执行效率会更高,编译时会在调用内联函数的地方直接全部展开这样就没有函数压栈的开销。但是相应的代价是空间占用会变大,这是一种以空间换时间的做法,如果过大或循环、递归的函数不建议用inline修饰因为占用的空间会很大,当然你强行用也用不了,因为inline对于编译器来说仅仅是一个建议,使用权是在编译器手里。
内联函数不建议声明和定义分离分离的话会导致链接错误,因为inline被展开了就没有地址了,链接就会找不到。
内联函数使用案列:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
inline int add(int a, int b)
{
return a + b;
}
int main()
{
cout << add(1, 2) << endl;
return 0;
}
auto关键字
在C11中auto 是用来推导变量类型的,推导过程是在编译期间发生的,编译之前auto 是一个类型声明占位符。
auto 只能推导基本类型,像函数名和自定义类型则不行。
使用案例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 10;
auto b = 1;
auto c = a;
int* d = nullptr;
auto e = d;
return 0;
}
注:auto在使用的时候必须初始化,auto不能推导数组
auto 能推导一行多个变量,但是要求所有变量都是同类型,不然会编译报错。
如:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
auto a = 10, b = 20;
auto c = 1.1, d = 10;
return 0;
}
范围for
范围for语法
如果要遍历一个数组我们可以搭配auto 来使用,这样会比以往的for循环遍历要简洁很多。
用一个: 来分隔第一部分是用来迭代的变量,第二部分是迭代范围。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1, 2, 3, 4 };
for (auto a : arr)
{
cout << a << ' ';
}
return 0;
}
注意:使用范围for必须明确迭代范围,范围for也可以像平常的循环使用break 和continue 。
如果想要修改数组里面的内容只需要引用a 即可。
如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1, 2, 3, 4 };
for (auto& a : arr)
{
a += 2;
cout << a << ' ';
}
return 0;
}
nullptr关键字
在C语言中指针置空,我们使用的一般都是NULL 但是NULL 是一个宏,这个宏的本值是0,一般推荐用nullptr 这个关键字才是真正意义上的空指针。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
void f(int a)
{
cout << "f(int)" << endl;
}
void f(int* a)
{
cout << "f(int*)" << endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);
f(nullptr);
return 0;
}
可以看到0等价NULL ,nullptr也因此被引入C++,nullptr 是真正意义上的空指针还不需要包含任何头文件。
引用
引用的概念
在C++中引用类似typoedef 不过引用是给变量名取别名用这个引用的变量相当于用这个变量名本身,引用本质就是一个指针,当然这是从底层的角度来看,如果从语法层来看引用和指针没有任何关系。
引用的定义
指针和引用不通点
- 引用定义的时候必须初始化,而指针变量可以不初始化。
- 引用不能像指针变量一样任意更改指向的地址,如果像更改指针变量那样更改只会造成,引用里面的变量的值更改。
- 引用只是名字看起来不同了,看底层的话引用的变量和变量本身都是同一个地址。
- 多个引用可以引用同一个变量。
- 有多级指针,但没多级引用
- 引用相比于指针更安全
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int& x = a;
cout << &x << endl;
cout << &a << endl;
return 0;
}
那引用可不可以引用const 修饰的变量呢?
答:可以,但是必须引用也是const 属性的,如果不是const 引用const 变量这是属于一种越级操作,就像这是我买的房子有一天,我把房子卖出去了,我自己不能住了,但是你拿着我之前的钥匙去住现在不属于我的房子,这个行为不就是违法行为吗?
引用可以用做函数形参,也可以作为返回值。当引用作返回值的时候返回的引用必须是栈销毁了还存在的,虽然不存在也能用但是这是一个非法行为。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int& test(int& a)
{
static int b = a;
return b;
}
int main()
{
int a = 90;
int& ret = test1(90);
ret = 20;
return 0;
}
内联函数
内联函数inline是用来修饰函数的,被它修饰过的函数执行效率会更高,编译时会在调用内联函数的地方直接全部展开这样就没有函数压栈的开销。但是相应的代价是空间占用会变大,这是一种以空间换时间的做法,如果过大或循环、递归的函数不建议用inline修饰因为占用的空间会很大,当然你强行用也用不了,因为inline对于编译器来说仅仅是一个建议,使用权是在编译器手里。
内联函数不建议声明和定义分离分离的话会导致链接错误,因为inline被展开了就没有地址了,链接就会找不到。
内联函数使用案列:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
inline int add(int a, int b)
{
return a + b;
}
int main()
{
cout << add(1, 2) << endl;
return 0;
}
auto关键字
在C11中auto 是用来推导变量类型的,推导过程是在编译期间发生的,编译之前auto 是一个类型声明占位符。
auto 只能推导基本类型,像函数名和自定义类型则不行。
使用案例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int a = 10;
auto b = 1;
auto c = a;
int* d = nullptr;
auto e = d;
return 0;
}
注:auto在使用的时候必须初始化,auto不能推导数组
auto 能推导一行多个变量,但是要求所有变量都是同类型,不然会编译报错。
如:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
auto a = 10, b = 20;
auto c = 1.1, d = 10;
return 0;
}
范围for
范围for语法
如果要遍历一个数组我们可以搭配auto 来使用,这样会比以往的for循环遍历要简洁很多。
用一个: 来分隔第一部分是用来迭代的变量,第二部分是迭代范围。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1, 2, 3, 4 };
for (auto a : arr)
{
cout << a << ' ';
}
return 0;
}
注意:使用范围for必须明确迭代范围,范围for也可以像平常的循环使用break 和continue 。
如果想要修改数组里面的内容只需要引用a 即可。
如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
int main()
{
int arr[] = { 1, 2, 3, 4 };
for (auto& a : arr)
{
a += 2;
cout << a << ' ';
}
return 0;
}
nullptr关键字
在C语言中指针置空,我们使用的一般都是NULL 但是NULL 是一个宏,这个宏的本值是0,一般推荐用nullptr 这个关键字才是真正意义上的空指针。
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
void f(int a)
{
cout << "f(int)" << endl;
}
void f(int* a)
{
cout << "f(int*)" << endl;
}
int main()
{
f(0);
f(NULL);
f((int*)NULL);
f(nullptr);
return 0;
}
可以看到0等价NULL ,nullptr也因此被引入C++,nullptr 是真正意义上的空指针还不需要包含任何头文件。
|