Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从全局变量填充整数数组,然后从C中的函数返回_C_Arrays - Fatal编程技术网

从全局变量填充整数数组,然后从C中的函数返回

从全局变量填充整数数组,然后从C中的函数返回,c,arrays,C,Arrays,有许多全局变量,比如someglobalvalue1、someglobalvalue2等,它们是从我正在使用的应用程序的不同部分动态更新的。在我目前正在处理的部分中,我需要将这些变量收集到一个整数数组中。因为在不同的组中有很多这样的变量,所以我有单独的函数,如GetGroupOne()、GetGroupTwo()等,将全局变量插入数组并返回给主函数。我将此页用作如何从函数返回int数组的指南: 例如: int main() { int *array; array = GetGroup

有许多全局变量,比如someglobalvalue1、someglobalvalue2等,它们是从我正在使用的应用程序的不同部分动态更新的。在我目前正在处理的部分中,我需要将这些变量收集到一个整数数组中。因为在不同的组中有很多这样的变量,所以我有单独的函数,如GetGroupOne()、GetGroupTwo()等,将全局变量插入数组并返回给主函数。我将此页用作如何从函数返回int数组的指南:

例如:

int main() {
   int *array;
   array = GetGroupOne();
   /* do stuff with array */
   return 0;
}

int * GetGroupOne() {
  static int array[GROUP_ONE_LENGTH] = { someglobalvalue1, someglobalvalue2, someglobalvalue3 };

  return array;
}
因此,试图编译它(顺便说一下,我仅限于C90编译器)会导致以下错误:

尝试使用常量初始化变量时出现错误“initializer元素不是常量”

所以,我确实发现了一些线程和其他线程,它们似乎暗示我试图做的事情,使用globals初始化,是不可能的。所以我咬了一口子弹,做了这个:

int * GetGroupOne() {
  static int array[GROUP_ONE_LENGTH];
  array[0] = someglobalvalue1;
  array[1] = someglobalvalue2;
  array[2] = someglobalvalue3;
  /* etc... */

  return array;
}
现在,这是可行的,但它是难以置信的丑陋,它伤害了我的灵魂看着它。特别是因为有多个组,其中一些组有超过100个条目,所以我必须将每个全局组分别插入数组中。我知道我将如何在更高级的语言中处理这个问题,但C对我来说仍然是一个谜。但我想一定有更好的方法来处理这个问题。有人能把我推向正确的方向吗


多谢各位

抛开我自己对一个需要数百个全局变量的设计的痛苦不谈,至少有一种方法可以改善实现的外观,使用一个具有可变长度参数列表的函数。它看起来像这样(未经测试):

#包括 整数*编译整数数组(整数*目的,无符号整数计数,…){ int*put=dest; va_列表arglist; va_开始(arglist,count); 对于(;计数!=0;--count){ *put++=va_arg(arglist,int); } va_end(arglist); 返回目的地; } ... int*GetGroupOne(){ 静态整数数组[组长度]; 返回编译数组(数组、组长度为1), someglobalvalue1, someglobalvalue2, someglobalvalue3 ); } 但是,要意识到你所做的事情有很多可怕的地方。至少,每当组更改长度时,您必须更新长度,并确保调用CompileIntegerArray时有正确数量的变量,否则可能会在代码中引入延迟堆栈炸弹

当然,这种方法会对性能产生一些(次要)影响,一些编译器可能会因为函数调用的数百个参数而阻塞

[编辑以添加备选方案]

您还可以做另一件事来稍微改善外观,同时使更改数组元素的顺序更容易。它稍微快一些,并且不依赖单独的函数来处理数组。这也将使您有机会进行一些错误检查。使用预处理器:

#define _el(x) array[ index++ ] = x; int * GetGroupOne() { static int array[GROUP_ONE_LENGTH]; int index = 0; _el( someglobalvalue1 ) _el( someglobalvalue2 ) _el( someglobalvalue3 ) if( index != GROUP_ONE_LENGTH ) { puts( "GAAK!" ); exit(1); } return array; } #定义_el(x)数组[index++]=x; int*GetGroupOne(){ 静态整数数组[组长度]; int指数=0; _el(someglobalvalue1) _el(someglobalvalue2) _el(someglobalvalue3) if(索引!=组长度){ 放置(“GAAK!”); 出口(1); } 返回数组; }
一个选项是使静态数组包含指向全局变量的指针(作为编译时常量计算):

然后通过宏访问全局

#define G1(n) ( *(get_group_one()[n])  )
您可以添加一些错误检查,以避免在范围错误上出现未定义的行为,如果尝试
G1(n)
n
超出范围,则可以访问虚拟变量,或者调用错误处理程序,等等

如果您的编译器支持内联函数,那么这将比宏更整洁


顺便说一句,有什么理由不能让全局变量首先在数组中?

为什么程序设计得如此糟糕,以至于有数百个全局变量?静态变量不是每次都初始化的。静态数组包含值。因此,坚持你的解决方案2或阅读David的解决方案是一个更好的主意。但是一个好的设计不需要全局变量。为什么不从一个数组开始呢?要扩展Paul的建议,您可以将全局变量定义为数组的一个成员::
int-array[3]#定义someglobalvar1数组[0]…
Ooga-我不能回答这个问题,我没有设计它。Paul-我不清楚当我没有在代码中声明全局数组并且无法控制全局数组时,如何生成全局数组。哦,我知道。不幸的是,我无法控制这个有数百个globals的部分。明天我会试试这个,谢谢!我还添加了一个静态标志,这样你每年只看一次这部戏run@MattMcNabb我猜实现会定期调用GetGroupOne,以获得全局状态的更新“视图”。如果可以选择大规模更改实现,我有点喜欢Daniel返回全局指针数组的解决方案。或者更好的方法是“struct GroupOne{int*value1;int*value2;}”,这样您就可以通过名称而不是索引来了解所查找的内容。这样就可以隐藏所有全局变量,只公开组。我使用了你的替代解决方案。它工作得很好,而且看起来更漂亮。非常感谢。一个问题:“el”是这里的缩写/首字母缩略词是什么?我只是好奇你为什么选择这个名字。@mrrow“el”暗指你每次调用宏时设置的数组元素。对不起,我不明白你的问题,为什么我不能将全局变量放在数组中。这就是我要做的,把它们放到一个数组中。你到底是什么意思,首先把它们放在一个数组中?声明全局变量的位置不是我的co
int **get_group_one(void)   // (void) instead of () is important
{
// note the `const`, your system will love you for it
// could also add a compile-time test that you actually do have GROUP_ONE_LENGTH entries
static int *const array[GROUP_ONE_LENGTH] = { &global0, &global1, &global2 };

    return array;
}
#define G1(n) ( *(get_group_one()[n])  )