将字符串分配给字符数组 我想知道为什么第一个语句是有效的,为什么不是C++中的第二个? char a[10]="iqbal"; // it works a="iqbal"; // does not work

将字符串分配给字符数组 我想知道为什么第一个语句是有效的,为什么不是C++中的第二个? char a[10]="iqbal"; // it works a="iqbal"; // does not work,c++,C++,严格来说,数组不是指针!数组的数组基址不能是可修改的左值。它不能出现在赋值运算符的左边。数组只有在某些情况下才会衰减为指针。阅读此文了解数组何时衰减为指针。这里还有一个解释了数组和指针之间的区别 还可以阅读关于左值和右值的内容,这样你就可以了解一些不能出现在左值和右值上的东西= 字符a[10]=iqbal;//有效 在这种情况下,内部发生的是 a[0] = 'i'; a[1] = 'q'; . . a[5] = '\0'; 所以一切都很好,因为数组[i]是一个可修改的左值 a=iqbal

严格来说,数组不是指针!数组的数组基址不能是可修改的左值。它不能出现在赋值运算符的左边。数组只有在某些情况下才会衰减为指针。阅读此文了解数组何时衰减为指针。这里还有一个解释了数组和指针之间的区别

还可以阅读关于左值和右值的内容,这样你就可以了解一些不能出现在左值和右值上的东西=

字符a[10]=iqbal;//有效

在这种情况下,内部发生的是

a[0] = 'i';
a[1] = 'q'; 
 .
 .
a[5] = '\0';
所以一切都很好,因为数组[i]是一个可修改的左值

a=iqbal;//不起作用

在内部,这大致相当于

0x60000(Address of a, but is a simple number here ) = Address of "iqbal"

这是错误的,因为我们不能给数字赋值。

第一行不是语句,而是带有初始化的声明。 第二行是带有赋值运算符的表达式语句

不能在C中分配数组


但是您可以使用字符串文字的元素初始化数组。

字符数组a将是静态的,如果您这样初始化它,则无法更改。无论如何,您永远不能在c中指定字符串a=iqbal。您必须使用strncpy或memcpy。否则,您将尝试覆盖指向字符串的指针,而这不是您想要的

因此,正确的代码将执行以下操作:

char a[10];
strncpy(a, "iqbal", sizeof(a) - 1);
a[sizeof(a) - 1] = 0;
-1是为终止零保留一个字节。注意,您必须自己检查字符串是否以null结尾。糟糕的api。有一个strlcpy调用可以为您执行此操作,但它不包含在glibc中。

编写时 字符a[10]=iqbal 您正在用字符初始化字符数组a的元素。我们可以对int类型执行相同的操作注意,char类型得到的处理略有不同: int a[10]={1,2,…}

但是,在声明之后编写以下部分将是无效的,因为声明将被视为指针。所以写一些像 a={1,2,…}; 或a=iqbal 没有任何意义

c语言中为什么第一个语句有效,为什么第二个语句无效++

因为它们是不同的陈述,几乎完全无关。不要因为它们都使用=符号而感到困惑。在一种情况下,它表示对象初始化。在另一种情况下,赋值运算符

第一行是合法的,因为初始化聚合(包括字符数组)是合法的

第二行不合法,因为分配给数组是不合法的

因为这是C++,我可以建议你避免使用裸数组吗?对于字符串,请使用std::string。对于其他数组,使用std::vector。如果您这样做,您的示例将变成:

std::string a = "iqbal";  // it works
a="iqbal"; // so does this
尝试:


在C++11中,可以使用lambda进行初始化,如下所示:

bool test = true;
/*const*/ char a[10] = { //Aggregate initialization
                        [=] //capture by value
                           ()//no parameters
                             { //start lambda
    switch (test) {
        case true: return *"test=true"; //*"xxx" don't return a pointer, but the 'string' itself
        case false: return *"test=false"; 
    } //switch
}()};  //}, close the lambda, (), call it, }; close aggregate initialization
当您的环境不支持std::string时,如NVidia的CUDA或某些奇怪的嵌入式环境,这会很方便。 lambda被内联,因此在内部它被转换为char a[10]=test?xxx:yyy

如果您可以选择这样做,那么您显然希望始终使用std::string,因为固定大小的字符缓冲区从根本上说是个坏主意


如果使用std::string,可以使用:chararray=mystring.c_str;将其转换为字符数组;。如果坚持使用printf:printfs=%s,mystring.c_str;,这将非常有用bool test = true; /*const*/ char a[10] = { //Aggregate initialization [=] //capture by value ()//no parameters { //start lambda switch (test) { case true: return *"test=true"; //*"xxx" don't return a pointer, but the 'string' itself case false: return *"test=false"; } //switch }()}; //}, close the lambda, (), call it, }; close aggregate initialization