假设我有两个功能:
void function1(int *ptr) {
printf("%d", *ptr);
}
和
void function2(char *str) {
printf("%s", str);
}
为什么function2在str
之前没有deference运算符时有效?在str
中,只有地址,它指的不是我想的值。
答案 0 :(得分:7)
为什么function2工作,之前没有deference运算符 STR
由于标准定义的%s
需要char *
,即地址。
7.21.6.1
如果不存在l length修饰符,则参数应为指针 字符类型数组的初始元素。人物 从数组写到(但不包括) 终止空字符。如果精确度是指定的,则不再存在 而不是写入多少字节。 如果未指定精度或是 大于数组的大小,数组应包含空字符。
答案 1 :(得分:6)
因为使用pointer to a char
时printf
是特殊的。它将其视为指向单个char的指针,而不是将其视为指向NUL
分隔的字符数组中第一个元素的指针,而不是仅仅是一个指针。
答案 2 :(得分:1)
在C中引用字符串的方式是第一个字符的地址。读取字符串的函数将读取此地址处的字节,对其执行某些操作(例如,在printf()
的情况下打印它),然后移动到下一个字符。这将一直持续到找到零字节,表示字符串结束。
这基本上是一种节省记忆的方法。其他基本数据类型(如int
)足够小,可以便宜地复制它们的值,因此无需引用对象的地址。
答案 3 :(得分:1)
因为我们写的时候
char *s="hello";
s
默认采用第一个元素的第一个地址的地址,即'h'的地址
printf中的%s和%s打印整个字符串而不是元素@ first location。
因此,它永远不需要尊重运算符。它可能会使C编译器混淆是打印第一个元素还是所有元素。
答案 4 :(得分:1)
之所以这样,是因为编写了printf()
函数来理解传递给它的不同类型的参数。字符串中的格式说明符告诉printf()
每个参数的期望值。然后文档会告诉你要传递给它的内容。
<强>即。基本上它是有效的,因为printf()
遵循已定义的规范,并且您正在关注它。
因此,在您的第一个示例中,您使用的是%d格式。 printf()
认为参数应该是一个整数值。不是指向整数的指针,而是整数。这就是为什么这样做的原因:
void function1(int *ptr) {
printf("%d", *ptr);
}
而这不是:
void function1(int *ptr) {
printf("%d", ptr);
}
你的第二个例子是一个字符串,这里有一些混淆的可能性,因为C中的字符串实际上不是直接的数据类型(如此)。它们是指向一个字符的指针通过其他字符然后以NULL \ 0终止。
void function2(char *str) {
printf("%s", str);
}
现在,如果字符串是C中的数据类型,那么您可能会以与执行其他值相同的方式传递它们(这纯粹是假设的):
void function2(string str) {
printf("%s", str);
}
总结如下:
%d -> int
%s -> char *