关于结构体中指针的一些探讨
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再获年度编程语言,微软或成最大赢家相关文章
OPPOR9Plus在VR方面的表现如何?(探索OPPOR9Plus在虚拟现实技术应用上的优势与不足)
摘要:近年来,随着虚拟现实VR)技术的发展,越来越多的人开始关注并追求更好的VR体验。作为一款备受关注的手机品牌,OPPOR9Plus在VR方面的表现备受期待。本文将探索OPPOR9P...2025-11-04
vue和react都已经全面进入了hooks时代在vue中也称为组合式api,为了方便后面统一称为hooks),然而受到以前react中类组件和vue2写法的影响,很多开发者都不能及时转换过来,以致于2025-11-04
CSS 计数器是个好东西原理其实很简单,content虽然本身不支持 CSS 变量直接渲染,但是可以支持counter-reset。count::before {--percent: 50;coun2025-11-04
在日常的开发中,我们经常会需要将数组做扁平化处理,以方便我们的开发,那么如何实现数组扁平化呢?首先我们先了解一下数组扁平化的应用场景,数组扁平化一般在一些多维数组的应用中会出现,因为操作多维数组会较为2025-11-04佳能50D配18-55镜头的完美搭配(出色成像,多功能应用,超值选择)
摘要:佳能50D相机搭配18-55镜头是许多摄影爱好者的选择,这一组合能够提供出色的成像效果和多功能的应用。本文将从不同角度对这一组合进行评价和分析,帮助读者更好地了解这款产品。...2025-11-04
作者:仕禄1. 前文回顾在上一篇中,我们主要介绍了分布式系统中常见的复制模型,并描述了每一种模型的优缺点以及使用场景,同时阐述了分布式系统中特有的一些技术挑战。首先,常见的分布式系统复制模型有3种,分2025-11-04


最新评论