0

在阅读了这个c-faq 问题后,我回来了,我完全对这里发生的事情感到困惑。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main  ()
 {
   char ar[3]="NIS", *c;
   printf ("%s\n", ar);
   strcpy (c, ar);
   printf ("%s\n", c);
   if (ar[4] == '\0')
{
   printf ("Null");
 }
else 
  {
  printf ("%c\n", ar[4]);
  }
}

在这里,我分配了“NIS”等大小的声明数组。当我尝试访问 ar[3],ar[4] 时它给出 null 为什么?在 ar[3] 的情况下没关系,但为什么在 ar[4] 的情况下是这样的另一个想法:在 c-faq 中提到,如果您分配任何等于声明数组大小的字符串,则不能使用 printf (" %s") 和 strcpy() 在该数组上,如 c-faq 中所述。但是在我上面的代码中,我在这里使用了 printf 和 strcpy 都可以正常工作。可能是我解释错了,请纠正我。另一个问题是,当我尝试将 ar[5] 与 null 进行比较时,它没有打印任何可以的东西,但为什么它为 ar[4] 打印 Null。我对这个“NIS”字符串的想法将像这样存储在内存中。 .

提前致谢。

  --------------------------------------------------------
  |   N   |   I    |   S   |   /0   |  Garbage value here
  |_______|________|_______|________|_____________________
    ar[0]    ar[1]   ar[2]    ar[3]  

好吧,当我将 ar[3] 与 '\0' 进行比较时,它给出了 null 没关系,但是当我将它与 ar[4] 比较时,它仍然给我 null 而不是一些垃圾值..

4

3 回答 3

5

您的代码表现出未定义的行为。它偶然为您工作,但在另一台机器上它可能会失败。正如您从常见问题解答中了解到的那样,该代码无效。但这并不意味着它总是会失败。这只是未定义行为的本质。从字面上看,任何事情都可能发生。

访问ar[3]是非法的,因为它超出了数组的末尾。此数组的有效索引为 0、1 和 2。

您没有为此分配内存,c因此指针的任何取消引用都是未定义的行为。

你的main声明是错误的。你应该写:

int main(void)
于 2012-05-17T07:07:32.960 回答
2

不要这样做。该声明char NIS[3];为您提供了一个三字符数组,您可以使用它来使用0索引2

任何使用其他索引(用于取消引用)都是未定义的行为,不应这样做。

它可能工作的原因是因为没有说明“垃圾”值必须为非零。这就是垃圾在这种情况下的含义,它们可以是任何东西。

strcpy的行为也是未定义的,因为您的c指针尚未初始化为任何有用的东西。

于 2012-05-17T07:11:00.653 回答
0

ar[3] 不存在,因为 ar 只有 3 个字符长。

该常见问题解答说它合法的,但它不是C 字符串。

如果数组太短,空字符将被截断。

基本上,“abc”默认为“a”、“b”、“c”、0。但是,由于 ar 的长度为 3 而不是 4,因此空字节会被截断。

编译器在这种情况下(和操作系统)选择做什么是未知的。如果它碰巧起作用,那只是运气。

于 2012-05-17T07:05:25.847 回答