C:字符数组的字符串赋值

C:字符数组的字符串赋值,c,C,我读完这篇文章回来,我完全搞不懂这里发生了什么 #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"

我读完这篇文章回来,我完全搞不懂这里发生了什么

#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]);
  }
}

这里,当我将ar[3]与“\0”进行比较时,它给出的是null,这没关系,但是当我将它与ar[4]进行比较时,它仍然给我null,而不是一些垃圾值。

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

那个常见问题是说它是合法的,但它不是一个C字符串

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

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


编译器在这种情况下(以及操作系统)选择做什么还不得而知。如果它碰巧工作,那只是运气好。

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

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

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

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

int main(void)

不要这样做。声明
charnis[3]
提供了一个三字符数组,您可以使用索引
0
2
包括在内

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

它可能工作的原因是因为没有任何东西说明“垃圾”值必须是非零的。这就是垃圾在这里的意思,它们可以是任何东西


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

ar[3]
不是c字符串。声明它为
ar[4]
,这样它就可以容纳额外的
\0
字节。@Daniel Kamil Kozar:亲爱的,请先阅读整个问题,为什么你这么匆忙……我知道你指出了什么。在你的函数输入时,堆栈的内容是未定义的。在这种情况下,您显然很幸运,在您的C字符串后面有一个
\0
。然而,情况并非总是如此。很抱歉没有早点读完整的问题。另外,
intmain(void)
而不是
void main()
@DanielKamilKozar:在我的代码中提到main(void)有必要吗?我不认为soYes。在C语言中,
main()
创建了一个具有任意数量参数的函数。请检查那里,它正在那里工作。请重新阅读答案。代码似乎在一个平台和编译器上工作,这一事实并不意味着代码是合法的。你真走运。你的运气很快就会耗尽。起初我是正确的,但代码板让我很困惑…我检查了那里的代码板只是在那里失去了头脑…是否有必要在主函数参数和返回类型int中提到void。你的main是非标准的。当然更容易做对吗?
int main(void)