我已经看到了两种终止字符串的方法。
// 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之后停止。为什么会有?那里?还知道如何在'?'之后停下来? ?是否有可能继续进行并拆分随机字符,直到它崩溃或奇迹般地在内存中找到一个随机的空终止字符?
答案 0 :(得分:4)
如果你把一个\ 0放在一个字符串中,告诉编译器这是一个特殊的东西。具体来说,它告诉编译器它是null。这些通常都藏在琴弦里面。
要回答你的问题,我不认为这两者更为标准。更为标准的方法是:
char greeting[] = "Hello";
或更一般地说:
const char *greeting = "Hello";
此代码:
char greeting[] = {'H', 'e', 'l', 'l', 'o'};
printf("Greeting message: %s\n", greeting );
打印出一个奇怪的字符,因为字符串没有明确终止。
答案 1 :(得分:2)
“哪一个更标准?”
这两种方法都有“更多”或“更少”的标准。 0
和'\0'
都代表C中int
类型的常量零,这意味着它们都是绝对等价的,可以互换使用。
“我希望编译器检测字符串的大小并添加终止字符”
编译器没有“string”这样的概念,并且知道任何“字符串”。 C中的“String”是一个纯粹的运行时概念 - 一个以零字符结尾的字符数组。唯一的例外是字符串文字,它们被编译器区别对待(例如,隐式添加零终结符)。您的示例中的内容只是抽象的char
数组。它们不是编译器的“字符串”。编译器不会将这些数组视为“字符串”,也不会向它们添加任何内容。它只做你告诉它做的事情。你明确要求它创建一个char
数组,最后没有任何零。此char
数组不是字符串,不能用作字符串。如果您尝试将其用作字符串,则行为将是未定义的,这完全是您的错。
答案 2 :(得分:0)
另一个答案的附录。两者之间的区别非常微妙。 ' \ 0'是一个零(一个字节)的字符常量。' 0'是一个整数常量,它是零(通常是四个字节。)当您为一个字符分配一个整数常量时,它将被隐式转换。所以在你的第二个例子中,0被隐式转换为' \ 0'在分配给阵列之前。
效果是一样的,所以它确实无关紧要,但你可以争辩说' \ 0'稍微好一些,因为它没有任何隐式转换。
但正如另一个答案所说,&char问候[] ="你好"'比两者都要好得多。
使用显式字符数组的唯一原因是,如果您想要使用字符数据执行非字符串式的操作,可能类似于:
char greeting[12] = {'H', 'e', 'l', 'l', 'o', '\0', 'w', 'o', 'r', 'l', 'd', '\0'}
当然,你不会使用标准的C函数来处理它。