C语言 全局变量的变化不会在函数中检测到,或者如何使main()变量在其他函数中使用

8fsztsew  于 2023-03-22  发布在  其他
关注(0)|答案(1)|浏览(145)

我正在用C写一个SDL程序,我使用raycastlib。我在头文件中设置了一个全局变量。我在main()中更改了它,然后调用另一个函数。这个函数使用变量的旧值。
我已经尝试将新变量作为函数的参数,但该函数调用了另一个函数,它再次中断。我不想将此作为参数添加到标题中的所有函数(是的,该函数几乎使用了所有函数)。

void draw() 
{
  RCL_RayConstraints c;

  c.maxHits = 32;
  c.maxSteps = 32;

  RCL_renderComplex(camera,floorHeightAt,ceilingHeightAt,textureA
t,c); 
}

这就是它的函数。代码基于the example from raycastlib。它只是试图程序化地生成世界(代码中的levelFloor)。
如果这是不可能的,我将需要从一开始就设置变量(这是好的,Map不会改变),但我需要找到一种方法,从生成函数传递一个数组到一个变量,而不需要主函数来启动函数。
头文件:

#define MAZE_WIDTH 25
#define MAZE_HEIGHT 25

int levelFloor[MAZE_WIDTH * MAZE_HEIGHT]; /* THIS VARIABLE IS THE PROBLEM */

static void shuffle(int *array, size_t n)
{
/* stuff */
/* returns nothing (but changes levelFloor) */
}

主循环的一部分,使用这些:

/* stuff */
 
#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

/* checked if it is changed here. it is. */

以及

draw(levelFloor) /* I also tried changing the function and passing levelFloor as an argument which worked but didn't effect the other called function */

draw()函数:

void draw(int levelFloor[]) /* originally I didn't pass levelFloor as an argument */
{
  RCL_RayConstraints c;

  c.maxHits = 32;
  c.maxSteps = 32;
  RCL_renderComplex(camera,floorHeightAt,ceilingHeightAt,textureA
t,c); 
}

RCL_RenderComplex来自raycastlib。
代码的抽象是这样的:

/*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;
}

谢谢。
编辑:我想我会重写程序。

cvxl0en2

cvxl0en21#

主要的问题似乎是你在头文件中声明变量/数组。这是一个不好的做法,因为这意味着变量只对某个翻译单元可用。那就是:

  • 如果foo.h包含数组,foo.c包含foo.h,那么foo.h + foo.c形成一个转换单元,数组将只存在于那里。
  • 如果另一个文件bar. c包含foo. h,那么在转换单元foo. h + bar. c中将存在具有相同名称的不同数组。
  • 如果幸运的话,您会在此时得到链接器错误。

解决方法是在头文件foo. h中将数组声明为extern int array [n];,并且仅在文件foo. c中定义变量int array[n] = { ... };

  • 然而 * 在extern中使用“globals”也是一个糟糕的设计,因为它将一个变量暴露给多个文件。这被称为“紧耦合”或有时是“意大利面条编程”,其中糟糕的设计迫使程序中不相关的部分相互依赖。在一个文件中更改变量,然后噗的一声:一些不相关的文件也使用了这个变量,突然停止工作。这意味着你必须跟踪所有使用这个变量来解决这个错误。而且这些对于多线程来说通常是不安全的。

一个更好的解决方案是通过所谓的“setter/getter”函数在不相关的文件之间共享数据,这样就可以清楚地知道数据属于谁。

相关问题