C语言 C 有字符串类型吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14709323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does C have a string type?
提问by arielschon12
I have recently started programming in C, coming from Java and Python. Now, in my book I have noticed that to make a "Hello World" program, the syntax is something like this:
我最近开始用 C 编程,来自 Java 和 Python。现在,在我的书中,我注意到要制作一个“Hello World”程序,语法是这样的:
char message[10]
strcpy(message, "Hello, world!")
printf("%s\n", message);
Now, this example is using a char array and I wondered - what happened to strings? Why can't I simply use one of those? Maybe there is a different way to do this?
现在,这个例子使用了一个字符数组,我想知道 - 字符串发生了什么?为什么我不能简单地使用其中之一?也许有不同的方法来做到这一点?
回答by dgvid
C does not and never has had a native string type. By convention, the language uses arrays of charterminated with a null char, i.e., with '\0'. Functions and macros in the language's standard libraries provide support for the null-terminated character arrays, e.g., strleniterates over an array of charuntil it encounters a '\0'character and strcpycopies from the source string until it encounters a '\0'.
C 没有也从来没有原生字符串类型。按照惯例,该语言使用char以空字符结尾的数组,即以'\0'. 语言标准库中的函数和宏支持以空字符结尾的字符数组,例如,strlen遍历数组char直到遇到一个'\0'字符并且strcpy从源字符串复制直到遇到一个'\0'。
The use of null-terminated strings in C reflects the fact that C was intended to be only a little more high-level than assembly language. Zero-terminated strings were already directly supported at that time in assembly language for the PDP-10 and PDP-11.
在 C 中使用以空字符结尾的字符串反映了一个事实,即 C 只是比汇编语言更高级一点。当时,PDP-10 和 PDP-11 的汇编语言已经直接支持零终止字符串。
It is worth noting that this property of C strings leads to quite a few nasty buffer overrun bugs, including serious security flaws. For example, if you forget to null-terminate a character string passed as the source argument to strcpy, the function will keep copying sequential bytes from whatever happens to be in memory past the end of the source string until it happens to encounter a 0, potentially overwriting whatever valuable information follows the destination string's location in memory.
值得注意的是,C 字符串的这种特性会导致很多讨厌的缓冲区溢出错误,包括严重的安全漏洞。例如,如果您忘记将作为源参数传递给 的字符串以空字符结尾strcpy,则该函数将继续从源字符串末尾之后的内存中复制顺序字节,直到它碰巧遇到0,可能会覆盖目标字符串在内存中的位置之后的任何有价值的信息。
In your code example, the string literal "Hello, world!" will be compiled into a 14-byte long array of char. The first 13 bytes will hold the letters, comma, space, and exclamation mark and the final byte will hold the null-terminator character '\0', automatically added for you by the compiler. If you were to access the array's last element, you would find it equal to 0. E.g.:
在您的代码示例中,字符串文字“Hello, world!” 将被编译成一个 14 字节长的char. 前 13 个字节将保存字母、逗号、空格和感叹号,最后一个字节将保存空终止符'\0',由编译器自动添加。如果您要访问数组的最后一个元素,您会发现它等于0。例如:
const char foo[] = "Hello, world!";
assert(foo[12] == '!');
assert(foo[13] == 'String str = new String("Hello");
');
However, in your example, messageis only 10 bytes long. strcpyis going to write all 14 bytes, including the null-terminator, into memory starting at the address of message. The first 10 bytes will be written into the memory allocated on the stack for messageand the remaining four bytes will simply be written on to the end of the stack. The consequence of writing those four extra bytes onto the stack is hard to predict in this case (in this simple example, it might not hurt a thing), but in real-world code it usually leads to corrupted data or memory access violation errors.
但是,在您的示例中,message只有 10 个字节长。strcpy将把所有 14 个字节(包括空终止符)写入内存中,从 的地址开始message。前 10 个字节将写入分配在堆栈上的内存message,其余 4 个字节将直接写入堆栈的末尾。在这种情况下,很难预测将这四个额外字节写入堆栈的后果(在这个简单的示例中,它可能不会造成任何伤害),但在实际代码中,它通常会导致数据损坏或内存访问冲突错误。
回答by Ivaylo Strandjev
There is no stringtype in C. You have to use char arrays.
中没有string类型C。您必须使用字符数组。
By the way your code will not work ,because the size of the array should allow for the whole array to fit in plus one additional zero terminating character.
顺便说一下,您的代码将不起作用,因为数组的大小应该允许整个数组适合加上一个额外的零终止字符。
回答by Mike
To note it in the languages you mentioned:
用你提到的语言记录它:
Java:
爪哇:
str = "Hello"
Python:
Python:
char * str = "Hello"; // the string "Hellochar str[] = "Hello"; // the characters: 'H''e''l''l''o'' char message[10];
or
char *message;
' have been copied to the
// array str. You can change them via: str[x] = 't'
" is pointed to by the character pointer
// str. This "string" can not be modified (read only)
Both Java and Python have the concept of a "string", C does not have the concept of a "string". C has character arrays which can come in "read only" or manipulatable.
Java 和 Python 都有“字符串”的概念,C 没有“字符串”的概念。C 具有可以“只读”或可操作的字符数组。
C:
C:
char message[14];
or
或者
##代码##A character array is a sequence of contiguous characters with a unique sentinel character at the end (normally a NULL terminator '\0'). Note that the sentinel character is auto-magically appended for you in the cases above.
字符数组是一系列连续字符,末尾有一个唯一的标记字符(通常为 NULL 终止符'\0')。请注意,在上述情况下,哨兵字符会自动为您附加。
回答by Peter
In C, a string simply is an array of characters, ending with a null byte. So a char*is often pronounced "string", when you're reading C code.
在 C 中,字符串只是一个字符数组,以空字节结尾。因此char*,当您阅读 C 代码时,a通常发音为“字符串”。
回答by wich
C does not support a first class string type.
C 不支持第一类字符串类型。
C++ has std::string
C++ 有 std::string
回答by Babul Mirdha
C does not have its own String data type like Java.
C 没有像 Java 那样自己的 String 数据类型。
Only we can declare String datatype in C using character array or character pointer For example :
只有我们可以使用字符数组或字符指针在 C 中声明 String 数据类型 例如:
##代码##But you need to declare at least:
但你至少需要声明:
##代码##to copy "Hello, world!" into message variable.
复制“你好,世界!” 进入消息变量。
- 13 : length of the "Hello, world!"
- 1 : for '\0' null character that identifies end of the string
- 13:“Hello, world!”的长度
- 1 : 对于标识字符串结尾的 '\0' 空字符
回答by Steve314
First, you don't need to do all that. In particular, the strcpyis redundant - you don't need to copy a string just to printfit. Your messagecan be defined with that string in place.
首先,您不需要做所有这些。特别是,这strcpy是多余的 - 您不需要将字符串复制到printf它。您message可以使用该字符串进行定义。
Second, you've not allowed enough space for that "Hello, World!" string (messageneeds to be at least 14 characters, allowing the extra one for the null terminator).
其次,您没有为“Hello, World!”留出足够的空间。字符串(message需要至少 14 个字符,允许额外的一个作为空终止符)。
On the why, though, it's history. In assembler, there are no strings, only bytes, words etc. Pascal had strings, but there were problems with static typing because of that - string[20]was a different type that string[40]. There were languages even in the early days that avoided this issue, but that caused indirection and dynamic allocation overheads which were much more of an efficiency problem back then.
然而,关于为什么,这是历史。在汇编程序中,没有字符串,只有字节、单词等。Pascal 有字符串,但是由于静态类型存在问题 -string[20]是一种不同的类型,string[40]. 甚至在早期也有语言避免了这个问题,但这会导致间接和动态分配开销,这在当时是一个效率问题。
C simply chose to avoid the overheads and stay very low level. Strings are character arrays. Arrays are very closely related to pointers that point to their first item. When array types "decay" to pointer types, the buffer-size information is lost from the static type, so you don't get the old Pascal string issues.
C 只是选择避免开销并保持非常低的水平。字符串是字符数组。数组与指向其第一项的指针密切相关。当数组类型“衰减”为指针类型时,静态类型会丢失缓冲区大小信息,因此您不会遇到旧的 Pascal 字符串问题。
In C++, there's the std::stringclass which avoids a lot of these issues - and has the dynamic allocation overheads, but these days we usually don't care about that. And in any case, std::stringis a library class - there's C-style character-array handling underneath.
在 C++ 中,有一个std::string类可以避免很多这些问题 - 并且具有动态分配开销,但现在我们通常不关心这个。无论如何,它std::string是一个库类——下面有 C 风格的字符数组处理。

