简体   繁体   English

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

[英]Filling an integer array from global variables then returning it from a function in C

There are a number of global variables, let's say for example someglobalvalue1, someglobalvalue2, etc, that are updated dynamically from a different part of the app I'm working on. 有许多全局变量,例如someglobalvalue1,someglobalvalue2等,它们是从我正在处理的应用程序的不同部分动态更新的。 In the part that I am currently working on, I need to gather these variables into an integer array. 在我目前正在研究的部分中,我需要将这些变量收集到一个整数数组中。 Because there are a lot of these variables in different groups, I have separate functions like GetGroupOne(), GetGroupTwo(), etc to insert the globals into an array and return it to the main function. 因为这些变量在不同的组中有很多,所以我有单独的函数(如GetGroupOne(),GetGroupTwo()等)将全局变量插入数组并将其返回给主函数。 I'm using this page as a guide for how to return int arrays from functions: http://www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm 我将此页面用作如何从函数返回int数组的指南: http : //www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm

So for example: 因此,例如:

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

So, trying to compile this (by the way, I am limited to a C90 compiler) gets me this error: 因此,尝试编译此代码(顺便说一句,我仅限于C90编译器)会收到以下错误消息:

Error “initializer element is not constant” when trying to initialize variable with const 尝试使用const初始化变量时出现错误“初始化元素不恒定”

So, I did find Error "initializer element is not constant" when trying to initialize variable with const and other threads that seemed to suggest that what I was trying to do, initialize using globals, is not possible. 因此, 在尝试使用const和其他线程初始化变量时 ,我确实发现了错误“初始化元素不是常量”,这似乎暗示着我尝试使用全局变量进行初始化的可能性。 So I bit the bullet and did this instead: 所以我咬紧牙关,改为这样做:

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

  return array;
}

Now, this works but it is incredibly ugly and it hurts my soul to look at it. 现在,此方法有效,但它的外观令人难以置信,而且令人难以忍受。 Especially because there are multiple groups, some of which have over a hundred entries, so I have to insert each global into the array individually. 特别是因为有多个组,其中一些有一百多个条目,所以我必须将每个全局变量分别插入到数组中。 I know how I would handle this in higher level languages, but C is still somewhat of a mystery to me. 我知道我将如何使用高级语言进行处理,但是C仍然对我来说还是个谜。 But I'm thinking there MUST be some better way to handle this problem. 但是我认为必须有一些更好的方法来解决这个问题。 Can anyone nudge me in the right direction? 谁能向正确的方向推我?

Thank you. 谢谢。

Putting aside my own soul's pain over a design that calls for hundreds of global variables, there is at least one way to improve the look of your implementation, using a function with a variable-length argument list. 除了需要花费数百个全局变量的设计之外,我不愿意忍受痛苦,至少有一种方法可以使用带有可变长度参数列表的函数来改善实现的外观。 It would look something like this (untested): 看起来像这样(未经测试):

#include <stdarg.h>
  int * CompileIntegerArray( int *dest, unsigned int count, ... ) {
    int *put = dest;
    va_list arglist;
    va_start( arglist, count );
    for( ; count != 0; --count ) {
      *put++ = va_arg( arglist, int );
    }
    va_end( arglist );
    return dest;
  }

...

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

Realize that there are terrible things about what you are doing, though. 但是请意识到,您所做的事情有些可怕。 At a minimum, whenever a group changes length you have to update the length and ensure that the right number of variables are in the call to CompileIntegerArray, or risk introducing delayed stack bombs into your code. 至少,每当组更改长度时,您都必须更新长度,并确保对CompileIntegerArray的调用中包含正确数量的变量,否则可能会在代码中引入延迟的堆栈炸弹。

There are of course some (minor) performance implications to this approach, and some compilers might choke on hundreds of arguments to a function call. 这种方法当然会对性能产生一些(次要的)影响,并且某些编译器可能会阻塞函数调用的数百个参数。

[Edited to add an alternative] [编辑添加替代项]

There's another thing you can do that will improve the look a little bit and still make it easier to change the order of the array elements. 您可以做的另一件事是改善外观,并且仍然可以更轻松地更改数组元素的顺序。 It is somewhat faster, and does not rely on a separate function to process the array. 它速度更快,并且不依赖于单独的函数来处理阵列。 This will also give you the opportunity to do some error checking. 这也将使您有机会进行一些错误检查。 Use the preprocessor: 使用预处理器:

#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;
}

One option is to make your static array contain pointers to the global variables (which does count as a compile-time constant): 一种选择是使您的静态数组包含指向全局变量的指针(该指针确实算作编译时常量):

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

and then access your globals via a macro 然后通过宏访问您的全局变量

#define G1(n) ( *(get_group_one()[n])  )

You could add some error checking to avoid undefined behaviour on range errors, if you try G1(n) where n is out of range then you either access a dummy variable, or call an error handler, etc. 您可以添加一些错误检查,以避免对范围错误的未定义行为,如果尝试在n超出范围的情况下尝试G1(n) ,则可以访问虚拟变量或调用错误处理程序等。

If your compiler supports inline functions then that would be tidier than a macro. 如果您的编译器支持内联函数,那么它将比宏更整齐。

BTW is there any reason you can't just have your global variables be in an array in the first place? 顺便说一句,您有什么理由不能只将全局变量放在数组中吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM