[英]Filling an integer array from global variables then returning it from a function in C
有许多全局变量,例如someglobalvalue1,someglobalvalue2等,它们是从我正在处理的应用程序的不同部分动态更新的。 在我目前正在研究的部分中,我需要将这些变量收集到一个整数数组中。 因为这些变量在不同的组中有很多,所以我有单独的函数(如GetGroupOne(),GetGroupTwo()等)将全局变量插入数组并将其返回给主函数。 我将此页面用作如何从函数返回int数组的指南: http : //www.tutorialspoint.com/cprogramming/c_return_arrays_from_function.htm
因此,例如:
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编译器)会收到以下错误消息:
尝试使用const初始化变量时出现错误“初始化元素不恒定”
因此, 在尝试使用const和其他线程初始化变量时 ,我确实发现了错误“初始化元素不是常量”,这似乎暗示着我尝试使用全局变量进行初始化的可能性。 所以我咬紧牙关,改为这样做:
int * GetGroupOne() {
static int array[GROUP_ONE_LENGTH];
array[0] = someglobalvalue1;
array[1] = someglobalvalue2;
array[2] = someglobalvalue3;
/* etc... */
return array;
}
现在,此方法有效,但它的外观令人难以置信,而且令人难以忍受。 特别是因为有多个组,其中一些有一百多个条目,所以我必须将每个全局变量分别插入到数组中。 我知道我将如何使用高级语言进行处理,但是C仍然对我来说还是个谜。 但是我认为必须有一些更好的方法来解决这个问题。 谁能向正确的方向推我?
谢谢。
除了需要花费数百个全局变量的设计之外,我不愿意忍受痛苦,至少有一种方法可以使用带有可变长度参数列表的函数来改善实现的外观。 看起来像这样(未经测试):
#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 ); }
但是请意识到,您所做的事情有些可怕。 至少,每当组更改长度时,您都必须更新长度,并确保对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; }
一种选择是使您的静态数组包含指向全局变量的指针(该指针确实算作编译时常量):
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]) )
您可以添加一些错误检查,以避免对范围错误的未定义行为,如果尝试在n
超出范围的情况下尝试G1(n)
,则可以访问虚拟变量或调用错误处理程序等。
如果您的编译器支持内联函数,那么它将比宏更整齐。
顺便说一句,您有什么理由不能只将全局变量放在数组中吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.