请问c具有一个字符串类型? [关闭](Does C have a string type? [c

2019-07-19 07:05发布

我用C最近已经开始编程,从Java和Python的到来。 现在,在我的书,我已经注意到了,做一个“Hello World”程序,语法是这样的:

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

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

Answer 1:

C不和从未有过本地字符串类型。 按照惯例,语言使用的阵列char用一个空字符,即终止, '\0' 。 在该语言的标准库函数和宏提供用于空终止字符数组,例如,支持的strlen遍历的阵列char直到遇到'\0'字符和strcpy的从源串拷贝直到遇到'\0'

使用用C零结尾的字符串反映了下意图是只有一点点多层次的高比汇编语言。 零终止字符串已经直接支持在当时的PDP-10和PDP-11的汇编语言 。

值得一提的是,C字符串的这一特性导致了相当多的讨厌的缓冲区溢出漏洞,其中包括严重的安全漏洞。 例如,如果你忘了空-终止作为源参数传递给一个字符串strcpy ,该函数将继续从任何恰好是在内存过去的源字符串的结束,直到它恰好遇到一个复制连续字节0 ,可能改写任何有价值的信息如下内存中的目标字符串的位置。

在你的代码示例中,字符串文字“你好,世界!” 将汇编成的一个14字节长的阵列char 。 第一个13个字节将持有的字母,逗号,空格和感叹号和最后一个字节将持有空终止字符'\0' ,编译器为你自动添加。 如果你要访问数组的最后一个元素,你会发现它等于0 。 例如:

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

然而,在你的榜样, message仅是10个字节长。 strcpy会写所有14个字节,包括空终止,到存储器中,起始的地址message 。 的前10个字节将被写入栈上分配的内存message ,其余四个字节将被简单地写入到栈的末端。 写这四个额外字节到堆栈的后果是很难在这种情况下,预测(在这个简单的例子,它可能不会伤害的事情),但在现实世界中的代码,它通常会导致损坏的数据或内存访问冲突错误。



Answer 2:

有没有stringC 。 你必须使用字符数组。

顺便说你的代码将无法正常工作,因为数组的大小应该允许整个阵列,以适应外加一零个终止字符。



Answer 3:

在C中,一个字符串简单地是字符数组,以空字节结束。 因此,一个char*常常发音“弦”,当你阅读的C代码。



Answer 4:

要注意的是在你所提到的语言:

Java的:

String str = new String("Hello");

蟒蛇:

str = "Hello"

无论是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)

要么

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'

的字符数组是连续的字符,其中所述端部(通常是NULL终止子的独特标记字符的序列'\0' )。 请注意,标记字符是自动奇迹般地在上述情况下,附加给你的。



Answer 5:

C不支持一流的字符串类型。

C ++拥有的std :: string



Answer 6:

C没有像Java自身的字符串数据类型。

只有我们可以使用字符数组或字符指针例如声明在C字符串的数据类型:

 char message[10]; 
 or 
 char *message;

但是,你需要至少声明:

    char message[14]; 

复制“你好,世界!” 为消息变量。

  • 13:长度的“你好,世界!”
  • 1:“\ 0”空字符识别所述串的端


Answer 7:

首先,你不需要做这一切。 特别是, strcpy是多余的-你不需要复制字符串只是printf它。 您的message可与地方的字符串来定义。

其次,你不允许足够的空间为“你好,世界!” 字符串( message需要是至少14个字符,从而允许额外的一个空终止)。

关于为什么,但是,它的历史。 在汇编时,不存在字符串,仅字节,字等等帕斯卡有字符串,但也有与由于其静态类型的问题- string[20]是一个不同类型的string[40] 甚至有在创业初期即避免了这个问题的语言,但间接造成的,哪些更多的效率问题的当年动态分配开销。

Ç只需选择避免开销并保持非常低的水平。 字符串是字符数组。 数组是很密切的关系指向他们的第一项指针。 当数组类型“衰减”为指针类型,缓冲区大小的信息是从静态类型丢失,所以你没有得到老帕串的问题。

在C ++中,有个std::string类,它避免了大量的这些问题-并且具有动态分配的开销,但这些天我们通常不关心这个。 在任何情况下, std::string是一个库类-有C风格字符数组处理的下方。



文章来源: Does C have a string type? [closed]