我如何声明和解压成对的 void 指针数组?
How can I declare and unpack an array of pairs of void pointers?
我想编写一个函数,它接受一个 void*
"pairs" 的数组——每个数组都是一对指向某物的指针。每对中的第一个元素将是一个字符串,第二个将是指向其他内容的指针。
我希望传入函数的数组声明如下:
<what type?> argument = {
{ "some string", <some pointer>},
{ "some other string", <some other pointer>},
// ... etc
NULL // To signal ending
}
function(argument);
在 function
内,我想遍历数组,访问每个 "pair",将 "pair" 的成员转换为它们各自的类型(我知道)并制作使用这些成员。
我遇到了一些麻烦。起初,我尝试将参数声明为 void* thing[][]
。认为它是 void
指针数组的数组。
但是,简单地尝试访问此类数组中的索引会给我错误:expression must be a pointer to a complete object type
。
阅读 SO 我意识到编译器认为我正在尝试取消引用 void*
。但我认为在这样的数组上执行 a[0]
会访问数组中的第一个 "pair",这应该取消引用 void**
- 这是合法的。我错了吗?
根据数组的类型、它的初始化以及在迭代期间解压缩数组的方式,正确的方法是什么?
你想要void *argument[][2] = { /* ... */ };
。您有一个未指定大小的数组,其元素是固定大小为 2 的数组,其元素是指向 void
的指针。你最初的编译器错误是因为当你有多个方括号时,只有第一组可以为空,所以添加 2
修复它。
顺便说一句,它可以作为指针衰减,在这种情况下它将是 void *(*argument)[2]
。
请注意,您的哨兵 NULL
并不完全符合您的预期,因为它位于数组的数组中,而数组并不完全是指针。请注意此警告:
warning: suggest braces around initialization of subobject [-Wmissing-braces]
NULL // To signal ending
^~~~
{ }
这是一个使用类型的示例程序:
#include <stdio.h>
void *g[][2] = {
{ "some string", (void*)0x1234},
{ "some other string", (void*)0x5678},
{ "some third string", (void*)0x9abc},
// ... etc
{NULL} // To signal ending
};
void print_things(void *argument[][2]) {
for(int i = 0; argument[i][0] /* using just argument[i] instead of argument[i][0] here would not work as intended */; ++i) {
printf("%s %p\n", (char*)argument[i][0], argument[i][1]);
}
}
int main(void) {
print_things(g);
return 0;
}
最后一点,我想说你的生活可能会更简单的自定义 struct
:
#include <stdio.h>
struct pair {
char *str;
void *ptr;
} g[] = {
{ "some string", (void*)0x1234},
{ "some other string", (void*)0x5678},
{ "some third string", (void*)0x9abc},
// ... etc
{NULL, NULL} // To signal ending
};
void print_things(struct pair argument[]) {
for(int i = 0; argument[i].str; ++i) {
printf("%s %p\n", argument[i].str, argument[i].ptr);
}
}
int main(void) {
print_things(g);
return 0;
}
我想编写一个函数,它接受一个 void*
"pairs" 的数组——每个数组都是一对指向某物的指针。每对中的第一个元素将是一个字符串,第二个将是指向其他内容的指针。
我希望传入函数的数组声明如下:
<what type?> argument = {
{ "some string", <some pointer>},
{ "some other string", <some other pointer>},
// ... etc
NULL // To signal ending
}
function(argument);
在 function
内,我想遍历数组,访问每个 "pair",将 "pair" 的成员转换为它们各自的类型(我知道)并制作使用这些成员。
我遇到了一些麻烦。起初,我尝试将参数声明为 void* thing[][]
。认为它是 void
指针数组的数组。
但是,简单地尝试访问此类数组中的索引会给我错误:expression must be a pointer to a complete object type
。
阅读 SO 我意识到编译器认为我正在尝试取消引用 void*
。但我认为在这样的数组上执行 a[0]
会访问数组中的第一个 "pair",这应该取消引用 void**
- 这是合法的。我错了吗?
根据数组的类型、它的初始化以及在迭代期间解压缩数组的方式,正确的方法是什么?
你想要void *argument[][2] = { /* ... */ };
。您有一个未指定大小的数组,其元素是固定大小为 2 的数组,其元素是指向 void
的指针。你最初的编译器错误是因为当你有多个方括号时,只有第一组可以为空,所以添加 2
修复它。
顺便说一句,它可以作为指针衰减,在这种情况下它将是 void *(*argument)[2]
。
请注意,您的哨兵 NULL
并不完全符合您的预期,因为它位于数组的数组中,而数组并不完全是指针。请注意此警告:
warning: suggest braces around initialization of subobject [-Wmissing-braces]
NULL // To signal ending
^~~~
{ }
这是一个使用类型的示例程序:
#include <stdio.h>
void *g[][2] = {
{ "some string", (void*)0x1234},
{ "some other string", (void*)0x5678},
{ "some third string", (void*)0x9abc},
// ... etc
{NULL} // To signal ending
};
void print_things(void *argument[][2]) {
for(int i = 0; argument[i][0] /* using just argument[i] instead of argument[i][0] here would not work as intended */; ++i) {
printf("%s %p\n", (char*)argument[i][0], argument[i][1]);
}
}
int main(void) {
print_things(g);
return 0;
}
最后一点,我想说你的生活可能会更简单的自定义 struct
:
#include <stdio.h>
struct pair {
char *str;
void *ptr;
} g[] = {
{ "some string", (void*)0x1234},
{ "some other string", (void*)0x5678},
{ "some third string", (void*)0x9abc},
// ... etc
{NULL, NULL} // To signal ending
};
void print_things(struct pair argument[]) {
for(int i = 0; argument[i].str; ++i) {
printf("%s %p\n", argument[i].str, argument[i].ptr);
}
}
int main(void) {
print_things(g);
return 0;
}