我在读完这篇文章后回来c-faq question我完全混淆了这里发生的事情。
#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]它给出了为什么?在ar [3]的情况下没问题,但为什么在ar [4]的情况下另一个想法:在c-faq中提到如果你指定任何字符串等于声明的数组的大小,你就不能使用printf(“在c-faq中提到的那个数组上的%s“)和strcpy()。但在我上面的代码中我使用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]对它进行comapre时它仍然给我null而不是一些垃圾值..
答案 0 :(得分:5)
您的代码显示未定义的行为。它偶然适合你,但在另一台机器上它可能会失败。正如您从常见问题解答中所理解的那样,代码无效。但这并不意味着它总会失败。这只是未定义行为的本质。从字面上看,任何事情都可能发生。
访问ar[3]
是非法的,因为这超出了数组的末尾。此数组的有效索引为0,1和2.
您没有为c
分配内存,因此指针的任何解引用都是未定义的行为。
您的main
声明有误。你应该写:
int main(void)
答案 1 :(得分:2)
不要这样做。声明char NIS[3];
为您提供了一个三字符数组,您可以使用索引0
到2
包含这些数据。
任何使用其他索引(用于解除引用)都是未定义的行为,不应该这样做。
它可能起作用的原因是因为没有任何说明“垃圾”值必须是非零的。这就是垃圾在这种情况下的含义,它们可以是任何东西。
您的strcpy
也是未定义的行为,因为您的c
指针尚未初始化为任何有用的内容。
答案 2 :(得分:0)
ar [3]不存在,因为ar只有3个字符长。
该常见问题解答 是合法的,但它不是C字符串。
如果数组太短,则会切断空字符。
基本上,“abc”是静默'a','b','c',0。但是,由于ar的长度为3而不是4,因此空字节会被截断。
编译器在这种情况下(以及操作系统)选择做什么是未知的。如果它碰巧运作,那就是好运。