在上篇文章《》中,有读者对下列代码有疑问
typedef struct{
char *name; //姓名
int num; //学号
int age; //年龄
float score; //成绩
}stuff_s;
stuff_s xiaoming;
void xiaoming_inf_init()
{
xiaoming.name = "xiaoming";
xiaoming.num = 1;
xiaoming.age = 18.0;
xiaoming.score = 100;
}
留言到
很明显,这位读者意识到了name成员是个指针,在没有对指针分配内存时,就直接复制“xiaoming”字符串,这是错误的。先说下结论,这个是没有问题的,在下文我会详细说明下。
02解释首先,实践是检验真理的唯一标准,我们直接在编译器运行代码即可,这里我使用的是IAR编译,在VisualStudio中运行结果也是一样的,这里我使用IAR为例
xiaoming.name = (char *)malloc(10);
memcpy(xiaoming.name,"xiaoming",8);
xiaoming.num = 1;
xiaoming.age = 18.0;
xiaoming.score = 100;
free(xiaoming.name);
运行结果如下
可以看出,name指针是指向内存的,和刚开始的代码是有区别的。那么像刚开始的写法,如下
xiaoming.name = "xiaoming";
编译正常,运行正常,在使用中有什么限制吗?答案是有的
char test_char;
xiaoming.name = "xiaoming";
test_char = xiaoming.name[2];
这样写是正确的,test_char可以被正确的赋值字符a;但如下写法是错误的
xiaoming.name = "xiaoming";
xiaoming.name[2] = 'Q';
这样写可以编译通过,执行的时候也不报错,但是并不能达到修改第3个字符的目的。
本质上因为name指针指向的是Flash,可以通过上面的方法进行读取操作,但是不能按上面方法进行写入操作。
如果按下面的写法,读取和写入的操作的操作都是没有问题的,因为name指针指向的是内存,具有可读可写的属性。xiaoming.name = (char *)malloc(10);
memcpy(xiaoming.name,"xiaoming",8);
xiaoming.num = 1;
xiaoming.age = 18.0;
xiaoming.score = 100;
free(xiaoming.name);
所以日常代码编写中需要注意这些,我的观点是:按照上述方法,先对指针申请内存,然后再赋值。
上文既然提到了只读属性,那么我们就再说一下const关键字。大家先看如下代码操作
typedef struct{
const char *name; //姓名
int num; //学号
int age; //年龄
float score; //成绩
}stuff_s;
stuff_s xiaoming;
int main(void)
{
xiaoming.name = (char *)malloc(10);
memcpy(xiaoming.name,"xiaoming",8);
xiaoming.name[2] = 'Q';
xiaoming.num = 1;
xiaoming.age = 18.0;
xiaoming.score = 100;
free(xiaoming.name);
}
指针name前加了const关键字,这段代码在IAR编译器中是根本编译不通过的。


☛
必读
☛
☛ 必读