为什么对于具有指定长度的数组,C中的字符串赋值是不可能的?

Pit*_*kos 5 c string initialization literals

可能重复:
C中的char s []和char*s有什么区别?
关于指针的这些陈述是否具有相同的效果?

这段时间我一直认为每当我需要复制一个字符串(文字或变量)时我都需要使用strcpy().但是我最近发现了这个:

char a[]="test";
Run Code Online (Sandbox Code Playgroud)

还有这个

char *a="test";
Run Code Online (Sandbox Code Playgroud)

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

char a[5];
a="test";
Run Code Online (Sandbox Code Playgroud)

或这个

char a[];
a="test";
Run Code Online (Sandbox Code Playgroud)

但这有效

char *a;
a="test";
Run Code Online (Sandbox Code Playgroud)

如果有人能稍微清理一下,我会很高兴.

K-b*_*llo 9

char a [] ="test";

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

char*a ="test";

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

char a [5]; 一个="测试";

这种失败即使当a"test"就像任何其他试图复制阵列thorugh分配具有完全相同的类型.

char a []; 一个="测试";

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

char*a; 一个="测试";

这可以正常工作,因为"test"衰减到指向文字的第一个元素的指针.尝试修改其内容仍然是未定义的行为.


Sha*_*baz 5

让我们逐案检查:

char a[]="test";
Run Code Online (Sandbox Code Playgroud)

这告诉编译器堆栈,就把分配5个字节't' 'e' 's' 't',并'\0'在其上。然后,该变量a指向't'写入位置,并且您有一个指向有效位置的指针,该位置具有5个可用空间。(也就是说,如果您将其a视为指针。实际上,编译器仍将其视为a包含5 chars 的单个自定义类型。在极端情况下,您可以将其想象为struct { char a, b, c, d, e; } a;

char *a="test";
Run Code Online (Sandbox Code Playgroud)

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

char a[5];
a = "test";
Run Code Online (Sandbox Code Playgroud)

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

定义char a[];,好吧,我认为这是不可能的,是吗?您要求a的数组是初始化时确定的大小。如果没有初始化,那就没有意义了。

char *a;
a = "test";
Run Code Online (Sandbox Code Playgroud)

您正在定义a为指向的数组的指针char。当您将其分配给时"test"a仅指向它,但是它没有任何特定的内存,就像char *a = "test";

就像我说过的那样,分配数组(char(字符串)或任何其他数组的以null终止的数组)是编译器不会为您完成的重要任务,这就是为什么要为其提供功能的原因。