C有字符串类型吗? [英] Does C have a string type?

查看:206
本文介绍了C有字符串类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始在C编程,来自Java和Python。现在,在我的书中,我注意到要创建一个Hello World程序,语法如下:

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:

char message[10]
strcpy(message, "Hello, world!")
printf("%s\n", message);

现在,这个例子使用了一个char数组,我想知道 - 字符串发生了什么?为什么我不能简单地使用其中的一个?也许有不同的方法来做这个?

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?

推荐答案

C没有,从来没有一个本机字符串类型。按照惯例,语言使用以NULL char,即'\0'终止的数组 char 。语言标准库中的函数和宏提供对以null结尾的字符数组的支持,例如 strlen 遍历 char 的数组,直到遇到'\0'字符和 strcpy 从源字符串复制,直到遇到'\0'

C does not and never has had a native string type. By convention, the language uses arrays of char terminated 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., strlen iterates over an array of char until it encounters a '\0' character and strcpy copies from the source string until it encounters a '\0'.

在C中使用以null结尾的字符串反映了C意在比汇编语言更高级的事实。当时已在 PDP-10和PDP-11的汇编语言中直接支持零终止字符串

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字符串的这个属性导致了相当多的令人讨厌的缓冲区溢出错误,包括严重的安全漏洞。例如,如果您忘记将终止作为源参数传递给 strcpy 的字符串,该函数将继续复制连续字节结束,直到遇到 0 ,可能覆盖目标字符串在内存中的位置之后的任何有价值的信息。

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.

在您的代码示例中,字符串字面量Hello,world!将被编译成 char 的14字节长数组。前13个字节将包含字母,逗号,空格和感叹号,最后一个字节将保存空字符'\0'由编译器。如果你要访问数组的最后一个元素,你会发现它等于 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.:

const char foo[] = "Hello, world!";
assert(foo[12] == '!');
assert(foo[13] == '\0');

但是,在您的示例中, message 只有10个字节长。 strcpy 将从 message 的地址开始将所有14个字节(包括空终止符)写入内存。前10个字节将被写入到分配给堆栈的消息中,剩余的四个字节将被简单地写入堆栈的末尾。将这四个额外字节写入堆栈的结果在这种情况下很难预测(在这个简单的例子中,它可能不会伤害一个东西),但在现实世界的代码中,它通常导致损坏的数据或内存访问冲突错误。

However, in your example, message is only 10 bytes long. strcpy is 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 message and 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.

这篇关于C有字符串类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆