C – 为什么strcpy()是必需的

有人可以向我解释为什么strcpy()是必须将字符串分配给字符数组,例如在下面的代码片段中。

int main(void) { char s[4]; s = "abc"; //Fails strcpy(s, "abc"); //Succeeds return 0; } 

s = "abc"失败的原因是什么? 为什么strcpy()是在声明字符串之后将字符串赋值给char数组的唯一方法? 我似乎很奇怪你必须使用一个函数来执行一个基本的赋值。

C中的数组是不可赋值和非可复制初始化的。 这就是数组如何在C中。历史上,在值上下文中(在赋值的RHS上)数组衰减到指针,这正式地阻止了赋值和复制初始化。 这适用于所有数组,不仅适用于char数组。

C语言从其前身–B和BCPL语言inheritance了这种数组行为。 在这些语言中,数组由物理指针表示。 (显然,当你将一个数组分配给另一个数组时,指针的重新分配并不是你想要发生的。)在C语言中,数组不是指针,但它们通过衰减“模拟”B和BCPL数​​组的历史行为。在大多数情况下指向。 这一历史遗产使Carrays至今无法复制。

上面的一个例外是使用字符串文字进行初始化。 即你可以做到

 char c[] = "abc"; 

但就是这样。

这意味着无论何时想要复制数组,都必须使用库级存储器复制function,如memcpystrcpy只是一种专门用于字符串的风格。

这就是C中的数组。您无法分配它们。 如果您愿意,可以使用指针:

 char *p; p = "abc"; 

顺便提一下,有一个C FAQ 。

数组是C中的“二等公民”; 这种偏见的一个结果就是你无法分配给他们

简答:历史原因。 C从未有过内置的字符串类型。 直到C ++出现std :: string才出现,甚至在第一次实现时也没有到来

答案很长:“abc”的类型不是char[] ,而是char *strcpy是一种机制,您可以使用该机制复制指针指向的数据(在本例中为ABC)。

strcpy不是初始化数组的唯一方法,但是,它足够聪明,可以检测并尊重字符串末尾的终止0。 您还可以使用memcpy将字符串复制到s但这需要传入要复制的数据长度,并确保在s存在终止0(NULL)

C语言缺少任何方便的语法来获取指向字符串文字的指针以及其长度的指示。 一些语言(包括许多Pascal方言)在每个字符串前面加上一个报告其长度的字节; 这很好地用于许多目的,但将字符串文字限制为255个字符。 C的方法允许容纳任何长度的字符串文字,但无论长度如何,只增加一个字节的开销。

除了字符串文字之外,零终止字符串几乎不是用于其他forms,但是文字是迄今为止许多程序必须处理的最常见的字符串forms,因此具有库函数具有相当大的优势有效地处理它们; 然后,在它们不理想的情况下使用零终止字符串变得更容易,而不是为其他类型设置一组单独的库例程。