【C++】C++11特性:范围for循环与指针空值nullptr详解
1. 基于范围的for循环(C++11)
1.1 范围for的语法
在C语言或C++98中如果要遍历一个数组,可以按照以下方式进行:
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
// 要求将数组中的值乘2,再打印一遍
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
array[i] *= 2;
for (int* p = array; p < array + sizeof(array) / sizeof(array[0]); ++p)
cout << *p << endl;
}
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
void TestFor()
{
int array[] = { 1, 2, 3, 4, 5 };
// 范围for写法,每次循环将array里的一个元素赋给e
// e会依次取出array中的内容,直到array走完,结束循环
for (auto& e : array)
e *= 2;
for (auto e : array)
cout << e << " ";
return 0;
}
注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
1.2 范围for的使用条件
1. for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为for的范围不确定
void TestFor(int array[])
{
// array 已经不再是数组,传参之后退化成了指针
for (auto& e : array)
cout << e << endl;
}
2. 迭代的对象要实现++和==的操作。
2. 指针空值nullptr(C++11)
2.1 C++98中的指针空值
在良好的C/C++编程习惯中,声明一个变量时最好给该变量一个合适的初始值,否则可能会出现不可预料的错误,比如未初始化的指针。如果一个指针没有合法的指向,我们基本都是按照如下方式对其进行初始化:
int main()
{
// C
int* p1 = NULL;
// C++11中,推荐像下面这样去用
int* p2 = nullptr;
return 0;
}
为什么C++中推荐使用 nullptr 作为空指针的值呢?看下面这段代码:
void fun(int n)
{
cout << "整形" << endl;
}
void fun(int* n)
{
cout << "整形指针" << endl;
}
int main()
{
// C
int* p1 = NULL;
// C++11中,推荐像下面这样去用
int* p2 = nullptr;
fun(0);
fun(NULL);
fun(p1);
fun(p2);
return 0;
}

可以看见,如果向 fun 函数中直接传入 NULL,会被识别成一个整形。这是因为 NULL 实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。
在C++98中,字面常量0既可以是一个整形数字,也可以是无类型的指针(void*)常量,但是编译器默认情况下将其看成是一个整形常量,如果要将其按照指针方式来使用,必须对其进行强转(void*)0。
注意:
1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
更多推荐



所有评论(0)