C 中是否有替代数组范围初始化的方法?
Is there an alternative to Range Initialization of arrays in C?
我认为这是一个简单的问题:
有没有一种方法可以在不使用循环的情况下用非零值初始化数组?
我知道的一种方法是使用范围初始化用我想要的值初始化数组。
例如:
int main()
{
/* Using Designated Range Initialization*/
int my_array[10] = {[0 ... 3] = 5, [4 ... 7] = 15, [8 ... 9] = 30};
/* Using Explicit initialization for each element */
int other_array[10] = {5, 5, 5, 5, 15, 15, 15, 15, 30, 30};
return 0;
}
但是,此方法只是 GCC 编译器的扩展,而不是 ISO C 的一部分。因此,考虑到系统之间可能存在的不可移植性,有没有办法以类似的方式进行数组初始化?当然,不使用循环。
此外,我正在寻找的方法只是超出了数组每个元素的显式初始化。
唯一可移植的替代方法是明确列出它们。
int my_array[] = {
5, 5, 5, 5,
15, 15, 15, 15,
30, 30
};
如果数组很大,这当然会很麻烦。在这种情况下,您可以使用 bash
或 awk
中的简单脚本来创建声明。它可以将其写入您与 #include
.
合并的头文件
代码需要显式初始化非零数组元素。
如果有模式,可以使用宏魔法:
#define ONE(x) (x), (x)+1, (x)+2, (x)+3, (x)+4, (x)+5, (x)+6, (x)+7, (x)+8, (x)+9
#define TEN(x) ONE(x),ONE((x)+10),ONE((x)+20),ONE((x)+30),ONE((x)+40), \
ONE((x)+50),ONE((x)+60),ONE((x)+70),ONE((x)+80),ONE((x)+90)
int main() {
int count[100] = { TEN(1) };
printf("%d %d\n", count[0], count[99] );
}
输出
1 100
OP 示例
#define X2(x) (x), (x)
// Note the nested macro
#define X4(x) X2(x), X2(x)
#define X8(x) X4(x), X4(x)
#define X10(x) X8(x), X2(x)
#define X16(x) X8(x), X8(x)
// ....
int main()
{
int my_array[10] = { X4(5), X4(15), X2(30)};
printf("%d %d\n", my_array[0], my_array[9] );
return 0;
}
输出
5 30
来自 Barmar 回答下的评论...
@CraigEstey, haven't reached that level of programming knowledge yet, but that's what I'm trying to achieve. – onlyMinimum
我也猜到了——这就是为什么我建议用 C 编写程序的原因。
不用担心...元编程是一个fancy/sexy术语,implement/use.
真的很简单
为了让您入门或给您想法,这里有一个生成器示例程序(例如 gen.c
):
#include <stdio.h>
void
dorange(int lo,int hi,int val)
{
for (; lo <= hi; ++lo)
printf("%d, ",val);
}
int
main(void)
{
printf("int myarray[10] = {\n");
dorange(0,3,5);
dorange(4,7,15);
dorange(8,9,30);
printf("\n");
printf("};\n");
return 0;
}
这是该程序的输出:
int myarray[10] = {
5, 5, 5, 5, 15, 15, 15, 15, 30, 30,
};
因此,如果您要使用 Makefile 将输出放入 myarray.h
:
all: myprogram
# create the target program [after creating the generated file]
myprogram: myprogram.c myarray.h
cc -o myprogram myprogram.c
# create the generated file
myarray.h: gen
./gen > myarray.h
# create the generator program
gen: gen.c
cc -o gen gen.c
# clean up files ...
clean:
rm -f gen myarray.h myprogram
这里是myprogram.c
:
#include <stdio.h>
#include "myarray.h"
int
main(void)
{
for (int idx = 0; idx < sizeof(myarray) / sizeof(myarray[0]); ++idx)
printf(" %d",myarray[idx]);
printf("\n");
return 0;
}
这是myprogram
的输出:
5 5 5 5 15 15 15 15 30 30
我认为这是一个简单的问题: 有没有一种方法可以在不使用循环的情况下用非零值初始化数组?
我知道的一种方法是使用范围初始化用我想要的值初始化数组。 例如:
int main()
{
/* Using Designated Range Initialization*/
int my_array[10] = {[0 ... 3] = 5, [4 ... 7] = 15, [8 ... 9] = 30};
/* Using Explicit initialization for each element */
int other_array[10] = {5, 5, 5, 5, 15, 15, 15, 15, 30, 30};
return 0;
}
但是,此方法只是 GCC 编译器的扩展,而不是 ISO C 的一部分。因此,考虑到系统之间可能存在的不可移植性,有没有办法以类似的方式进行数组初始化?当然,不使用循环。
此外,我正在寻找的方法只是超出了数组每个元素的显式初始化。
唯一可移植的替代方法是明确列出它们。
int my_array[] = {
5, 5, 5, 5,
15, 15, 15, 15,
30, 30
};
如果数组很大,这当然会很麻烦。在这种情况下,您可以使用 bash
或 awk
中的简单脚本来创建声明。它可以将其写入您与 #include
.
代码需要显式初始化非零数组元素。
如果有模式,可以使用宏魔法:
#define ONE(x) (x), (x)+1, (x)+2, (x)+3, (x)+4, (x)+5, (x)+6, (x)+7, (x)+8, (x)+9
#define TEN(x) ONE(x),ONE((x)+10),ONE((x)+20),ONE((x)+30),ONE((x)+40), \
ONE((x)+50),ONE((x)+60),ONE((x)+70),ONE((x)+80),ONE((x)+90)
int main() {
int count[100] = { TEN(1) };
printf("%d %d\n", count[0], count[99] );
}
输出
1 100
OP 示例
#define X2(x) (x), (x)
// Note the nested macro
#define X4(x) X2(x), X2(x)
#define X8(x) X4(x), X4(x)
#define X10(x) X8(x), X2(x)
#define X16(x) X8(x), X8(x)
// ....
int main()
{
int my_array[10] = { X4(5), X4(15), X2(30)};
printf("%d %d\n", my_array[0], my_array[9] );
return 0;
}
输出
5 30
来自 Barmar 回答下的评论...
@CraigEstey, haven't reached that level of programming knowledge yet, but that's what I'm trying to achieve. – onlyMinimum
我也猜到了——这就是为什么我建议用 C 编写程序的原因。
不用担心...元编程是一个fancy/sexy术语,implement/use.
真的很简单为了让您入门或给您想法,这里有一个生成器示例程序(例如 gen.c
):
#include <stdio.h>
void
dorange(int lo,int hi,int val)
{
for (; lo <= hi; ++lo)
printf("%d, ",val);
}
int
main(void)
{
printf("int myarray[10] = {\n");
dorange(0,3,5);
dorange(4,7,15);
dorange(8,9,30);
printf("\n");
printf("};\n");
return 0;
}
这是该程序的输出:
int myarray[10] = {
5, 5, 5, 5, 15, 15, 15, 15, 30, 30,
};
因此,如果您要使用 Makefile 将输出放入 myarray.h
:
all: myprogram
# create the target program [after creating the generated file]
myprogram: myprogram.c myarray.h
cc -o myprogram myprogram.c
# create the generated file
myarray.h: gen
./gen > myarray.h
# create the generator program
gen: gen.c
cc -o gen gen.c
# clean up files ...
clean:
rm -f gen myarray.h myprogram
这里是myprogram.c
:
#include <stdio.h>
#include "myarray.h"
int
main(void)
{
for (int idx = 0; idx < sizeof(myarray) / sizeof(myarray[0]); ++idx)
printf(" %d",myarray[idx]);
printf("\n");
return 0;
}
这是myprogram
的输出:
5 5 5 5 15 15 15 15 30 30