我发现strcpy函数只是将一个字符串复制到另一个字符串。例如,如果一个程序包含以下语句:
char buffer[10];
----------
strcpy(buffer, "Dante");
字符串"Dante"将被放置在数组缓冲区[]中。该字符串将包括终止的null(\0),这意味着总共将复制六个字符。我只是想知道为什么我们不能更简单地说就能达到同样的效果:
buffer = "Dante";
如果我没有记错的话,C把字符串处理得比BASIC更像数组。
因为字符串不是C中的数据类型。"字符串"是char*
s,所以当您尝试分配它们时,您只是将内存地址而不是字符复制到缓冲区中。
考虑一下:
char* buffer;
buffer = malloc(20);
buffer = "Dante";
为什么它要神奇地把"但丁"放进缓冲区?
因为C中的"数组"是一块内存。没有可分配的指针。
如果你问为什么语法不是这样的:那么,如果长度不同会发生什么?
数组的地址不可更改。在其他意义上您可以考虑,
char buffer[20];
是编译时的等价物,
char* const buffer = (char*)malloc(20);
现在,由于buffer
地址无法更改,因此无法执行以下操作:
buffer = "Dante"; // error 'buffer' address is not modifiable
您不能执行buffer = "Dante"
,因为C中没有"字符串"数据类型,只有数组。
现在你可以做…
char buffer[10] = "Dante";
但是如果字符串的长度是未知的,你可以做…
char buffer[] = "Dante123456678";
但只在初始化期间,这意味着你不能做…
char buffer[];
buffer = "Dante";
在编写buffer
时,它被视为指向数组第一个元素的指针。当然,*buffer
或buffer[0]
是第一个元素。由于buffer
只是一个指针,您不能将像"Dante"
这样的一整堆数据分配给它。
-
如果
char buffer[128];
是声明,则buffer
引用数组的第一个位置,因此buffer="Dante"将尝试将字符串的地址分配到存储在数组中的地址上。数组中的内存地址位置是只读的,并且在编译时静态分配。因此,您不能执行buffer = "Dante"
,因为它试图更改指向编译时固定的其他位置的地址位置。无法写入这些位置。 -
如果
char *buffer;
是声明,那么buffer
是指向char
类型变量的指针,该变量可以指向内存块的主要块。因此,当执行buffer = "Dante"
时,将字符串的地址转换为buffer
。当将打印字符串时显示字符串,因为它指向一个字符串起始地址,该地址在可执行文件中编译并存储。但这不是一个首选的方法。 -
如果您执行
char arr[] = "Dante";
,字符串"Dante"将存储在.text
部分,您可以在其中写入,因此arr[0] = 'K'
类似于此,即修改是可能的。 -
如果执行
char *arr = "Dante";
,则字符串"Dante"将存储在.rodata
或类似的不可写位置。这是因为根据标准,字符串文字是不可修改的。