#include<stdio.h>
int main(void){
int arr[] = {1,2,3};
printf("arr=%p,&arr=%p\n",arr,&arr);
printf("*arr=%d,*&arr=%d(%p)\n",*arr,*&arr,*&arr);
return 0;
}
然而
#include<stdio.h>
int main(void){
int a = 0;
int *p = &a;
int *pp = &p;
printf("&a=%p,p=%p,pp=%p\n",&a,p,pp);
return 0;
}
这里 pp 和 p 的%p 是不相同的.
对于第二个程序不相同我就很好理解了,p 中存放变量 a 的地址,pp 存放指针 p 的地址...
而对于第一个程序,arr 存放数组首元素地址,&arr 则是变量 arr 的地址.&arr 和 arr 显然不应该一样..
但它们就是一样了,这我就无法理解
1
Yourshell 2018-10-18 15:34:17 +08:00 via iPhone
数组的地址不就是首元素的地址吗
|
2
kkhaike 2018-10-18 15:35:22 +08:00
我能告诉你 arr 这个变量的地址就是他的首元素地址吗
|
3
kljsandjb 2018-10-18 15:53:40 +08:00 via iPhone
约定俗成的
|
4
Newyorkcity OP @kkhaike
简单一点,假定内存给每个字节分配一个地址,对 char s[]={'a','b'},假定地址 01 的空间存储'a'对应的 ASCII 码,地址 02 的空间存储'b'对应的 ASCII 码,那么 s 应该分到 03-10 共 8 个 byte 作为它的空间用来存储 01(数组首元素的地址),那么 s 的地址,也就是&s 应当是 03..如果认为 s 这个变量的地址就是数组首元素的地址,那 01-08 共 8 个字节用来存储数组首元素'a'的地址 01,地址为 01 和 02 的字节就必须为 0,那还怎么存储'a'和'b'的 ASCII 码? |
5
wevsty 2018-10-18 16:51:34 +08:00 1
@Newyorkcity
1、不用假定,内存里面的每个 byte 都一定有地址对应。 2、在你的例子里,char s[]作为数组 s 本身可以理解为只有编译器知道的一个地址的别名,这个地址本身不占用内存空间,只有数组里面储存的内容才占用空间。 |
6
misaka19000 2018-10-18 16:52:04 +08:00
append 看晕了,不过隐约感觉楼主好像把 bit 和 byte 搞混了,1byte = 8bits
|
7
Newyorkcity OP |
8
innoink 2018-10-18 16:57:11 +08:00 1
并不存在一个“单独的” arr 变量。arr 你可以理解为一个**字面量**。意思是,这个 arr 会被当成立即数或者编译期常量来用,并不需要占有一个专门的内存单元。
|
10
wevsty 2018-10-18 17:04:13 +08:00 1
@Newyorkcity
顺便说一句 指针类型不一定是 8 byte,这取决于机器的指令集。对于 X86 指针类型是 4 byte,对于 X64 来说才是 8 byte,不同的指令集对应的大小是不一定一样的。 |
11
msg7086 2018-10-19 00:19:27 +08:00
「&arr 和 arr 显然不应该一样」
这是怎么显然的。&arr 和 arr 显然本来就是一样的,唯一区别是类型,但是 arr 会自动转换(退化)成其地址,也就是在读取地址立即量的时候,arr 会自动退化成&arr。 另外,数组严格来说不能称作「变量」。arr 是「变量名」,但不是「变量」。数组是「一群变量 / 数据」的集合,数组本身不是变量,所以不像变量那样有地址,也不占用内存空间。你可以定义一个零长度的数组,其在内存中不占用任何空间。 |