指针与数组的复习

Published: 11 May 2016 Category: C

指针与数组算是C/C++中比较基础又重要的内容了,早晨到实验室随手拿起"c++ primer"翻到这里,发现里面很多容易混淆的内容.

  1. 指针不是整数,虽然计算机通常把地址当做整数来处理.通常指针大小与机器位数相同,即32位机的指针大小为4B,64位机的指针大小为8B.
  2. 数组的动态分配:

    int* p = new int [10];

    delete [] p;

    不能使用sizeof运算符来确定动态分配的数组包含的字节数.
  3. 将指针变量加1后,其增加的值等于指向的类型占用的字节数.
  4. 指针与数组名的区别:
  • 指针的值可以修改,而数组名是常量.
  • 对数组名应用sizeof运算符的得到的是数组的长度;而对指针应用sizeof得到的是指针的长度(4或8),即使指针指向的是一个数组.
数组的地址

我们已经知道,sizeof(数组名)时,C++不会将数组名解释为地址;而对数组取地址时,数组名也不会被解释为其地址.
等等,数组名难道不被解释为数组的地址吗?不完全如此:数组名被解释为第一个元素的地址,而对数组名应用取地址运算符,得到的是整个数组的地址:

short tell[10]; // tell an array of 20 bytes
cout << tell << endl; // displays &tell[0]
cout << &tell << endl; // displays address of whole array

从数字上说,这两个地址相同;但从概念上说,&tell[0](即tell)是一个20姊jie妹内存块的地址.因此,表达式tell+1将地址值增加2,而表达式&tell+1将地址值增加20.换句话说,tell是一个short指针(short*),而&tell是一个这样的指针,即指向包含10个元素的short数组( short(*)[10]).
你可能会问,前面有关&tell的类型描述是如何来的呢?首先,你可以这样声明和初始化这种指针:

short tell[10];
short (*pas)[10] = &tell; // pas points to array of 10 shorts

如果省略括号,优先级规则将使得pas先与[10]结合,导致pas是一个short指针数组,它包含10个元素,因此括号是必不可少的. 如果要描述变量类型(比如用于强制转型),只要将上述声明中的变量名去掉,因此pas的类型为:

short(*)[10]

另外,由于pas被设置为&tell,因此*pas与tell等价,所以(*pas)[0]为tell数组的第一个元素.

上面的这个例子取自<C++ primer plus(第6版)> p109,书上的示例代码也是错的...所以这么看来这部分确实很容易混淆 (=. = )

comments powered by Disqus