假设我有一组数组,字符串和常量:
const int a[]={0x01, 0x02};
const int b[]={2,0};
const int c=234;
const char* name="foo";
一起组成对象foo。
还有许多类似的对象,例如
const int a[]={0x04, 0x02, 0x03};
const int b[]={2,0,1};
const int c=1234;
const char* name="arfle";
在C中声明这些对象的最佳方法是什么? (特别是gcc,我对gcc-only扩展,c99等没问题。)
我希望像
这样的东西thing[0]={a={0x04, 0x02, 0x03}, b={2,0,1}, c=1234, name="arfle"};
thing[1]={a={0x01, 0x02}, b={2,0}, c=234, name="foo"};
printf("%s", thing.name);
但任何解决一般问题的巧妙方法都可以。 我可以在任何阵列上放置最大长度,但如果我不需要额外的功劳。 我对预处理器技巧没有任何问题,并且运行时初始化不会杀死我,尽管如果可能的话我宁愿避免它。
答案 0 :(得分:4)
使用结构:
struct object
{
int *a;
int *b;
int c;
const char *name;
}
int arfle_a[] = { 4, 3, 2 };
int arfle_b[] = { 2, 0, 1 };
int foo_a[] = { 1, 2 };
int foo_b[] = { 2, 0 };
struct object thing[] = {
{ arfle_a, arfle_b, 1234, "arfle" },
{ foo_a, foo_b, 234, "foo" },
};
printf("%s\n", thing[1].name);
请注意,此表示非常弱,表示具有大小的整数向量会更好(但更复杂),因为现在无法知道a
或{{1中有多少个数字在运行时。
更新:我修复了破损的代码,道歉。这就是我发布未经测试的代码所得到的。 :/
答案 1 :(得分:0)
您可以创建一个结构类型来保存不同的成员。
由于您的数组大小不同,请使用指针并动态分配数组对象。
struct bla {
const int *a;
const int *b;
int c;
const char *name;
};
如果您不想通过动态分配a
和b
数组来构造struct对象,还可以使用C99复合文字初始化struct bla
类型的对象并指定C99初始化。
struct bla a = {.a = (const int [3]) {4, 2, 3},
.b = (const int [2]) {2, 0},
.c = 42,
.name = "arfle"};
您还应该添加struct成员来存储数组对象的元素数。
答案 2 :(得分:0)
这是放松回答和ouah的评论的组合:
找到摆脱声明中重复数组的好方法可以完成这项工作。
struct object
{
int *a;
int sizeof_a;
int *b;
int sizeof_b;
int c;
const char *name;
};
struct object thing[] = {
{ (int[]){ 4, 3, 2 }, sizeof((int[]){ 4, 3, 2 }), (int[]){ 2, 0, 1 }, sizeof((int[]){ 2, 0, 1 }), 1234, "arfle" },
{ (int[]){ 1, 2 }, sizeof((int[]){ 1,2 }), (int[]){ 2, 0 }, sizeof((int[]){ 2, 0 }), 234, "foo" },
};
void test(void) {
int i;
printf("%s\n", thing[1].name);
for(i=0; i<thing[1].sizeof_a; i++)
printf("%d, ", thing[1].a[i] );
}
答案 3 :(得分:0)
另一个版本,结合了cnicutar,ouah和unwind的各种贡献。我不确定额外的冗长是好还是坏。
struct object
{
int *a;
int sizeof_a;
int *b;
int sizeof_b;
int c;
const char *name;
};
struct object thing[] = {
{ .a=(int[]){ 4, 3, 2 }, .sizeof_a=sizeof((int[]){ 4, 3, 2 }), .b=(int[]){ 2, 0, 1 }, .sizeof_b=sizeof((int[]){ 2, 0, 1 }), .c=1234, .name="arfle" },
{ .a=(int[]){ 1, 2 }, .sizeof_a=sizeof((int[]){ 1,2 }), .b=(int[]){ 2, 0 }, .sizeof_b=sizeof((int[]){ 2, 0 }), .c=234, .name="foo" },
};
void test(void) {
int i;
printf("%s\n", thing[1].name);
for(i=0; i<thing[1].sizeof_a; i++)
printf("%d, ", thing[1].a[i] );
printf("\n");
}
答案 4 :(得分:0)
到目前为止,这是所有答案的组合,带有测试循环。
我认为这就是我实际要使用的内容。谢谢大家的帮助!
#include<stdio.h>
typedef struct object_s
{
int *a;
size_t sizeof_a;
int *b;
size_t sizeof_b;
int c;
const char *name;
} object_t ;
#define DECLARE_OBJECT(a,b,c,d) { (a), (sizeof(a)/(sizeof(int))),(b), sizeof(b)/(sizeof(int)), (c),(d)}
object_t thing[] = {
DECLARE_OBJECT(((int[]){4,3,2}), ((int[]){ 2, 0, 1 }), 1234, "arfle"),
DECLARE_OBJECT(((int[]){1,2}) , ((int[]){ 2, 0 }) , 234, "foo")
};
int main(void) {
int i,j;
for(j=0; j<((sizeof(thing)/(sizeof(object_t)))); j++){
printf("%s\n", thing[j].name);
for(i=0; i<thing[j].sizeof_a; i++) printf("%d, ", thing[0].a[i] );
printf("\n");
for(i=0; i<thing[j].sizeof_b; i++) printf("%d, ", thing[0].b[i] );
printf("\n");
printf("%d\n",thing[j].c);
}
return 0;
}