案例一:当我写的时候
char*str={"what","is","this"};
则 str[i]="newstring";
有效,而 str[i][j]='j';
无效。
案例二:当我写的时候
char str[][5]={"what","is","this"};
然后 str[i]="newstring";
无效,而 str[i][j]='J';
有效。
为什么会这样?我是一个初学者,在阅读其他答案后已经很困惑了。
最佳答案
首先:一个建议:请阅读 arrays are not pointers and vice-versa !!
也就是说,为了启发这个特定场景,
第一种情况,
char*str={"what","is","this"};
并没有按照您的想法行事。这是一种约束违规,需要根据第 6.7.9/P2 章从任何符合的 C 实现中进行诊断:
No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
如果启用警告,您(至少)会看到
warning: excess elements in scalar initializer
char*str={"what","is","this"};
但是,启用了严格一致性的(纽约)编译器应该拒绝编译代码。如果编译器选择编译并生成二进制文件,则行为不在 C 语言定义的范围内,这取决于编译器实现(因此可能有很大差异)。
在这种情况下,编译器决定此语句仅在功能上与
char*str= "what";
所以,这里的
str
是一个指向char
的指针,它指向一个 string literal。 可以重新赋值给指针,str="newstring"; //this is valid
但是,像这样的声明
str[i]="newstring";
将无效,因为这里尝试将指针类型转换并存储为
char
类型,其中类型不兼容。在这种情况下,编译器应该发出有关无效转换的警告。之后,像这样的声明
str[i][j]='J'; // compiler error
在语法上是无效的,因为您在不是“指向完整对象类型的指针”的对象上使用数组下标
[]
运算符,例如str[i][j] = ... ^^^------------------- cannot use this ^^^^^^ --------------------- str[i] is of type 'char', not a pointer to be used as the operand for [] operator.
另一方面,在第二种情况下,
str
是一个数组数组。您可以更改单个数组元素,str[i][j]='J'; // change individual element, good to go.
但是你不能给数组赋值。
str[i]="newstring"; // nopes, array type is not an lvalue!!
最后, considering you meant to write (as seen in comments)
char* str[ ] ={"what","is","this"};
在您的第一种情况下,数组的逻辑相同。这使得
str
成为一个指针数组。所以,数组成员是可赋值的,所以,str[i]="newstring"; // just overwrites the previous pointer
完全没问题。但是,存储为数组成员的指针是指向字符串文字 的指针,因此出于与上述相同的原因,您调用undefined behavior。 , 当你想修改内存中属于字符串字面量的元素之一时
str[i][j]='j'; //still invalid, as above.
关于c - char*str= {"foo",...} 和 char str[][5]= {"foo",...} 数组定义有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48315523/