我试图理解数组和指针之间存在的特殊关系,即没有括号的数组名称总是指向数组的第一个元素。
在Linux系统上,我用C程序得到它:
char name[7] = "unique";
printf("\nAddress stored of name: %p", name);
printf("\nAddress stored of name: %s", name); //Conflict
printf("\nAddress of name[0]: %p", &name[0]);
//dereferencing the pointer
printf("\nValue of name[0]: %c", *name);
printf("\nValue of name[1]: %c", *(name+1));
输出结果为:
Address stored of name: 0xbff68131
Address stored of name: unique
Address of name[0]: 0xbff68131
Value of name[0]: u
Value of name[1]: n
我理解上面输出中的所有内容,但 // Conflict 的代码行输出除外。换句话说,如果 name 等同于& name [0] ,根据数组和指针之间的特殊关系,那么为什么只需更改格式说明符(来自%p)到%s)打印数组的实际值。如果情况确实如此,那么这是否意味着名称,& name [0] 和 * name 都相同?
我至少期望它(// Conflict)打印一些其他(垃圾?)值,但不打印数组的实际值。
答案 0 :(得分:2)
%s
这告诉printf
将参数视为指向包含字符数组的内存位置的指针,并打印每个字符,直到遇到\0
为止。
%p
这会将争论视为内存位置,并以十六进制打印其值,如您所见。
你所谓的“冲突”实际上是更重要的用途,也是打印c-strings的正确方法。
答案 1 :(得分:-1)
当使用数组表达式代替指针表达式时,数组表达式将转换为指向第一个元素的指针。指向第一个元素的指针是array+0
或&array[0]
,第一个元素是*(array+0)
或array[0]
。
在printf("\nAddress stored of name: %p", name);
中,数组表达式转换为指向第一个元素的指针。同样地,对于printf("\nAddress stored of name: %s", name);
,名称将转换为指向name[0]
的指针。添加1会产生指向name[1]
的指针。添加2会产生指向name[2]
等的指针
值得注意的是array[n]
运算符实际上是pointer[n]
运算符,array
转换为指向第一个表达式的指针。 n被添加到指针以产生指向第n个元素的指针,然后将其解除引用以从其指针中生成第n个元素。这是%s
格式说明符的结果。但是,%p
格式说明符根本不进行任何解除引用。
如果确实如此,那么这是否意味着名称,& name [0]和 *名字都相同?
没有。 name
是一个数组表达式:sizeof name
将导致7. &name[0]
是一个指针表达式,转换为“指向名称[0]的指针”:sizeof &name[0]
将导致sizeof (char *)
。 *name
是一个char表达式,转换为“由name指向的char”。 sizeof *name
将导致1。