为什么在打印字符串时不使用取消引用?

Why de-referencing is not used in case of printing of a string?

我们如何在 C 中使用字符串名称来打印字符串而不取消引用它?

在这里点赞:

char str[];
printf("%s",str);

但在数组的情况下,我们使用方括号[]取消引用来打印数组:

int a[10];
for(i=0;i<10;i++);
   printf("%d",a[i]);

打印字符串和数组有什么区别?我们需要通过使用方括号 [] 取消引用数组,但在字符串 的情况下不使用任何取消引用 printf();只是打印字符串的值而不是地址。

这完全取决于函数(printf 或其他)期望的内容。

当您将 printf 与 %s 一起使用时,例如

printf("%s",str);

printf() 想要“一个字符串”,在 C 中,它与“[NUL-terminated] char 的数组”相同。因此,您传递了唯一真正标识整个数组的东西:它的名称(衰减到第一个元素的地址)。

这同样适用于每个需要数组作为参数的函数。

如果对于您调用的函数,您必须传递其他内容,您可以使用不同的方法。当printf用于打印整数时,如

printf("%d",a[i]);

你必须传递一个整数;并且数组 不是 整数,因此您必须使用正确的 notation/mechanism 从数组中取消引用(或“select”)一个整数。但是,例如,如果您想使用结构的成员,情况并没有什么不同。您不能将结构传递给 printf(),因此您使用点来 select 结构的 [correct] 成员。这同样适用于指向整数的指针,当您需要值而不是指针本身时,您可以取消引用它们。等等功能...喜欢

printf("%d", (int) floor(PI));

在上面的行中,如果 printf 想要一个整数,你必须给它一个整数,所以要使用 PI (3.14),你必须将它转换为一个整数。

因为那是 printf 的接口规定的。

  • "%s" 的情况下,它期望 指向 NUL 终止字符串的指针
  • "%d" 的情况下,它需要一个 int

对于初学者来说,例如这样的代码片段

char str[5] = "Hello";
printf("%s",str);

可能会导致未定义的行为。

格式字符串 "%s" 期望参数是指向字符串第一个字符的指针。

在 C 中,字符串被定义为以零字符 '[=18=]' 结尾的字符序列。这是一个字符数组,其中包含一个具有标记值 '[=18=]'.

的字符串

所以实际上这样调用printf

printf("%s",str);

逻辑上类似于下面的代码

while ( *str != '[=12=]' ) putchar( *str++ );

在上面的例子中

 char str[5] = "Hello";

字符数组 str 不包含字符串,因为它的五个元素是由字符串文字 "Hello" 的字符初始化的,不包括它的终止零字符(没有足够的 space在数组中容纳字符串文字的第六个字符 '[=18=]')。

所以这样的调用

printf("%s",str);

对于上面声明的数组,将尝试输出内存中数组后面的任何内容。

为了避免未定义的行为,您应该声明数组,例如

 char str[6] = "Hello";

或喜欢

 char str[] = "Hello";

至于其他基本类型的数组,那么在大多数情况下它们没有标准的标记值。与字符串相反,不可能为整数或浮点数组定义这样的标记值。

所以包含字符串的字符数组是排除在所有数组种类之外的。根据 C 中字符串的定义,字符串始终以终止零字符 '[=18=]' 结尾。这对其他类型的数组无效。

因此,要输出任何其他类型的数组,您通常需要使用一个循环来知道您需要输出多少元素。