为啥 C 中的文字字符串分配不可能用于指定长度的数组? [复制]

Posted

技术标签:

【中文标题】为啥 C 中的文字字符串分配不可能用于指定长度的数组? [复制]【英文标题】:Why is literal string assignment in C not possible for array with specified length? [duplicate]为什么 C 中的文字字符串分配不可能用于指定长度的数组? [复制] 【发布时间】:2011-12-23 19:50:56 【问题描述】:

可能重复:What is the difference between char s[] and char *s in C?Do these statements about pointers have the same effect?

一直以来,我都认为每当我需要复制字符串(文字或变量)时,我都需要使用strcpy()。但是我最近发现了这一点:

char a[]="test";

还有这个

char *a="test";

据我了解,第二种类型是不安全的,在某些情况下会打印垃圾。那是对的吗?更让我好奇的是为什么以下方法不起作用:

char a[5];
a="test";

或者这个

char a[];
a="test";

但是这有效

char *a;
a="test";

如果有人能把事情弄清楚一点,我会很高兴的。

【问题讨论】:

他们的关键是知道赋值和初始化之间的区别 【参考方案1】:

char a[]="test";

这声明并初始化了一个大小为 5 的数组,其内容为 "test"

char *a="test";

这声明并初始化了一个指向文字"test" 的指针。尝试通过 a 修改文字是未定义的行为(并且可能会导致您看到的垃圾)。它不是不安全的,它只是不能被修改,因为字面量是不可变的。

字符 a[5]; a="测试";

即使 a"test" 具有完全相同的类型,这也会失败,就像通过赋值复制数组的任何其他尝试一样。

字符 a[]; a="测试";

这声明了一个未知大小的数组。声明应在使用前完成。

字符 *a; a="测试";

这很好用,因为"test" 衰减为指向文字第一个元素的指针。尝试修改其内容仍然是未定义的行为。

【讨论】:

不错的答案!在你的最后一行,你的意思是“......从文字衰减到一个指针”? @Nicolás:我的意思是文字 "test" 的类型为 char[5],数组衰减为指向其第一个元素的指针。 现在一切都清楚了! :)【参考方案2】:

让我们逐个检查:

char a[]="test";

这告诉编译器在堆栈上分配 5 个字节,将 't' 'e' 's' 't''\0' 放在上面。然后变量a 指向写入't' 的位置,并且您有一个指向具有5 个可用空间的有效位置的指针。 (也就是说,如果您将a 视为指针。实际上,编译器仍将a 视为由5 个chars 组成的单个自定义类型。在极端情况下,您可以将其想象为@987654332 @)

char *a="test";

“测试”(就像我说的基本上是't''e''s''t''\0')存储在你的程序中的某个地方,比如“文字区域”,a 正在指向给它。该区域不是您可以修改的,只能用于阅读。 a 本身没有任何特定的内存(我不是在谈论指针值的 4/8 字节)。

char a[5];
a = "test";

您是在告诉编译器将一个字符串的内容复制到另一个字符串。这不是一个简单的操作。在char a[] = "test"; 的情况下,它相当简单,因为堆栈上只有5 个pushes。然而,在这种情况下,它是一个循环,需要 1 到 1 复制。

定义char a[];,我认为这根本不可能,是吗?您要求 a 是一个大小在初始化时确定的数组。没有初始化的时候,就没有意义了。

char *a;
a = "test";

您将a 定义为指向char 数组的指针。当你将它分配给"test" 时,a 只是指向它,但它没有任何特定的内存,就像char *a = "test"; 的情况一样

就像我说的那样,分配数组(无论是 char(字符串)的空终止数组还是任何其他数组)是编译器不会为您完成的一项重要任务,这就是您为它提供函数的原因。

【讨论】:

"那么变量a 指向't' 的写入位置" - 不,它没有。变量a 是一个数组,它的类型为char[5],它不指向任何地方。在大多数情况下,表达式a 衰减为指向该数组变量的第一个元素的指针。 @SteveJessop,好的,我要编辑得更精确。【参考方案3】:

不要混淆C中的assignmentinitialisation,它们是不同的。

在 C 中,字符串不是数据类型,它是一种约定,利用数组和 nul 终止符。像任何数组一样,当您分配它时,它的名称仅解析为一个指针。您可以分配一个指针,但这与分配一个字符串不同。

【讨论】:

以上是关于为啥 C 中的文字字符串分配不可能用于指定长度的数组? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

动态内存分配

C语言学习笔记--动态内存分配

为啥是 ”\?” C/C++ 中的转义序列?

为啥字符串长度应该加一它在 C 中的容量?

为啥这种语法专门用于初始化字符串文字而不能用于字符数组? [复制]

为啥允许将字符串文字分配给 C++ 中 char * 类型的指针 [重复]