C++在C上的再次扩充
1.基于范围的for循环
2.全新的auto
3.通用初始化(列表初始化)
1.基于范围的for循环
在C++11之后新增了基于范围的for循环(range-based)
int main(void)
{
int a[]={1,2,3,4,5,6,7,8};
for(int x:a)
{
cout<<x<<endl;
}
cout<<endl;
for(int&x:a)
{
x=x*2;
}
for(int x:a)
{
cout<<x<<endl;
}
return 0;
}
输出结果为1 2 3 4 5 6 7 8以及2 4 6 8 10 12 14 16
这个就是很经典的一个例子。通过引入一个变量就能输出整个数组的内容,而在对数组内容进行修改时用到的是“引用”。这里的int&x:a相当于给数组里各个元素起了别名,对x进行操作就是对各个元素进行操作,进而改变数组元素的值。
优势:范围for循环写法简便,无需获得数组、集合长度,也无需根据索引来访问各个元素。
劣势:范围for循环不能获取下标,所以在遍历数组时采用传统for循环更好。同时由于这个原因,不能通过索引操作数组或集合中的元素,若只操作数组或集合中的元素而不使用索引还是可以使用范围for循环的。传统for循环利用索引可以对某个数组或集合元素进行操作,而范围for循环对数组或集合进行遍历时,只能获取集合元素,不能对某个数组或集合元素进行操作。
和传统for循环的主要区别就是:范围for循环必须有被遍历的目标(数组或集合),传统for循环遍历数组的时候需要索引。
int main(void)
{
int a[5];
for(int&x:a)
{
cin>>x;
}
for(int x:a)
{
cout<<a<<endl;
}
return 0;
}
如上所示,范围for循环可以输入、输出并且修改数组元素内容。int&x:a是引用,相当于向数组元素赋值。
注意:任何范围for循环都可以写成传统for循环,但是不一定每个传统for循环都能写成范围for循环。
范围for循环形式:for(type var:list)
type是指类型,var是变量名,list是指列表。可以理解成: 数据类型 变量名:遍历的目标
2.全新的auto(自动类型推断)
auto在很早之前就存在,C++11之后对它的语义进行了更新,原来的语义被推翻,取而代之的是一个全新的语义。
在之前auto表示自动变量,用于声明一个变量存储类型。
在C++11之后,在C++上表示其是一个占位符,并不再声明变量存储类型,也就是其不再是一个真正的类型,不能使用一些以类型为操作数的操作符,如sizeof。
auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型
auto的自动类型推断发生在编译期,所以使用auto并不会造成程序运行时效率的降低。
auto和其他变量类型有明显的区别:
1.auto声明的变量必须要初始化,否则编译器不能判断变量的类型。
2.auto不能被声明为返回值,auto不能作为形参,auto不能被修饰为模板参数
还是有一点很关键,虽然auto是C++11被彻底更新过的一个概念,但是还是要指出:尽量少用auto,直接写出变量的类型会使程序可读性更高。auto主要用于代替类型复杂且使用范围专一的变量声明。
3.通用初始化
struct Stu
{
int num;
char name[20];
int age;
};
int main(void)
{
int a=2;
int*pa=&a;
int b[5]={1,2,3,4,5};
struct Stu s={1008,"Zhangsan",20}; //定义结构体变量
return 0;
}
如上所示,这就是一个传统的初始化。
这些初始化使用规范不一样,而通用初始化就不一样了,下面是通用初始化:
struct Stu
{
int num;
char name[20];
int age;
};
int main(void)
{
int a{2};
int*pa{&a};
int b[5]{1,2,3,4,5};
struct Stu s{1008,"Zhangsan",20};
return 0;
}
全部变成了类似于数组列表那样的初始化形式,所以通用初始化也叫列表初始化。不过有一点需要指出:通用初始化是C++独有的,C不具备。
通用初始化的优势也比较明显,统一了初始化行为,从某种程度上说对程序员进行了减负,同时对C++初学者比较友好,降低了学习难度。