1

假设我有两个功能:

void function1(int *ptr) {
     printf("%d", *ptr);
}

void function2(char *str) {
     printf("%s", str);
}

为什么 function2 工作,当之前没有尊重运算符时strstr那里只有它指向的地址,而不是我想的值。

4

5 回答 5

7

当 str 之前没有遵循运算符时,为什么 function2 起作用

因为%s,按照标准的定义,需要一个char *,即一个地址。

7.21.6.1

如果不存在 l 长度修饰符,则参数应为指向字符类型数组的初始元素的指针。数组中的字符被写入(但不包括)终止空字符。如果指定了精度,则写入的字节数不会超过这个数。如果未指定精度或大于数组的大小,则数组应包含空字符

于 2012-07-25T15:45:50.390 回答
6

因为 apointer to a char在使用时是特殊的printf。它不是将其视为指向单个字符的指针,而是将其视为指向NUL分隔字符数组中第一个元素的指针,打印一个字符串而不是一个指针。

于 2012-07-25T15:46:26.170 回答
1

您在 C 中引用字符串的方式是通过其第一个字符的地址。读取字符串的函数将读取该地址处的字节,对其进行处理(例如打印它,在 的情况下printf()),然后移动到下一个字符。这一直持续到找到零字节,表示字符串的结尾。

这基本上是一种节省内存的方法。其他基本数据类型,如int,足够小,可以廉价地复制它们的值,因此无需引用对象的地址。

于 2012-07-25T15:48:37.747 回答
1

因为当我们写

char *s="hello";

s默认情况下,采用第一个元素的第一个地址的地址,即 printf 中的“h”地址和 %s 打印整个字符串而不是元素@第一个位置。因此,它从不需要遵从运算符。是否打印第一个元素或所有元素可能会使 C 编译器感到困惑。

于 2012-07-25T16:04:56.660 回答
1

这样做的原因是因为该printf()函数已被编写为理解传递给它的不同类型的参数。字符串中的格式说明符告诉printf()每个参数应该是什么。然后文档会告诉您要传递给它的内容。

IE。基本上它可以工作,因为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 *
于 2012-07-25T16:09:33.527 回答