关于组织体中指针的一些探讨
      发布时间:2022-01-13 13:32      作者:admin      点击:

01 首因

在上篇文章《STM32编程中枚举和组织体的结相符》中,有读者对下列代码有疑问

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为例

能够望到,运走异国题目的,name成员被平常赋值。这边仔细name指针指向的位置是0x8002A5C,这是在flash的地址周围,也就是编译器直接把“xiaoming”字符串放到了flash中,行为一个常量,然后把这个常量的指针赋给name指针,于是不必挑前给name指针申请内存空间。关于STM32的内存分配,能够望之前推文《C说话在STM32中的内存分配》。云云写也是相符法且切确的,自然吾们最熟识手段如下

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); 

于是平时代码编写中必要仔细这些,吾的不悦目点是:遵命上述手段,先对指针申请内存,然后再赋值。

自然,万事异国绝对,必要视情况而定,下列情况,你也能够直接将字符串赋给指针

确认指针不会有写入操作,只有读操作,且你认为多添一句memcpy语句影响你的代码运走速度了。

确认指针不会有写入操作,只有读操作,且编制异国有余的内存给指针申请了。

03 const关键字

上文既然挑到了只读属性,那么吾们就再说一下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编译器中是根本编译不经过的。

因为很浅易,就是由于指针name具有const属性,不及被写入。

于是,在上一节最有一片面说到,当你确认指针不会有写入操作,只有读操作,你能够在这个指针定义前添一个const属性,由于项现在辈码不是你一个维护的,你设计时认为这个指针只有读操作,就添const,云云别人进走写访问时直接就会在IAR报错,而不会将这个暗藏的隐患遗留在产品中。

自然,上文定义的const char *name;也是不规范的,当这个指针添了const,就答该在指针的名字中表现到,这个分别公司有分别的命名规范,每幼我也有每幼我的规范,这边不在演示了。

本文转载自微信公多号「清新编程」

【编辑选举】

Kubernetes容器平台架构解读 支付宝 App 集五福版发布:福相伴,五福,马上到! Windows 11 22526新版修复大量题目!新特性抢先望 WiFi7有多强?比WiFi6高三倍,速度快如飞 Python再获年度编程说话,微柔或成最大赢家

鸿蒙官方战略配相符共建——HarmonyOS技术社区

 
 

Powered by 轮理片在人线2021-老扒让儿媳欲仙欲死手机官网-四个男人搞 @2018 RSS地图 HTML地图

Copyright 站群系统 © 2013-2021 365建站器 版权所有