在C语言中使用异构数组
我希望使用具有多种类型的数组-字符串和数字int。以下是我到目前为止得到的:在C语言中使用异构数组,c,C,我希望使用具有多种类型的数组-字符串和数字int。以下是我到目前为止得到的: int main(int argc, char *argv[]) { int number = 2; void * array[] = {"helo", &number, "watkins"}; int array_len = sizeof(array)/sizeof(array[0]) for (int i=0; i<array_len; i++) {
int main(int argc, char *argv[]) {
int number = 2;
void * array[] = {"helo", &number, "watkins"};
int array_len = sizeof(array)/sizeof(array[0])
for (int i=0; i<array_len; i++) {
void *value = array[i];
// how to do this in C?
if (type(value) == char)
printf("The string is: %s", value);
else
printf("The number is: %d", value);
}
}
如何在C语言中测试类型或执行等效操作?在C语言级别上,此功能不存在。如果你想要这样的东西,你必须自己创造。因此,数组元素的类型必须可以包含任何一种类型的对象,例如结构或联合。此外,您的代码必须跟踪哪种类型是哪种类型-语言不会为您这样做 因此,一种方法如下所示:
#include <stdio.h>
#include <stdlib.h>
enum my_type { IS_STRING, IS_INTEGER };
struct my_multitype {
enum my_type t;
union {
char *s;
int n;
} u;
};
int main(int argc, char *argv[]) {
struct my_multitype array[] =
{
{ IS_STRING, { .s = "helo" } },
{ IS_INTEGER, { .n = 2 } },
{ IS_STRING, { .s = "watkins" } }
};
int array_len = sizeof(array)/sizeof(array[0]);
for (int i=0; i<array_len; i++) {
switch (array[i].t) {
case IS_STRING:
printf("The string is: %s\n", array[i].u.s);
break;
case IS_INTEGER:
printf("The number is: %d\n", array[i].u.n);
break;
default:
printf("Something is horribly wrong\n");
abort();
break;
}
}
}
注意,在每种情况下,我们都使用初始化正确的联合成员
您也可以尝试使用void*,但是您必须将类型信息保存在单独的数组或其他东西中,这很尴尬。初始化这样的数组也很尴尬,正如你在整数中看到的那样,你必须引入一个辅助变量。我喜欢内特的答案,所以不要改变你的选择,但它有一个微妙的变化,即使用匿名联合,这将允许您直接引用联合的成员,而无需使用联合标记引用成员 这是在年的C11标准中引入的。它只是提供了一些语法上的简写。例如,在结构中使用匿名联合,例如
typedef struct { /* struct containing tag and union between int/char[] */
int tag;
union { /* anonymous union allow you to refer */
char str[MAXC]; /* to members as members of the struct */
int number;
};
} mytype;
...
mytype array[] = {{ISSTR, {"helo"}}, {ISINT, {{2}}}, {ISSTR, {"watkins"}}};
您与工会成员的联系方式如下:
printf ("The string is: %s\n", array[i].str);
#include <stdio.h>
#define MAXC 16 /* if you need a constant, #define one (or more) */
enum { ISSTR, ISINT }; /* enum can provide global constants as well */
typedef struct { /* struct containing tag and union between int/char[] */
int tag;
union { /* anonymous union allow you to refer */
char str[MAXC]; /* to members as members of the struct */
int number;
};
} mytype;
int main (void) {
mytype array[] = {{ISSTR, {"helo"}}, {ISINT, {{2}}}, {ISSTR, {"watkins"}}};
int array_len = sizeof array/sizeof *array;
for (int i=0; i<array_len; i++) {
// how to do this in C?
if (array[i].tag == ISSTR) /* if tag ISSTR element is string */
printf ("The string is: %s\n", array[i].str);
else if (array[i].tag == ISINT) /* if ISINT, element holds an int */
printf ("The number is: %d\n", array[i].number);
else
fputs ("As Nate put it, things are horribly wrong...\n", stderr);
}
}
或
数组[i]和str或number之间没有联合标记
总之,你的例子是:
printf ("The string is: %s\n", array[i].str);
#include <stdio.h>
#define MAXC 16 /* if you need a constant, #define one (or more) */
enum { ISSTR, ISINT }; /* enum can provide global constants as well */
typedef struct { /* struct containing tag and union between int/char[] */
int tag;
union { /* anonymous union allow you to refer */
char str[MAXC]; /* to members as members of the struct */
int number;
};
} mytype;
int main (void) {
mytype array[] = {{ISSTR, {"helo"}}, {ISINT, {{2}}}, {ISSTR, {"watkins"}}};
int array_len = sizeof array/sizeof *array;
for (int i=0; i<array_len; i++) {
// how to do this in C?
if (array[i].tag == ISSTR) /* if tag ISSTR element is string */
printf ("The string is: %s\n", array[i].str);
else if (array[i].tag == ISINT) /* if ISINT, element holds an int */
printf ("The number is: %d\n", array[i].number);
else
fputs ("As Nate put it, things are horribly wrong...\n", stderr);
}
}
请记住,这是C11引入的,在C99中,您将找不到匿名结构或匿名联合,尽管某些编译器提供了作为扩展的您可以创建一个联合数组。我想您想创建一个类似于Python或JavaScript的数组吗?@AbdulRehman是的,类似于此。您可以创建一个结构变量数组{字符类型;void*数据;}当你阅读它的时候,你会检查每个元素的类型,以知道如何处理它各自的数据。用一种更简单的方式来做是不可能的,因为C的设计不支持这一点,所以C的语法也不支持。在C中,数组是由单一类型的对象组成的。现在数组可以是一个结构数组。但是,你不能这样做e一个void*类型的数组,因为该类型没有提供关于您所声明内容的完整信息。是的,这正是我应该如何处理它的,但是您在标记的枚举中做得更好,我只使用了一个int标记;作为一个标志。如果没有指定的初始值设定项,您可以执行{{1,{hello},{0,{2}},…..此外,您还可以删除命名联合体的“u”,只需引用,例如数组[i].s和数组[i].n。