考虑到必须在%p中分配指针,我期待编译错误,但是当我故意将指针指向%s时,下面的代码不会给我错误。通过添加&符号,它应该生成数组的地址并将内存地址分配到%p,而不是给出字符串的值。除非我取消引用指针,但我根本没有取消引用指针,我从不在printf中的my_pointer前放一个星号*。
#include <stdio.h>
int main()
{
char words[] = "Daddy\0Mommy\0Me\0";
char *my_pointer;
my_pointer = &words[0];
printf("%s \n", my_pointer);
return 0;
}
请看这个:
printf("%s \n", my_pointer);
我的理解是, * my_pointer (带星号*)应该给我字符串的值。 但是 my_pointer (没有星号)不应该给我字符串的值,但它应该只给我内存地址,但是当我运行这段代码时,我得到字符串的值尽管我没有不要把星号*放在前面。我希望这次我能说清楚。
答案 0 :(得分:2)
下面:
PointCloudMaterial
printf("%s \n", my_pointer);
,预计%s
,char*
是my_pointer
,char*
指向一个包含NUL终止字符串的数组,printf
没有问题并且完全有效。 C11标准的相关引用(强调我的):
7.21.6.1 fprintf函数
[...]
- 转换说明符及其含义如下:
醇>
[...]
s - 如果不存在l长度修饰符,参数应为指向初始值的指针 字符类型数组的元素。 280)数组中的字符是 写入(但不包括)终止空字符。如果 指定精度,不超过写入的多个字节。如果 精度未指定或大于数组的大小,数组应 包含空字符。
[...]
IMO,你在这里感到困惑:
考虑到必须在%p中指定指针,但是当我故意为%s指定指针时,下面的代码不会给我错误
首先,%s
,%p
等是转换说明符。它们用于某些功能,如printf
,scanf
等
接下来,您是指定指针类型的那个。所以这里:
my_pointer = &words[0];
&words[0]
以及my_pointer
的类型为char*
。因此,分配这两者是完全有效的,因为两者属于同一类型。
答案 1 :(得分:0)
在c中,数组名称也是指向第一个元素的指针,在您的情况下是words
和&words[0]
,当它们作为指针时,它们具有相同的值。
然后,将它分配给同一类型的另一个指针,这是合法的。
关于c中的字符串,它只是一个以'\0'
结尾的字符数组,其名称指针指向第一个字符。
答案 2 :(得分:0)
编译器正在严格按照要求处理您的代码。
%s
格式说明符告诉printf()
期望const char *
作为相应的参数。然后它认为指针是char
数组的第一个元素的地址,并打印它找到的每个char
,直到它遇到值为零('\0'
)的那个。
严格地说,编译器甚至不需要检查my_pointer
是const char *
,还是可以隐式转换为{{1}}。但是,大多数现代编译器(假设格式字符串是在编译时提供的)都可以做到这一点。