数组名被解释为第一个元素的地址,而在数组名前应用地址运算符时,得到的是整个数组的地址:- int add[10];
- cout << add << endl;
- cout << &add << endl;
复制代码 这两个输出的值一样,即两个地址相同。但概念上,这两者却不一样。add 或 &add[0] 是一个 4 字节整型内存地址,而 &add 却是一个 40 字节的内存地址块的地址。
因此,add + 1 是将地址加上 4 ,而 &add + 2 则表示的是将地址加上 80 。换句话来说,add 是一个 int 指针 ( *int ) ,而 &add 则是一个指向包含 10 个元素的 int 数组 ( int(*)[10] ) 。
可以像下面这样声明和初始化这种指针:上面 pas 指向的是一个包含了 10 个 int 原型的数组。
需要注意的是,不能省掉括号,即不能写成 int *pas[10] = &add; 。这是因为,[ ] 的优先级比 * 高,这样 pas 就会先于 [10] 结合,从而导致了 pas 变成了一个 int 指针数组,且包含了 10 个这样的指针,所以括号必不可少。
如果要描述变量的类型,可将声明中的变量名删除,因此 pas 的类型为 int (*) [20] 。
由于 pas 被设置为 &add,所以 *pas 和 add 是等价的,所以 (*pas)[0] 就是 add 数组的第一个元素。
将上面所述,用下面一段简单的代码测试,比较其地址关系便可一目了然:
[C++] 纯文本查看 复制代码 #include <iostream>
using namespace std;
int main()
{
int add[10];
cout << add << endl;
cout << &add + 2 << endl;
int (*pas) [10] = &add;
cout << pas+1 << endl;
cout << pas+2 << endl;
add[0] = 88;
cout << "--------------------" << endl;
cout << pas << endl;
cout << *pas << endl;
cout << **pas << endl;
cout << (*pas)[0] << endl;
return 0;
}
运行输出:
[beyes@groad ~]$ ./address
0xbfc0c434
0xbfc0c484
0xbfc0c45c
0xbfc0c484
--------------------
0xbfc0c434
0xbfc0c434
88
88
另外,还有一种情况,如果上面的 add 数组是 char 类型,那么如何输出其地址:
[C++] 纯文本查看 复制代码 #include <iostream>
using namespace std;
int main()
{
char add[10];
cout << add << endl;
return 0;
}
这样输出是乱码,而不会是 add 的地址当一个数组是 char 类型时,cout 其数组名时,会优先输出其数组的内容,这里数组名相当于一个字符串指针。那么要想输出数组地址,可以像上面在 add 面前使用地址运算符,即 &add 。还可以在数组名面前使用 (void *) 进行地址的强制声明,这样就可以输出数组地址了。再比较下面的程序:
[C++] 纯文本查看 复制代码 #include <iostream>
using namespace std;
int main()
{
char add[10];
cout << add << endl;
add[0] = 'a';
add[1] = 'b';
add[2] = 'c';
cout << &add[2] << endl;
return 0;
}
在第 2 条 cout 语句中,你同样不会获得 add[2] 这个元素的地址,而仍然是乱码,因为它仍然将该地址当作是从该元素为起始的字符串指针,而该数组里又没有 '\0' 结尾的元素,因此仍然输出乱码。同样,想获得 add[2] 的地址,可以在 &add[2] 的前面加上 (void *) 进行强制转换,即写成 (void *)&add[2];
|