我对以下内容感到有些惊讶。
范例1:
char s[100] = "abcd"; // declare and initialize - WORKS
范例2:
char s[100]; // declare
s = "hello"; // initalize - DOESN'T WORK ('lvalue required' error)
我想知道为什么第二种方法不起作用。应该看起来很自然(它可以与其他数据类型一起使用)?有人能解释一下这背后的逻辑吗?
Answers:
初始化数组时,C允许您使用值填充它。所以
char s[100] = "abcd";
基本上和
int s[3] = { 1, 2, 3 };
但是它不允许您执行赋值,因为它s
是一个数组而不是一个自由指针。的含义
s = "abcd"
是将的指针值分配给abcd
,s
但您不能更改,s
因为那样一来就不会指向数组。
如果s
是char*
-可以指向任何对象的指针,则可以并且确实可以工作。
如果要复制字符串,请简单使用strcpy
。
s[0] = 'x'; s[1] = 'y'; s[2] = 'z'; s[3] = 'm';
如果即使在初始化后也要一一替换字符串字符,则可以使用。
char s[100]; s = "abcd";
给人错误是非常合情合理的,因为s的有效作为常量指针处理。因此,如果我们尝试在第二行中分配“ abcd”,我们将尝试更改不允许的指针值。但是,如果const指针指向一个存储位置,则该存储位置的内容当然应该可以修改。假设s
指向存储位置1000,则s包含1000,而存储位置#1000包含a。我不能改变s到存储新的存储位置,例如2000,但我可以在存储器位置存储一个新的角色如ž1000
C中没有“字符串”之类的东西。在C中,字符串是的一维数组char
,以空字符终止\0
。由于无法在C中分配数组,因此也无法分配字符串。文字“你好”是语法糖const char x[] = {'h','e','l','l','o','\0'};
正确的方法是:
char s[100];
strncpy(s, "hello", 100);
或更好:
#define STRMAX 100
char s[STRMAX];
size_t len;
len = strncpy(s, "hello", STRMAX);
1 char s[100];
2 s = "hello";
在您提供的示例中,s实际上是在第1行而不是第2行初始化的。即使此时您没有显式地给它赋值,编译器还是这样做了。在第2行,您正在执行分配操作,并且不能像这样将一个字符数组分配给另一个字符数组。您必须使用strcpy()或某种循环来分配数组的每个元素。
char s[6]
不够吗
扩大Sparr的答案
初始化和赋值是两个截然不同的操作,碰巧在这里使用相同的运算符(“ =”)。
这样想:
想象有两个函数,分别称为InitializeObject
和AssignObject
。当编译器看到时thing = value
,它会检查上下文并InitializeObject
在创建新内容时调用上下文thing
。如果您不是,则调用AssignObject
。
通常,这很好InitializeObject
并且AssignObject
通常以相同的方式运行。除了在处理char数组(和其他一些边缘情况)时,它们的行为有所不同。为什么这样 好吧,这是另一篇有关堆栈与堆的文章,依此类推。
PS:顺便说一句,如果您尝试使用C ++,以这种方式进行思考也将帮助您了解复制构造函数和其他类似内容。
我知道已经回答了这个问题,但是我想与一个在C / C ++ Facebook小组中问过一个非常类似问题的人分享一个答案。
数组没有赋值运算符功能*。这意味着您不能简单地将char数组分配给字符串文字。为什么?因为数组本身没有任何赋值运算符。(*这是一个常量指针,无法更改。)
数组只是连续分配的内存区域,数组的名称实际上是指向数组第一个元素的指针。(引用自https://www.quora.com/Can-we-copy-an-array-using-an-assignment-operator)
要将字符串文字(例如"Hello world"
或"abcd"
)复制到char数组,您必须手动将字符串文字的所有char元素复制到数组中。
char s[100];
这将初始化一个长度为100的空数组。
现在将字符串文字复制到此数组上,使用 strcpy
strcpy(s, "abcd");
这将从字符串文字中复制内容"abcd"
并将其复制到s[100]
数组中。
这是一个很好的例子:
int i = 0; //start at 0
do {
s[i] = ("Hello World")[i]; //assign s[i] to the string literal index i
} while(s[i++]); //continue the loop until the last char is null
您显然应该使用strcpy
此自定义字符串文字复印机代替它,但这是一个很好的示例,说明了其strcpy
原理。
希望这可以帮助!
您可以使用此:
yylval.sval=strdup("VHDL + Volcal trance...");
其中yylval是char *。strdup从完成这项工作。