我正在读一本有关c语言的书,对它的字符串指针示例之一有疑问。
int x;
char *str = "Food";
printf("Pointer variable value: %p\n", *str);
printf("Pointer points to: %s\n", str);
printf("Memory locations of chars are: \n");
for(x = 0; x < 5; x++)
printf("%p\n", str[x]);
为什么在第一个printf
的字符串名称前面需要间接运算符,为什么在for
循环printf
中不需要地址运算符?>
但是,当我执行此程序时,两个'o'字符实际上具有相同的地址。当我在str[x]
前面添加address-of运算符时,地址变得连续。
答案 0 :(得分:1)
以下一行是错误的。
printf("Pointer variable value: %p\n", *str);
要打印指针,第二个参数只需为str
。
printf("Pointer variable value: %p\n", str);
以下一行也是错误的。
printf("%p\n", str[x]);
要打印指针,请将第二个参数更改为&str[x]
。
printf("%p\n", &str[x]);
答案 1 :(得分:0)
%p
用于打印指针。
来自C标准#7.21.6.1p8
p
该参数应为指向void的指针。指针的值以实现定义的方式转换为一系列打印字符。
编译器必须在以下两个语句上给出警告消息:
printf("Pointer variable value: %p\n", *str);
和
printf("%p\n", str[x]);
原因是%p
期望指向void
类型的指针,而您给出的是char
类型。
*str
等效于*(str + 0)
,*(str + 0)
是str[0]
,它是字符串str
的第一位置的字符。
因此,如果要打印指针,则应给定str
而不是*str
;如果要打印字符串的每个字符的地址,则应给定&str[x]
。
运算符&
用于获取地址,运算符*
用于取消引用。
所以
str[x] -> *(str + x)
&str[x] -> &(*(str + x))
这些运算符&
和*
相互抵消时会相互抵消。因此,
&(*(str + x)) -> (str + x)
str + x
是字符x
处的地址。
因此,正确的陈述是:
printf("Pointer variable value: %p\n", str);
和
printf("%p\n", &str[x]);