最近我开始学习C语言编程,之前我学过Java和Python。现在,在我的书里我注意到如果要编写一个“Hello World”程序,语法应该是这样的:
char message[10]
strcpy(message, "Hello, world!")
printf("%s\n", message);
现在,这个例子使用了char数组,我想知道-字符串呢?为什么我不能简单地使用其中之一?也许有另一种方法来做到这一点?
'\0'
)结尾的char
数组。语言标准库中的函数和宏提供对以空字符结尾的字符数组的支持,例如strlen遍历char
数组直到遇到'\0'
字符,strcpy复制源字符串直到遇到'\0'
字符。strcpy
函数将继续从源字符串末尾所在内存的连续字节中复制,直到它恰好遇到一个 0
字符,这可能会覆盖内存中目标字符串位置后面的任何有价值的信息。char
数组。前 13 个字节将包含字母、逗号、空格和感叹号,最后一个字节将包含由编译器自动添加的以空字符结尾的字符 '\0'
。如果你要访问数组的最后一个元素,你会发现它等于 0
。例如:const char foo[] = "Hello, world!";
assert(foo[12] == '!');
assert(foo[13] == '\0');
message
只有 10 个字节长。 strcpy
将写入所有 14 个字节(包括空终止符)到从 message
的地址开始的内存中。前 10 个字节将被写入为 message
分配的堆栈内存中,剩余的四个字节将简单地写入堆栈的末尾。在这种情况下,写入这四个额外的字节到堆栈上的后果很难预测(在这个简单的例子中,可能不会有任何问题),但在实际代码中,它通常会导致数据损坏或内存访问违规错误。char
数组如果没有'\0'
字节,它就不是一个字符串。 - 12431234123412341234123To note it in the languages you mentioned:
Java:
String str = new String("Hello");
Python:
str = "Hello"
char * str = "Hello"; // the string "Hello\0" is pointed to by the character pointer
// str. This "string" can not be modified (read only)
或者
char str[] = "Hello"; // the characters: 'H''e''l''l''o''\0' have been copied to the
// array str. You can change them via: str[x] = 't'
'\0'
)。请注意,在上述情况下,哨兵字符会自动附加在末尾。在C语言中,没有string
类型。必须使用char数组来代替。
另外,你的代码将无法正常工作,因为数组的大小应该足够容纳整个数组,再加上一个零终止字符。
C语言中,字符串只是一个以空字符结尾的字符数组。因此,当你阅读C代码时,char*
通常被发音为"字符串"。
C语言不支持一流字符串类型。
C++有std::string。
C语言没有像Java那样拥有自己的字符串数据类型。
在C语言中,我们只能使用字符数组或者字符指针声明字符串数据类型。例如:
char message[10];
or
char *message;
char message[14];
将“Hello, world!”复制到消息变量中。
strcpy
是多余的 - 你不需要复制一个字符串只为了 printf
它。你可以用那个字符串来定义你的 message
。message
至少需要14个字符,允许额外的一个空字符)。string[20]
是不同于 string[40]
的类型。即使在早期也有一些避免这个问题的语言,但这会导致更多的间接和动态分配开销,而那时效率问题更加突出。std::string
的类,它避免了许多这些问题 - 并且具有动态分配开销,但现在我们通常不关心这个。无论如何,std::string
是一个库类 - 其下面有C风格的字符数组处理。
strncmp
这个函数有两个问题,首先它是一个比较(cmp
)函数而不是一个复制(cpy
)函数;其次,你应该使用strlcpy
,它可以确保使用空终止符。strncpy
可能会给你一个没有以空字符结尾的字符串。 - wich