C++中char数组赋值char报错:为何解引用数组可成功?
我定义了如下包含char数组成员的结构体:
typedef struct { // ... char myCharArr[200]; } myStruct;
我创建了该结构体的动态数组,尝试向myCharArr中存储单个字符时,出现错误:incompatible types in assignment of 'char' to 'char[200]',报错代码如下:
int num = 2; myStruct* data = new myStruct[num]; // ... data[i].myCharArr = 'a'; // 此处报错
但使用如下代码则可正常运行:
*data[i].myCharArr = 'a';
我重新拾起C++开发,希望有人能解释两种写法的差异。我知道可使用strcpy等函数向char数组写入字符串,但此处是单个字符,为何解引用数组就能成功赋值?另外,空终止符在此场景下有何影响?
两种写法的核心差异
在C/C++里,数组名是指向数组首元素的常量指针,但它不能被当作可修改的左值——数组创建后,它的内存起始地址是固定的,你没法直接给数组名赋值。
第一种写法
data[i].myCharArr = 'a':这里myCharArr代表整个数组,类型是char[200],你试图把单个char类型的'a'赋值给整个数组,类型完全不匹配,编译器必然报错。本质上这是在做“用字符给数组整体赋值”的非法操作。第二种写法
*data[i].myCharArr = 'a':此时myCharArr会自动转换成指向数组第一个元素的指针(类型为char*),解引用*就等价于访问myCharArr[0]——也就是数组的第一个char元素,这时赋值的是单个字符,类型匹配,所以能正常运行。你也可以直接写成data[i].myCharArr[0] = 'a',效果完全一致。
空终止符的影响
空终止符'\0'的作用是标记C风格字符串的结束位置,只有当你把myCharArr当作字符串使用时(比如用printf("%s", ...)、strlen()这类函数处理),它才是必需的。
如果只是存储单个字符,之后不会把这个数组当作字符串操作,有没有空终止符都不影响当前赋值的正确性。但如果后续要把它当作字符串用,就必须在字符后面手动加'\0',否则会出现未定义行为(比如读取到数组外的垃圾数据)。示例:
*data[i].myCharArr = 'a'; data[i].myCharArr[1] = '\0'; // 添加空终止符后,可安全作为字符串使用
内容的提问来源于stack exchange,提问作者Suhaib Ahmad

