Keil uVision5中static数组赋值后值未改变问题咨询
问题根因
这个问题和Keil uVision5开发环境无关,是C语言static关键字的链接属性规则导致的:
在文件作用域(所有函数外部)使用static修饰的变量属于内部链接属性,只要某个.c文件包含了写有这个static定义的头文件,该.c文件就会独立生成一份仅本文件可见、和其他文件完全隔离的数组副本,不同c文件里的同名usRegInputBuf本质是完全无关的独立变量。
你的工程里modbusTCP.c必然也包含了modbusTCP.h,因此modbusTCP.c会生成一份属于自己的usRegInputBuf;main.c包含头文件后又生成了另一份独立的usRegInputBuf。你在main.c里赋值修改的是main.c自己持有的数组副本,而Modbus协议栈逻辑、或者你打印时读取的是其他c文件里的数组副本,自然读不到你写入的值,输出始终是初始的0。
修复方案
针对你用全局数组做Modbus寄存器缓冲区的场景,需要保证整个工程访问的是同一份数组,按以下方式修改即可:
- 修改modbusTCP.h头文件,去掉static定义,仅保留extern声明:
/* 头文件里只做声明,不要放变量定义 */ extern USHORT usRegInputBuf[REG_INPUT_NREGS]; - 在modbusTCP.c文件中添加数组的全局定义(不要加static修饰):
/* 对应c文件里放全工程唯一的数组定义 */ USHORT usRegInputBuf[REG_INPUT_NREGS];
修改后所有包含modbusTCP.h的c文件访问的都是同一份数组,main.c里的赋值操作会直接修改全局唯一的缓冲区,打印和协议栈读取都能拿到正确的赋值结果。
额外注意:你贴的示例代码里printf拼写错成了pritnf,如果实际代码里也是这个写法正常会触发编译报错,能输出0,0说明这段拼写错误是提问时的笔误,实际开发时注意排查即可。
内容的提问来源于stack exchange,提问作者변상규
相关产品推荐
相关产品推荐

