C++数组名与指针

DengZY 2019-06-26

在大多数情况下,C++和C语言一样,将数组名视为指针,C++将数组名解释为其第一个元素的地址 。

int cookies[ArSize] = {10,2,3,4,5,6,7,8};
bool result1 = cookies == &cookies[0]; 
cout << result1 << endl;

结果会输出1

但是该规则有一些例外。

  1. 数组声明使用数组名来标记存储位置;
  2. 对数组名使用sizeof将得到整个数组的长度(以字节为单位)

    int size = sizeof(cookies);
    cout << size << endl;

    结果为32

  3. 将地址运算符&用于数组名时,将返回整个数组的地址

下面就第三点做详细阐述

运行如下代码

cout << cookies << " " << &cookies << endl;
    int *pointer = new int[5];
    cout << pointer << " " << &pointer <<endl;

结果为:

0x22fe20 0x22fe20
0x5a58b0 0x22fe48

如果吧数组名视为指向数组第一个元素的指针,则对数组名cookies使用&取地址,应该会返回这个指针的地址,但通过结果可见,cookies
&cookies返回的是同一地址。
显然在C++中数组名与纯粹的指针变量还是有区别的,对数组名cookies进行&操作,并不是取其地址,而是得到了指向整个数组的指针。也就是说,cookies&cookies指向的是同一地址,但是他们的类型不一样。cookies相当于&cookies[0],类型是int*,而&cookies是指向整个数组的指针,类型是int (*)[8]

如执行语句bool result2 = cookies == &cookies;编译会报错
comparison between distinct pointer types 'int' and 'int ()[8]' lacks a cast [-fpermissive]

在掌握了以上知识之后,来看以下代码

cout << *cookies << " " << *(cookies + 1) 
    << " " << *((int*)(&cookies + 1)) << " " 
    << *((int*)(&cookies + 1) - 1);

结果为:

10 2 1 8

注意到C++数组的性质
两个恒等式

cookies[i] == *(cookies + i) //values in two notations
&cookies[i] == cookies + i //addresses in two notations

将指针(包括数组名)加1,实际上是加上一个与指针指向的类型的长度(以字节为单位)相等的值。

前两个输出分别为cookies[0]cookies[1]的值;
第三个输出:&cookies是指向整个数组的指针,类型是int (*)[8],因此它的+1相当于加上32个字节(这里假设按字节寻址,且int为4个字节),然后使用(int*)强制类型转换,将int (*)[8]转换为int*,所以结果相当于cookies[7]之后4个字节存储单元的值。
第四个输出:同理,实际为cookies[7]的值。

相关推荐