dgv*_*vid 68
C没有,也从未有过本机字符串类型.按照惯例,该语言使用char
以null char结尾的数组,即with '\0'
.语言标准库中的函数和宏提供对以null结尾的字符数组的支持,例如,strlen遍历数组,char
直到遇到'\0'
字符并从源字符串中读取strcpy副本直到遇到a '\0'
.
在C中使用以null结尾的字符串反映了这样一个事实,即C只是比汇编语言更高级.当时已经用PDP-10和PDP-11的汇编语言直接支持零终止字符串.
值得注意的是,C字符串的这种属性会导致相当多的令人讨厌的缓冲区溢出错误,包括严重的安全漏洞.例如,如果您忘记将作为源参数传递的字符串作为空终止strcpy
,则该函数将继续从源字符串末尾的内存中复制顺序字节,直到它碰巧遇到0
可能被覆盖的字符串为止.任何有价值的信息都跟在目标字符串在内存中的位置.
在您的代码示例中,字符串文字"Hello,world!" 将编译成一个14字节长的数组char
.前13个字节将包含字母,逗号,空格和感叹号,最后一个字节将保存空终止符'\0'
,由编译器自动为您添加.如果你要访问数组的最后一个元素,你会发现它等于0
.例如:
const char foo[] = "Hello, world!";
assert(foo[12] == '!');
assert(foo[13] == '\0');
Run Code Online (Sandbox Code Playgroud)
但是,在您的示例中,message
只有10个字节长.strcpy
将所有14个字节(包括空终止符)写入从地址开始的内存中message
.前10个字节将写入堆栈中分配的内存中message
,剩余的4个字节将简单地写入堆栈的末尾.在这种情况下,将这四个额外字节写入堆栈的结果很难预测(在这个简单的示例中,它可能不会伤害事物),但在实际代码中,它通常会导致数据损坏或内存访问冲突错误.
用你提到的语言注意它:
Java的:
String str = new String("Hello");
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
str = "Hello"
Run Code Online (Sandbox Code Playgroud)
Java和Python都有"字符串"的概念,C没有"字符串"的概念.C具有可以"只读"或可操作的字符数组.
C:
char * str = "Hello"; // the string "Hello\0" is pointed to by the character pointer
// str. This "string" can not be modified (read only)
Run Code Online (Sandbox Code Playgroud)
要么
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'
Run Code Online (Sandbox Code Playgroud)
字符数组是一系列连续字符,末尾有唯一的标记字符(通常是NULL终止符'\0'
).请注意,在上述情况下,会自动为您添加标记字符.
归档时间: |
|
查看次数: |
106533 次 |
最近记录: |