如何解决空指针数组参数传递
我试图传递一个 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,我不明白为什么要打印这些数字。
解决方法
从字里行间看,C 常见问题解答中的 Question 4.13: What's the 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,x };
struct item b = { INTARR,x };
struct item c = { INTARR,1,x };
struct item *d[] = { &a,&b,&c };
struct item e = { INTARRLIST,d };
print_item(&a);
print_item(&e);
return EXIT_SUCCESS;
}
,
我认为对于 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]);
}
}
,
实际上我需要能够接收任何类型的数组,因为我的目的不是打印它们而是将它们排入队列。
您的 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 '\0' 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;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。