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

C-为什么strcpy()是必需的,c,string,strcpy,C,String,Strcpy,有人能给我解释一下为什么strcpy()是为字符数组分配字符串所必需的,比如在下面的代码段中 int main(void) { char s[4]; s = "abc"; //Fails strcpy(s, "abc"); //Succeeds return 0; } s=“abc”失败的原因是什么?为什么strcpy()是在声明字符串后将字符串分配给字符数组的唯一方法?我觉得很奇怪,你必须用一个函数来完成一个基本的任务 这就是C语言中数组的含义。你不能给它们赋值。如果愿意,可以使用指针

有人能给我解释一下为什么strcpy()是为字符数组分配字符串所必需的,比如在下面的代码段中

int main(void) {

char s[4];

s = "abc"; //Fails
strcpy(s, "abc"); //Succeeds

return 0;
}

s=“abc”
失败的原因是什么?为什么strcpy()是在声明字符串后将字符串分配给字符数组的唯一方法?我觉得很奇怪,你必须用一个函数来完成一个基本的任务

这就是C语言中数组的含义。你不能给它们赋值。如果愿意,可以使用指针:

char *p;
p = "abc";
顺便说一句,有一个问题

数组在C中是“二等公民”;结果之一 偏见是你不能分配给他们


C中的数组是不可分配的,也不可复制初始化。这正是C语言中数组的用法。从历史上看,在值上下文中(在赋值的RHS上),数组会衰减为指针,这就是形式上阻止赋值和复制初始化的原因。这适用于所有数组,而不仅仅是
char
数组

C语言从它的前身B和BCPL语言继承了这种数组行为。在这些语言中,数组由物理指针表示。(很明显,当你将一个数组分配给另一个数组时,指针的重新分配不是你想要发生的事情。)在C语言中,数组不是指针,但是它们确实“模拟”了B和BCPL数组的历史行为,在大多数情况下,它们都会衰减为指针。这一历史遗产使C阵列至今仍不可复制

上面的一个例外是使用字符串文本进行初始化。也就是说,你能做到

char c[] = "abc";
在这种情况下,从概念上讲,我们将字符串literal
“abc”
复制到数组
c
。另一个例外是数组包装到结构类型中,在复制整个结构对象时复制该结构类型。就这样


这意味着,无论何时要复制裸(非包装)阵列,都必须使用库级内存复制功能,如
memcpy
<代码>strcpy只是专门为处理字符串而定制的样式。

简短回答:历史原因。C从来没有内置的字符串类型。直到C++出现STD::字符串出现,甚至没有到达第一个实现< /P> 详细回答:“abc”的类型不是
char[]
,而是
char*
strcpy
是一种可以复制指针指向的数据的机制(在本例中为ABC)


strcpy
不是初始化数组的唯一方法,但是,它足够智能,可以检测并尊重字符串末尾的终止0。您也可以使用
memcpy
将字符串复制到
s
中,但这需要您传入要复制的数据的长度,并且为了确保
s
中存在终止0(NULL),C语言缺少任何方便的语法来获取字符串文本的指针及其长度指示。包括许多帕斯卡方言在内的一些语言在每个字符串前面加上一个字节来报告其长度;这可以很好地用于许多目的,但将字符串文本限制为255个字符。C的方法允许容纳任意长度的字符串文本,但不管长度如何,只会增加一个字节的开销


零终止字符串在除字符串文字外的几乎所有用途上都不如其他形式,但文字是许多程序必须处理的最常见的字符串形式,因此让库函数有效地处理它们有相当大的优势;然后,在不理想的情况下使用以零结尾的字符串比为其他类型使用一组单独的库例程更容易。

是的,我确实使用指针,我只是不明白为什么s=“abc”在我的示例中不起作用。s是字符数组,“abc”也是字符数组。@C_p678-不,
s
是字符数组,“abc”是指向常量字符串的指针。@MByD:不完全正确<代码>“abc”不是指针
“abc”
类型为
char[4]
的数组,在此上下文中,该数组衰减为类型为
char*
的指针。注意,在C中,字符串不是常量。它是不可修改的,但是类型本身不包括
const
限定符。@安德烈:更挑剔的是,“const”和“constant”是两个截然不同的东西。“const”可能应该被称为“readonly”。常量或常量表达式可以在编译时求值;常量对象是在运行时无法修改的对象。考虑<代码> const int r= RAND();<代码>。
“abc”
的类型是
char[4]
strcpy
不是初始化,而是赋值。字符数组可以像所有其他数组一样初始化,请参见AndreyT的回答。为了澄清这一点,所有数组类型都可以用
{val0,val1,…}
形式的适当初始值设定项初始化;您可以为(char*dst=s,*src=“abc”;*dst++=*src++;)分配单个字符,例如
。不过,库函数是一个更好的选择,因为它更易于阅读,并且可能针对系统进行了优化。是的,要进一步了解@AnT所说的,
strcpy()
几乎与
memcpy()
完全相同,只是它包含空字节。