Question about terminating strings in C

在C问题终止字符串

Tags: c string null
标签: c string null

问题 (Question)

I've seen two ways to terminate a string.

// char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\n'}; //ignore this one, /n does not terminate

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}

and

char greeting[6] = {'H', 'e', 'l', 'l', 'o', 0};

Out of curiosity, which one is more standard?


Another question I have is with the below code

char greeting[] = {'H', 'e', 'l', 'l', 'o'};
printf("Greeting message: %s\n", greeting );
//output message is Greeting message: Hello? Question mark is upside down in Xcode

What happened here? I expected compiler to detect the size of the string itself and add a terminating character after the last character. Then in that printf statement, it would stop after the 'o'. Why is there a ? there? Also how did it know to stop after the '?' ? Was it possible for it to keep going and split out random characters until it crashes or miraculously find a random null terminating character in memory?

我见过两种方式终止一个字符串。

// char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\n'}; //ignore this one, /n does not terminate

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'}

char greeting[6] = {'H', 'e', 'l', 'l', 'o', 0};

出于好奇,哪一个更标准?


另一个问题我有如下的代码

char greeting[] = {'H', 'e', 'l', 'l', 'o'};
printf("Greeting message: %s\n", greeting );
//output message is Greeting message: Hello? Question mark is upside down in Xcode

这里发生了什么事?我希望编译器检测字符串本身的大小和最后一个字符之后添加一个终止字符。然后在printf语句,将停止后,“o”。为什么有?在吗?还怎么知道停止后”?”?很有可能要继续和拆分随机字符,直到崩溃或奇迹般地找到随机空终止字符在内存吗?

最佳答案 (Best Answer)

If you put a \0 in a string that is a way to tell the compiler that this is something special. Specifically it tells the compiler that it is a null. Also these are generally tucked inside of strings.

To answer your question I don't think that either is more standard. The more standard way to do this is:

char greeting[] = "Hello";

or more generally:

const char *greeting = "Hello";

This code:

char greeting[] = {'H', 'e', 'l', 'l', 'o'};
printf("Greeting message: %s\n", greeting );

prints out a strange character because the string is not explicitly terminated.

如果你把一个\ 0的字符串来告诉编译器,这是一些特别的东西。特别是它告诉编译器,它是一个空值。这些通常插在里面的字符串。

回答你的问题我也不认为更标准。更标准的方法是:

char greeting[] = "Hello";

答案 (Answer) 2

An addendum to the other answer. The difference between the two is very subtle. '\0' is a character constant that is zero (one byte.) '0' is an integer constant that is zero (usually four bytes.) When you assign an integer constant to a character, it is implicitly converted. So in your second example, 0 is implicitly converted to '\0' before assigning to the array.

The effect is identical, so it really doesn't matter, but you could argue that '\0' is slightly better as it does not have any implicit conversion.

But as the other answer says, 'char greeting[] = "Hello"' is much better than either.

The only reason to use the explicit array of characters is if you wanted to do something non-string-like with the character data, perhaps something like:

char greeting[12] = {'H', 'e', 'l', 'l', 'o', '\0', 'w', 'o', 'r', 'l', 'd', '\0'}

Of course, you wouldn't use standard C functions to deal with that.

其他答案的补充物。两者的区别是非常微妙的。' \ 0字符常数,是零(一个字节)。“0”是一个整数常数为零(通常是四个字节)。当你将一个整数常量分配给一个角色,这是隐式转换。所以在你的第二个例子,0是隐式转换为' \ 0之前分配的数组。

效果是相同的,所以它真的不重要,但你可能会说,' \ 0是略好,因为它没有任何隐式转换。

但随着其他回答说,“char[]=问候“你好”好过。

使用显式的字符数组的唯一原因是如果你想要做些non-string-like字符数据,也许类似:

char greeting[12] = {'H', 'e', 'l', 'l', 'o', '\0', 'w', 'o', 'r', 'l', 'd', '\0'}

答案 (Answer) 3

"Which one is more standard?"

There's noting "more" or "less" standard about either approach. Both 0 and '\0' stand for constant zero of type int in C, meaning that both are absolutely equivalent and can be used interchangeably.

"I expected compiler to detect the size of the string and add a terminating character"

The compiler has no such concept as "string" and knows noting about any "strings". "String" in C is a purely run-time concept - an array of characters terminated by a zero character. The only exception from this are string literals, which are treated differently by the compiler (e.g. a zero terminator is added implicitly). What you have in your examples are just abstract char arrays. They are not "strings" to the compiler. The compiler does not see these arrays as "strings" and does not add anything to them. It only does what you tell it to do. And you explicitly asked it to create a char array without any zeros at the end. This char array is not a string and cannot be used as a string. If you attempt to use it as a string, the behavior will be undefined and it will be entirely your fault.

“哪一个是更标准?”

有注意的“更多”或“少”的标准方法。这两个0'\0'类型的常数为零int在C语言中,这意味着两者都完全相同,可以互换使用。

“我希望编译器检测字符串的大小和添加一个终止字符”

编译器没有“字符串”等概念,指出了解任何“弦”。C是一个纯粹的“字符串”运行时概念——一个字符由一个零终止字符数组。从这个字符串,唯一的例外是区别对待由编译器(如添加一个零终结者隐式)。你在你的例子只是抽象的char数组。他们不是“字符串”编译器。编译器不会看到这些数组作为“弦”,不添加任何东西。它只做你告诉它做什么。和您明确要求创建一个char数组最后没有零。这char数组不是一个字符串,不能作为一个字符串。如果您试图使用它作为一个字符串,将未定义的行为,它将完全是你的错。

本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:http://stackoverflow.com/questions/23451177