我有一个基本的C编程问题,这是情况。如果我正在创建一个字符数组,并且如果我想使用%s转换代码将该数组视为字符串,我是否必须包含空零。例如:
char name[6] = {'a','b','c','d','e','f'};
printf("%s",name);
控制台输出为:
abcdef
请注意,数组中的最后一个元素没有空零,但我仍然将其打印为字符串。
我是编程的新手......所以我正在阅读一本初学者C书,其中指出,由于我在最后一个元素中没有使用空零,所以我不能将它视为字符串。
这是与上面相同的输出,尽管我包含零值。
char name[7] = {'a','b','c','d','e','f','\0'};
printf("%s",name);
答案 0 :(得分:5)
你只是幸运;可能在该数组结束后,在堆栈上,为零,所以printf
在最后一个字符后停止读取。如果您的程序非常短并且堆栈区域仍然未被发现" - 即堆栈还没有增长到那一点 - 它非常容易归零,因为通常现代操作系统会给应用程序提供最初归零的页面。
更正式地说:由于没有明确地NUL
终结者,你将进入未定义行为的土地,这意味着任何事情都可能发生;这样的任何事情也可能是你的程序工作正常,但它只是运气 - 而且它是最糟糕的类型的bug,因为如果它通常工作正常,很难发现。< / p>
TL; DR版本:不要这样做。坚持保证工作,你不会在你的应用程序中引入偷偷摸摸的错误。
答案 1 :(得分:3)
您的拳头printf
的输出无法预测,因为您未能包含终止零字符。如果它似乎在您的实验中起作用,那只是因为随机的可能性是内存中的下一个字节碰巧为零并且作为零终止符。发生这种情况的可能性很大程度上取决于您声明name
数组的位置(您的示例不清楚)。对于静态数组,机会可能相当高,而对于本地(自动)数组,您将经常遇到各种垃圾。
答案 2 :(得分:2)
你必须在最后包含空字符。
由于运气和运气,它没有错误。试试这个:
char name[6] = {'a','b','c','d','e','f'};
printf("%s",name);
printf("%d",name[6]);
你很可能会看到你可以读取那个记忆,并且它中有一个零。但这绝对是运气。
答案 3 :(得分:0)
最可能发生的是在内存位置名称+ 6处碰巧有0的值。虽然这不是定义的行为,但是您可以在不同的系统上或使用不同的编译器获得不同的输出。
答案 4 :(得分:0)
是。你做。还有其他几种方法可以做到。
这种初始化形式会自动为您提供NUL字符。
char name[7] = "abcdef";
printf("%s",name);
请注意,我在数组大小中添加了1,以便为该NUL腾出空间。
人们也可以省略大小,让编译器弄明白。
char name[] = "abcdef";
printf("%s",name);
另一种方法是使用指向char的指针来指定它。
char *name = "abcdef";
printf("%s",name);