首页 > 代码库 > C++ Primer 随笔 Chapter 4 数组和指针

C++ Primer 随笔 Chapter 4 数组和指针

1.数组:数组是由类型名、标识符和维数组成的符合数据类型,类型名规定了存放在数组中的元素类型,维数规定数组中包含元素的个数而标识符就是数组的名称。例如:

  int  arr[10]; 其中 int 是类型名,arr是标识符而 10 是数组的维数。

2.数组的定义和初始化:数组的初始化要注意以下几点

  (1). 数组中存放的元素类型不能是引用类型,除此之外可以是其他任何类型。

  (2). 数组的维数必须是字面值常量、枚举常量或者常量表达式(但不能是在运行时才知道其值得常量表达式)

  (4). 显示初始化整形数组时,如果 {} 内元素的个数小于数组维数,那么剩下的元素初始化为 0, 如果 {} 内元素个数大于数组的维数,会报错。

  (5). 如果不显示初始化数组,那么数组会像普通变量一样初始化:

    (a). 在函数体外定义的内置数组,其元素均初始化为 0.

    (b). 在函数体内定义的内置数组,其元素无初始化.

    (c). 不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化。如果该类没有默认构造函数,则必须为数组的元素提供显示初始化。

3.指针:指针用于指向对象。具体来说,指针保存的是另一个对象的地址。

4.指针的定义:

  (1). 指针定义的时候推荐写法应该是这样 int *ip 而不是 int* ip,也就是说让 * 更靠近变量。为什么这样?如果一个定义这样写 int* ip1,ip2,会让很多人误以为 int * 是一种指针类型,这样定义出来的 ip1 与 ip2 都是 int * 类型,实际上只有 ip1 是而 ip2 是 int 型。但如果这样写:int *ip1,ip2,就不会让人产生这么大误会了。

  (2). 指针的初始化或复制只能是一下四种类型的值:

    (a). 0 值表达式,例如,在编译时可获得 0 值得整型 const 对象或字面值常量 0.  

    (b). 类型匹配的对象的地址.

    (c). 另一个对象之后的下一个地址.

    (c). 同类型的另一个有效指针.

5.void 指针:它可以保存任何类型对象的地址。

6.指针与引用的比较:

  (1). 引用总是指向某个对象:定义引用时没有初始化时错误的。

  (2). 给指针赋值是让指针指向另一个对象而给引用赋值是修改该引用所关联的对象的值。

7.指针和 const 限定符:

  (1). 指向 const 对象的指针:const int *cip; 这里定义的指针 cip 是一个指向 const 对象的指针,表示不能通过指针的解引用操作来改变 cip 所指向的内容。 

  (2). const 指针: int errNumb = 0; int * const curErr = &errNum; 这里定义的 curErr 是一个 const 指针,表示这个指针本身不能被改变,所以它在被定义的时候就必须被初始化。

  (3). 指向 const 对象的 const 指针:const int pi = 3; const int * const pi_ptr = π 这里定义的是一个指向 const 对象的 const 指针,它本身和指向的对象内容都不能被改变。

  (4). 这里需要注意的是:

    (a). 不能使用 void * 指针保存 const 对象的地址,而必须使用 const void * 类型的指针保存 const 对象的地址,下面的例子是错误的:

    const int universe = 42; void * cpv = &univers; 而 const void * cpv = &universe 才是正确的写法。

    (b). 不能把 const 对象的地址赋值给一个非指向 const 对象的指针,但是允许将非 const 对象的地址赋值给一个指向 const 对象的指针。例子如下:

      const double pi = 3.14;//↓          |    double pi = 3.14; ↓  

      double *ptr = π //错误↓           |   const double *cptr = π// 正确

      const double cptr = π //正确

8. C风格字符串:char p[] = "hello"; 此数组 p 维数是 6 而不是5 ,为什么呢?因为该字符串后面还有一个空字符null。类似的以空字符null结束的字符数组就是 C 风格字符串。我们需要注意的是:C 语言标准库提供的一系列 C 风格字符串的库函数要求传入的字符串参数必须以空字符 null 结束。

9. 指针数组与数组指针:

  (1). int (*p)[10]; 由于 () 的优先级高,p 与 * 结合,说明 p 是一个指针;那么这样定义出来的 p 就是数组指针,一个指向拥有 10 个整形元素的数组的指针。

  (2). int * p[10];  由于没有 (), 故 [] 优先级高,先与p结合成为一个数组,说明是 p 表示的数组。而 int * 在这种情况下可以看着是一种数据类型---整型指针。这样就容易理解:数组 p 里面存放 10 个 int * 类型的元素。

建议:尽量避免使用指针和数组,用 vector 代替数组,用迭代器代替指针,用 string 类型取代 C 语言风格的字符串。

C++ Primer 随笔 Chapter 4 数组和指针