void指针数组参数传递
void pointer array parameter passing
我正在尝试传递一个 int 数组作为接收 void * 数组的函数的参数
函数是:
void foo(void *A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", (u32)(long)A[i]);
}
}
然后我这样调用:
int A[5] = {11, 12, 13, 14, 11};
foo((void *)A, 5);
但打印的数组是:11 13 11 -2015754187 -274447056 我不明白为什么要打印这些数字。
我认为对于 foo 你想要一个整数数组而不是一个空指针数组。
改为尝试?
void foo(int A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", A[i]);
}
}
或者如果您无法更改 foo 的签名。
void foo(void *A[], unsigned int array_length)
{
int* p = (int*) A;
for (unsigned int i = 0; i < array_length; ++i) {
// printf("%d ", *p++);
printf("%d ", p[i]);
}
}
字里行间,C FAQ 中的 Question 4.13: What's the total generic pointer type? 似乎与切线相关:
There is no "total generic pointer type.".
声明 void *A[]
表示该函数需要一个空指针列表,而不是指向数据元素的通用指针。您似乎正在寻求实现的接口类型可以在标准 qsort
函数中找到。
void qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
注意base
指向要排序的数组的第一个元素。另请注意,第二个和第三个参数对于 qsort
在调用比较函数 compar
时能够访问数组的不同元素是必不可少的。我们假设 compar
知道它的参数应该指向什么数据类型。
我建议研究 qsort
和 compar
的原型,以便您可以更好地构建您想要的设计。
虽然下面的示例可能不直接对应您正在尝试做的事情,但它应该是集思广益的良好起点:
#include <stdio.h>
#include <stdlib.h>
enum item_type {
INTARR,
INTARRLIST,
DOUBLEARR,
DOUBLEARRLIST,
};
struct item;
struct item {
enum item_type type;
size_t nelem;
void *item;
};
void
print_int_arr(const int *x, size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
printf("%d\n", x[i]);
}
}
void
print_int_arr_list(const struct item *x[], size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
const struct item *y = x[i];
print_int_arr(y->item, y->nelem);
}
}
void
print_item(struct item *x)
{
switch(x->type)
{
case INTARR:
print_int_arr(x->item, x->nelem);
break;
case INTARRLIST:
print_int_arr_list(x->item, x->nelem);
break;
default:
fprintf(stderr, "Unknown item type '%d'\n", x->type);
exit(EXIT_FAILURE);
}
}
int
main(void)
{
int x[] = {1, 3, 5, 7, 9};
struct item a = { INTARR, 5, x };
struct item b = { INTARR, 3, x };
struct item c = { INTARR, 1, x };
struct item *d[] = { &a, &b, &c };
struct item e = { INTARRLIST, 3, d };
print_item(&a);
print_item(&e);
return EXIT_SUCCESS;
}
Actually i need to be able to receive an array of any type because my intention is not to print them but to enqueue them in a queue.
您的 foo
函数缺少的是确定应作为参数传递的数据类型,没有它我们无法从 void*
中正确提取值
以下是实现您所要求的方法之一。这里我传递的是数据类型和操作。
注意:这不是通用函数,它只是用来处理一些已知类型的。
您可以添加更多类型(指针和结构等)并进行实验。
我正在打印数据只是为了确保我们正在提取我们传递的内容,但您可以根据需要使用它们。
#include <stdio.h>
typedef enum { CHAR = 0, INT, FLOAT, STRING} DataType;
const char* getType(DataType t)
{
if(t == CHAR)
return "CHAR";
else if(t == INT)
return "INT";
else if(t == FLOAT)
return "FLOAT";
else
return "STRING";
}
void foo(void *A, unsigned int array_length, DataType type )
{
printf("type is %s and len = %d\n", getType(type), array_length);
switch(type)
{
case CHAR:
{
char *list = (char *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%c ", list[i]);
}
}
break;
case INT:
{
int *list = (int *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", list[i]);
}
}
break;
case FLOAT:
{
float *list = (float *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%.2f ", list[i]);
}
}
break;
case STRING:
{
char**list = (char**) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%s ", list[i]);
}
}
break;
default:
printf("Invalid type");
break;
}
putchar('\n');
}
int main()
{
int arr_int[] = {11, 12, 13, 14, 11};
//char arr_char[] = {"abcde"}; better way we have '[=10=]' at the end
char arr_char[] = {'a','b','c','d','e'};
float arr_float[] = {11.20, 12.25, 13.70, 14.80, 11.15};
char* arr_strings[] = {"abc","def","ghi","jkl","mno"};
foo(arr_int, sizeof(arr_int) / sizeof(arr_int[0]), INT);
foo(arr_char, sizeof(arr_char) / sizeof(arr_char[0]), CHAR);
foo(arr_float, sizeof(arr_float) / sizeof(arr_float[0]), FLOAT);
foo(arr_strings, sizeof(arr_strings) / sizeof(arr_strings[0]), STRING);
return 0;
}
我正在尝试传递一个 int 数组作为接收 void * 数组的函数的参数
函数是:
void foo(void *A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", (u32)(long)A[i]);
}
}
然后我这样调用:
int A[5] = {11, 12, 13, 14, 11};
foo((void *)A, 5);
但打印的数组是:11 13 11 -2015754187 -274447056 我不明白为什么要打印这些数字。
我认为对于 foo 你想要一个整数数组而不是一个空指针数组。
改为尝试?
void foo(int A[], unsigned int array_length)
{
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", A[i]);
}
}
或者如果您无法更改 foo 的签名。
void foo(void *A[], unsigned int array_length)
{
int* p = (int*) A;
for (unsigned int i = 0; i < array_length; ++i) {
// printf("%d ", *p++);
printf("%d ", p[i]);
}
}
字里行间,C FAQ 中的 Question 4.13: What's the total generic pointer type? 似乎与切线相关:
There is no "total generic pointer type.".
声明 void *A[]
表示该函数需要一个空指针列表,而不是指向数据元素的通用指针。您似乎正在寻求实现的接口类型可以在标准 qsort
函数中找到。
void qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *, const void *));
注意base
指向要排序的数组的第一个元素。另请注意,第二个和第三个参数对于 qsort
在调用比较函数 compar
时能够访问数组的不同元素是必不可少的。我们假设 compar
知道它的参数应该指向什么数据类型。
我建议研究 qsort
和 compar
的原型,以便您可以更好地构建您想要的设计。
虽然下面的示例可能不直接对应您正在尝试做的事情,但它应该是集思广益的良好起点:
#include <stdio.h>
#include <stdlib.h>
enum item_type {
INTARR,
INTARRLIST,
DOUBLEARR,
DOUBLEARRLIST,
};
struct item;
struct item {
enum item_type type;
size_t nelem;
void *item;
};
void
print_int_arr(const int *x, size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
printf("%d\n", x[i]);
}
}
void
print_int_arr_list(const struct item *x[], size_t nelem)
{
for (size_t i = 0; i < nelem; ++i)
{
const struct item *y = x[i];
print_int_arr(y->item, y->nelem);
}
}
void
print_item(struct item *x)
{
switch(x->type)
{
case INTARR:
print_int_arr(x->item, x->nelem);
break;
case INTARRLIST:
print_int_arr_list(x->item, x->nelem);
break;
default:
fprintf(stderr, "Unknown item type '%d'\n", x->type);
exit(EXIT_FAILURE);
}
}
int
main(void)
{
int x[] = {1, 3, 5, 7, 9};
struct item a = { INTARR, 5, x };
struct item b = { INTARR, 3, x };
struct item c = { INTARR, 1, x };
struct item *d[] = { &a, &b, &c };
struct item e = { INTARRLIST, 3, d };
print_item(&a);
print_item(&e);
return EXIT_SUCCESS;
}
Actually i need to be able to receive an array of any type because my intention is not to print them but to enqueue them in a queue.
您的 foo
函数缺少的是确定应作为参数传递的数据类型,没有它我们无法从 void*
以下是实现您所要求的方法之一。这里我传递的是数据类型和操作。
注意:这不是通用函数,它只是用来处理一些已知类型的。 您可以添加更多类型(指针和结构等)并进行实验。
我正在打印数据只是为了确保我们正在提取我们传递的内容,但您可以根据需要使用它们。
#include <stdio.h>
typedef enum { CHAR = 0, INT, FLOAT, STRING} DataType;
const char* getType(DataType t)
{
if(t == CHAR)
return "CHAR";
else if(t == INT)
return "INT";
else if(t == FLOAT)
return "FLOAT";
else
return "STRING";
}
void foo(void *A, unsigned int array_length, DataType type )
{
printf("type is %s and len = %d\n", getType(type), array_length);
switch(type)
{
case CHAR:
{
char *list = (char *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%c ", list[i]);
}
}
break;
case INT:
{
int *list = (int *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%d ", list[i]);
}
}
break;
case FLOAT:
{
float *list = (float *) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%.2f ", list[i]);
}
}
break;
case STRING:
{
char**list = (char**) A;
for (unsigned int i = 0; i < array_length; i++) {
printf("%s ", list[i]);
}
}
break;
default:
printf("Invalid type");
break;
}
putchar('\n');
}
int main()
{
int arr_int[] = {11, 12, 13, 14, 11};
//char arr_char[] = {"abcde"}; better way we have '[=10=]' at the end
char arr_char[] = {'a','b','c','d','e'};
float arr_float[] = {11.20, 12.25, 13.70, 14.80, 11.15};
char* arr_strings[] = {"abc","def","ghi","jkl","mno"};
foo(arr_int, sizeof(arr_int) / sizeof(arr_int[0]), INT);
foo(arr_char, sizeof(arr_char) / sizeof(arr_char[0]), CHAR);
foo(arr_float, sizeof(arr_float) / sizeof(arr_float[0]), FLOAT);
foo(arr_strings, sizeof(arr_strings) / sizeof(arr_strings[0]), STRING);
return 0;
}