微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

空指针数组参数传递

如何解决空指针数组参数传递

我试图传递一个 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 知道它的参数应该指向什么数据类型。

我建议您同时研究 qsortcompar 的原型,以便更好地构建您所追求的设计。

虽然下面的示例可能与您尝试做的事情不直接对应,但它应该是头脑风暴的不错起点:

#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 举报,一经查实,本站将立刻删除。