m*********a 发帖数: 3299 | 1 二位矩阵array,比如multi[5][10]
为啥multi,*multi,&multi的地址都是一样的?
看下面的程序的运行结果
&multi is 0028FE58
multi is 0028FE58
*multi is 0028FE58
**multi is 67
&multi[0] is 0028FE58
multi[0] is 0028FE58
&multi[0][0] is 0028FE58
multi[0][0] is 67
#include
int main(void){
int multi[5][10]; /*define a two dimensional 5x10 array with a name multi*/
multi[0][0]=67; /*assign 67 to the first element of array*/
printf("&multi is %pn",&multi);
printf("multi is %pn",multi);
printf("*multi is %pn",*multi);
printf("**multi is %dn",**multi);
printf("&multi[0] is %pn",&multi[0]);
printf("multi[0] is %pn",multi[0]);
printf("&multi[0][0] is %pn",&multi[0][0]);
printf("multi[0][0] is %dn",multi[0][0]);
return 0;
} |
d****i 发帖数: 4809 | 2 This can be a bit confusing. In C, multi-dimensional array is stored in
contiguous memory. So c[i][j]=*(*(c+i)+j). For each line, see my comment
below:
#include
int main(void){
int multi[5][10]; /*define a two dimensional 5x10 array with a name multi*/
multi[0][0]=67; /*assign 67 to the first element of array*/
printf("&multi is %pn",&multi); //address of the array
printf("multi is %pn",multi); //same as above
printf("*multi is %pn",*multi); //address of the first row of the array,
which is the same as the address of the array
printf("**multi is %dn",**multi); //the first element
printf("&multi[0] is %pn",&multi[0]); //the address of the first row,
which is the same as multi
printf("multi[0] is %pn",multi[0]); //same as above
printf("&multi[0][0] is %pn",&multi[0][0]); //The address of the first
element, which is the same as address of the array
printf("multi[0][0] is %dn",multi[0][0]); //first element
return 0;
}
【在 m*********a 的大作中提到】 : 二位矩阵array,比如multi[5][10] : 为啥multi,*multi,&multi的地址都是一样的? : 看下面的程序的运行结果 : &multi is 0028FE58 : multi is 0028FE58 : *multi is 0028FE58 : **multi is 67 : &multi[0] is 0028FE58 : multi[0] is 0028FE58 : &multi[0][0] is 0028FE58
|
m*********a 发帖数: 3299 | 3 多谢回答
你知道这个问题的答案吗?
比如需要二次deference **multi才会给出67
但是如果你定义一个指针 int *ptr;
ptr=multi;
*ptr就等于67了
,
【在 d****i 的大作中提到】 : This can be a bit confusing. In C, multi-dimensional array is stored in : contiguous memory. So c[i][j]=*(*(c+i)+j). For each line, see my comment : below: : #include : int main(void){ : int multi[5][10]; /*define a two dimensional 5x10 array with a name multi*/ : multi[0][0]=67; /*assign 67 to the first element of array*/ : printf("&multi is %pn",&multi); //address of the array : printf("multi is %pn",multi); //same as above : printf("*multi is %pn",*multi); //address of the first row of the array,
|
S*A 发帖数: 7142 | 4
这个说法其实要是不懂 C array 指针的地址退化规则理解会更加混乱。
看了你的解释事乎访问 c[i][j] 要 de-reference 变量 c 两次。
其实没有。这里只有一个 load.
c[i][j] 等价于 *(base_addr + i*ARRAY_SIZE(c[0]) + j), 其中 ARRAY_SIZE
是 constant. base_addr 是数组 C 的地址。
,
【在 d****i 的大作中提到】 : This can be a bit confusing. In C, multi-dimensional array is stored in : contiguous memory. So c[i][j]=*(*(c+i)+j). For each line, see my comment : below: : #include : int main(void){ : int multi[5][10]; /*define a two dimensional 5x10 array with a name multi*/ : multi[0][0]=67; /*assign 67 to the first element of array*/ : printf("&multi is %pn",&multi); //address of the array : printf("multi is %pn",multi); //same as above : printf("*multi is %pn",*multi); //address of the first row of the array,
|
S*A 发帖数: 7142 | 5 你需要知道,& 取地址是有特例的, 那就是数组和函数指针。
数组一般的表达为 a[sub_script]. 函数是 func(..)
如果没有后面的 【】 ,数组自动退化为数组的指针。
a 是 &a[0] 的简化写法, 这是一个隐含规则,当 a 后面没有【】的
时候触发。
*multi = multi[0] ,这是一个一维数组。Type 是 basetype[len_of_y]
所以 **multi = *(multi【0】)=multi【0】【0】
【在 m*********a 的大作中提到】 : 多谢回答 : 你知道这个问题的答案吗? : 比如需要二次deference **multi才会给出67 : 但是如果你定义一个指针 int *ptr; : ptr=multi; : *ptr就等于67了 : : ,
|
S*A 发帖数: 7142 | 6 你这个例子里面区别是退化后的 C type
ptr 的 C type 是 int *
mutli 的 C type 是 int [][]
multi[0] 的 C type 是 int 【】,等价于 int *。
【在 m*********a 的大作中提到】 : 多谢回答 : 你知道这个问题的答案吗? : 比如需要二次deference **multi才会给出67 : 但是如果你定义一个指针 int *ptr; : ptr=multi; : *ptr就等于67了 : : ,
|
z*******n 发帖数: 1034 | 7 不是memory order的问题 是arrays 和 pointers的区别问题
,
【在 d****i 的大作中提到】 : This can be a bit confusing. In C, multi-dimensional array is stored in : contiguous memory. So c[i][j]=*(*(c+i)+j). For each line, see my comment : below: : #include : int main(void){ : int multi[5][10]; /*define a two dimensional 5x10 array with a name multi*/ : multi[0][0]=67; /*assign 67 to the first element of array*/ : printf("&multi is %pn",&multi); //address of the array : printf("multi is %pn",multi); //same as above : printf("*multi is %pn",*multi); //address of the first row of the array,
|
t****t 发帖数: 6806 | 8 actually, array is NOT equivalent to pointer. array will decay to pointer wh
en use in expression, with certain exceptions.
【在 S*A 的大作中提到】 : 你这个例子里面区别是退化后的 C type : ptr 的 C type 是 int * : mutli 的 C type 是 int [][] : multi[0] 的 C type 是 int 【】,等价于 int *。
|
z*******n 发帖数: 1034 | 9 英语的好处就是术语 中文有时候你不知道在说什么 cfaq是不是就好理解的解释
wh
【在 t****t 的大作中提到】 : actually, array is NOT equivalent to pointer. array will decay to pointer wh : en use in expression, with certain exceptions.
|
S*A 发帖数: 7142 | 10 对,这是比较正式的一点说法。
我是想说他的区别关键在 C type 上面的结果。
你说说 array in expression 还有什么特别 exceptions?
前面有 &, sizeof (array), typeof(array)?
array 到了编译器后端就全部变成 pointer 统一起来
了。这 array vs pointer 对生成代码没有什么区别。
wh
【在 t****t 的大作中提到】 : actually, array is NOT equivalent to pointer. array will decay to pointer wh : en use in expression, with certain exceptions.
|
|
|
m*********a 发帖数: 3299 | 11 讨论这么热烈。我还是只能说array不是指针来理解。
他有自己的规则, **multi对于array不是deference二次
但是对于指针**ptr就是,deference二次。
是不?
wh
【在 t****t 的大作中提到】 : actually, array is NOT equivalent to pointer. array will decay to pointer wh : en use in expression, with certain exceptions.
|
d****i 发帖数: 4809 | 12 对,你这个解释更好,我那个等于实际上是对于指向指针的指针来说的,实际上对于
array来说只有derefenrece一次。
【在 S*A 的大作中提到】 : 对,这是比较正式的一点说法。 : 我是想说他的区别关键在 C type 上面的结果。 : 你说说 array in expression 还有什么特别 exceptions? : 前面有 &, sizeof (array), typeof(array)? : array 到了编译器后端就全部变成 pointer 统一起来 : 了。这 array vs pointer 对生成代码没有什么区别。 : : wh
|
z*******n 发帖数: 1034 | 13 哪个编译器
【在 S*A 的大作中提到】 : 对,这是比较正式的一点说法。 : 我是想说他的区别关键在 C type 上面的结果。 : 你说说 array in expression 还有什么特别 exceptions? : 前面有 &, sizeof (array), typeof(array)? : array 到了编译器后端就全部变成 pointer 统一起来 : 了。这 array vs pointer 对生成代码没有什么区别。 : : wh
|
m*********a 发帖数: 3299 | 14 c[i][j] 等价于 *(base_addr + i*ARRAY_SIZE(c[0]) + j),这个是对的
这个base_addr 是 *multi 或 multi[0],不是multi
【在 d****i 的大作中提到】 : 对,你这个解释更好,我那个等于实际上是对于指向指针的指针来说的,实际上对于 : array来说只有derefenrece一次。
|
t****t 发帖数: 6806 | 15 "The exceptions are when the array is the operand of a sizeof or & operator,
or is a string literal initializer for a character array."
C FAQ
【在 S*A 的大作中提到】 : 对,这是比较正式的一点说法。 : 我是想说他的区别关键在 C type 上面的结果。 : 你说说 array in expression 还有什么特别 exceptions? : 前面有 &, sizeof (array), typeof(array)? : array 到了编译器后端就全部变成 pointer 统一起来 : 了。这 array vs pointer 对生成代码没有什么区别。 : : wh
|
S*A 发帖数: 7142 | 16 嗯,和我想的差不多。我漏掉了 literal string initializer
FAQ 漏掉了 typeof。
operator,
【在 t****t 的大作中提到】 : "The exceptions are when the array is the operand of a sizeof or & operator, : or is a string literal initializer for a character array." : C FAQ
|
t****t 发帖数: 6806 | 17 typeof is not part of standard C.
【在 S*A 的大作中提到】 : 嗯,和我想的差不多。我漏掉了 literal string initializer : FAQ 漏掉了 typeof。 : : operator,
|
f*******n 发帖数: 12623 | 18 关于 **multi,是multi(int[5][10]),decay成指针(int (*)[10]),跟着
dereference(结果int[10]),再decay成指针(int *),跟着再dereference(结果
int)。所以**multi的确是有两次dereference,只不过再加上两次decay。
【在 m*********a 的大作中提到】 : 讨论这么热烈。我还是只能说array不是指针来理解。 : 他有自己的规则, **multi对于array不是deference二次 : 但是对于指针**ptr就是,deference二次。 : 是不? : : wh
|
S*A 发帖数: 7142 | 19 你这个理解不对。只有一次 dereference。
二维的下标只是用来计算转换的连续一维数组(内存)的 offset。
下标的 offset 计算本身不是 dereference.
我给你这个示范程序,注意看这里面的 array assign.
只用了一个 dereference。
======================
int a[5][6];
void foo(void)
{
a[1][2] = 1;
**a = 2;
}
======================
$ gcc -S -O2 multi.c
.file "multi.c"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
.LFB0:
.cfi_startproc
movl $1, a+32(%rip) // 这里是 a[1][2] = 1
movl $2, a(%rip) // 这里是 **a = 2
ret
.cfi_endproc
.LFE0:
.size foo, .-foo
.comm a,120,32
.ident "GCC: (GNU) 4.8.2 20131212 (Red Hat 4.8.2-7)"
.section .note.GNU-stack,"",@progbits
【在 f*******n 的大作中提到】 : 关于 **multi,是multi(int[5][10]),decay成指针(int (*)[10]),跟着 : dereference(结果int[10]),再decay成指针(int *),跟着再dereference(结果 : int)。所以**multi的确是有两次dereference,只不过再加上两次decay。
|
f*******n 发帖数: 12623 | 20 我的理解完全对。我是说语义。跟compiler怎么实现没有关系。
【在 S*A 的大作中提到】 : 你这个理解不对。只有一次 dereference。 : 二维的下标只是用来计算转换的连续一维数组(内存)的 offset。 : 下标的 offset 计算本身不是 dereference. : 我给你这个示范程序,注意看这里面的 array assign. : 只用了一个 dereference。 : ====================== : int a[5][6]; : void foo(void) : { : a[1][2] = 1;
|
|
|
S*A 发帖数: 7142 | 21 Dereference means accessing the memory variable by the pointer
address. In other words, dereference meaning memory load or
store using pointer.
int multi[4][5];
multi【0】 as expression can decay to a pointer. That itself
is not an deference. Just like
int array[5];
expression "array" by itself is not a dereference.
It is just a pointer.
【在 f*******n 的大作中提到】 : 我的理解完全对。我是说语义。跟compiler怎么实现没有关系。
|
f*******n 发帖数: 12623 | 22 No. Dereference means the * operator, which takes a "pointer to T"
expression and evaluates to a "T" expression.
And arrays and pointers are very different things.
【在 S*A 的大作中提到】 : Dereference means accessing the memory variable by the pointer : address. In other words, dereference meaning memory load or : store using pointer. : int multi[4][5]; : multi【0】 as expression can decay to a pointer. That itself : is not an deference. Just like : int array[5]; : expression "array" by itself is not a dereference. : It is just a pointer.
|
S*A 发帖数: 7142 | 23 Where is your definition come from? Any link?
The stander C definition does not have definition for "dereference".
The closest one I can find about the memory reference is at:
http://cplus.about.com/od/glossar1/g/dereference.htm
You said array and pointer are very different thing.
At the same time you are using pointer operation to explain
array dereference.
【在 f*******n 的大作中提到】 : No. Dereference means the * operator, which takes a "pointer to T" : expression and evaluates to a "T" expression. : And arrays and pointers are very different things.
|