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。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐