C有字符串类型吗?

ari*_*n12 43 c string printf char strcpy

我最近开始用C编程,来自Java和Python.现在,在我的书中,我注意到要制作一个"Hello World"程序,语法是这样的:

char message[10]
strcpy(message, "Hello, world!")
printf("%s\n", message);
Run Code Online (Sandbox Code Playgroud)

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

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个字节将简单地写入堆栈的末尾.在这种情况下,将这四个额外字节写入堆栈的结果很难预测(在这个简单的示例中,它可能不会伤害事物),但在实际代码中,它通常会导致数据损坏或内存访问冲突错误.

  • 这是最有用的答案,谢谢:) (2认同)

izo*_*ica 15

没有string类型C.你必须使用char数组.

顺便说一下,你的代码不起作用,因为数组的大小应该允许整个数组加上一个额外的零终止字符.


Pet*_*ter 8

在C中,字符串只是一个字符数组,以空字节结尾.所以char*当你正在阅读C代码时,a 通常会发音为"string".


Mik*_*ike 8

用你提到的语言注意它:

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').请注意,在上述情况下,会自动为您添加标记字符.


wic*_*ich 7

C 不支持第一类字符串类型。

C++ 有 std::string