有人告诉我作为我上一次question
的回答char *name[] = {"xxx", "yyy"}
由编译器更改为
char *name[] = {Some_Pointer, Some_Other_Pointer};
我尝试了以下内容以便理解:
printf("%p\n", &name);
printf("%p\n", name);
printf("%s\n", *name);
printf("%c\n", **name);
所以作为输出它给了我:
0xfff0000f0
0xfff0000f0
xxx
x
你能解释一下指针“name”的地址如何与指针“name”所指向的地址相同吗? 根据我的理解,指针“name”本身占用8个字节。如何在内存中占用4个字节的第一个字符串“xxx”与指针位于同一位置?
答案 0 :(得分:7)
首先,当你在C中有任何类似name
的数组时,数组的值是其第一个元素的地址。请注意,此值不存储在某个变量中。它在编译的汇编代码中用作立即值。因此,考虑其地址是没有意义的。
其次,由于数组作为一堆连续位置存储在存储器中,所以数组的地址定义为第一个元素的地址。因此,对于任何数组A
,您都具有以下地址相等性
&(A[0]) == A == &A
如果您有指针数组或其他任何内容,它不会改变任何内容。
答案 1 :(得分:4)
要查看“xxx”的地址,您应该像这样打印printf("%p\n", name[0]);
。当然是name and address of "xxx" wont be the same
的地址。此处name
为array of pointer
,其中包含“xxx和yyy”的地址。
printf("%p\n", &name);
printf("%p\n", name);
printf("%p\n", name[0]); address of "xxx"
printf("%p\n", name[1]); address of "yyy"
答案 2 :(得分:2)
name
的类型从array of char*
衰减到pointer to char*
,其值是数组第一个元素的地址。表达式&name
的类型为pointer to char* [2]
,其值为数组的地址,该数组的地址与数组的第一个元素的地址相同。
似乎你误解了C中数组的表示。没有一个“meta”对象表示C中的数组.C中的数组只包含其序列中的元素。因此应用运算符&到数组名称只是获取数组的第一个元素的地址(值 - 而不是类型)。
如果您尝试写作:
char (*p)[2] = &name;
printf("%p", &p);
这会打印出address of a pointer to an array
,它肯定会与name
和&name
不同。
答案 3 :(得分:2)
你能解释一下指针“name”的地址如何与指针“name”所指向的地址相同吗?
&name
为您提供整个指针数组的地址(其中包含指向字符串XXX
和YYY
)的指针,name
将为您提供指向它的第一个元素,即XXX
(衰变后)。由于第一个字节的地址被称为变量(数组)的地址,因此&name
的值与name
的值相同,但&name
和{{1}的值都相同是不同类型的。
答案 4 :(得分:2)
根据我的理解,指针“name”本身占用8个字节。怎么样 可以在内存中占用4个字节的第一个字符串“xxx” 与指针位置相同的位置?
那是因为name
是一个数组,而不是一个指针。指针是存储相同类型的另一个变量的地址的变量,但是数组是绑定到(由单个标识符引用)的连续内存块。基本上,它是一种不同的类型。请注意,数组不是C中的第一类对象 - 您无法将数组传递给函数或从函数返回数组。
由于数组在许多情况下衰变(隐式转换)为指向其第一个元素的指针,因此产生混淆。发生这种情况的一些情况是:
void f(char p[]); // p is a pointer, not an array
// This is exactly the same as
void f(char *p);
char s[] = {'h', 'e', 'l', 'l', 'o'};
f(s); // here s decays to a pointer to its first element
// another example
char t = "hello"[1]; // the string literal decays to a pointer to its first element
以下是数组保持数组(不会衰变为指针)的一些情况:
char s[] = "hello";
char *t = "hello"; // string literal decays into a pointer
printf("%d", sizeof s); // prints 5
printf("%d", sizeof t); // prints 4 or 8 depending on the pointer size on the machine
printf("%d", sizeof *t); // prints 1
// taking your example
char *name[] = {"xxxx", "yyyy"}; // yet another case where string literals decay to a pointer
printf("%p", name); // name is an array but here decays to a pointer
printf("%p", &name); // &name is a pointer to an array of 2 pointers to characters
虽然name
,&name
在printf
调用中评估的值相同,但它们的类型不同。要看到差异,请执行以下操作:
printf("%p", name + 1);
printf("%p", &name + 1);
printf("%d", *(&name + 1) - name); // prints the length of the array
总而言之,数组和指针是不同的类型。指针存储地址,数组存储它们被定义为存储的类型的值。在某些情况下,数组会计算其第一个元素的地址。这就是数组和指针之间的相似性结束的地方。