C语言全局变量修改后未被函数识别的问题求助
SDL+raycastlib全局变量更新失效问题
我用SDL写C程序,搭配raycastlib库。在头文件里定义了全局变量levelFloor,在main()里修改这个变量后调用其他函数,结果这些函数还是在用变量的旧值。试过把新变量作为参数传给函数,但因为这个函数还会调用其他函数,问题又重复出现了,我不想给头文件里几乎所有函数都加这个参数。
如果这个问题实在解决不了,我可以从程序启动时就设置好这个变量(地图不会变化,这么做可行),但需要找到不用通过main()启动生成函数就能把数组传给变量的方法。
当前draw()函数代码
void draw() { RCL_RayConstraints c; c.maxHits = 32; c.maxSteps = 32; RCL_renderComplex(camera,floorHeightAt,ceilingHeightAt,textureAt,c); }
头文件代码
#define MAZE_WIDTH 25 #define MAZE_HEIGHT 25 int levelFloor[MAZE_WIDTH * MAZE_HEIGHT]; /* 就是这个变量出问题 */ static void shuffle(int *array, size_t n) { /* 内部逻辑代码 */ /* 无返回值,但会修改levelFloor */ }
main()相关代码片段
/* 其他前置代码 */ #define STARTX (MAZE_WIDTH - (MAZE_WIDTH % 4))/2 #define STARTY (MAZE_HEIGHT - (MAZE_HEIGHT % 4))/2 MAZE_Recurse(STARTX,STARTY,levelFloor); #undef STARTX #undef STARTY /* 这里已经确认变量被修改了 */
调用draw()的代码
draw(levelFloor) /* 我试过修改draw函数传levelFloor,这步本身有效,但不影响draw内部调用的其他函数 */
修改后的draw()函数
void draw(int levelFloor[]) /* 原本没传这个参数 */ { RCL_RayConstraints c; c.maxHits = 32; c.maxSteps = 32; RCL_renderComplex(camera,floorHeightAt,ceilingHeightAt,textureAt,c); }
代码抽象结构
main.c
#include "xar.h" #include "bar.h" void foo() { bar(); } int main() { xar(); foo(); }
bar.h
void bar() { stuff(); }
xar.h
int var[]; void xar() { var = 1; return; }
可行的解决思路
- 修复全局变量的重复定义问题:头文件里直接定义
levelFloor,会导致每个包含该头文件的源文件都生成一份独立的变量副本。你修改的是main.c里的副本,但其他函数用的是自己文件里的旧副本。解决方法是:- 在头文件里用
extern声明变量:extern int levelFloor[MAZE_WIDTH * MAZE_HEIGHT]; - 只在一个源文件(比如main.c)里定义变量:
int levelFloor[MAZE_WIDTH * MAZE_HEIGHT];
- 在头文件里用
- 在main()之前初始化地图:如果地图不会变化,可以用编译器扩展的构造函数特性,让生成函数在程序启动、main()执行前自动运行:
__attribute__((constructor)) void init_level() { const int STARTX = (MAZE_WIDTH - (MAZE_WIDTH % 4))/2; const int STARTY = (MAZE_HEIGHT - (MAZE_HEIGHT % 4))/2; MAZE_Recurse(STARTX, STARTY, levelFloor); } - 用结构体封装全局状态:把
levelFloor和其他相关的渲染状态打包到一个全局结构体里,后续函数只需要传递这个结构体的指针,不用逐个加参数,减少代码改动量。
内容的提问来源于stack exchange,提问作者Macintosh3D
相关产品推荐
相关产品推荐

