解释使用void指针的区别

Explain difference between the use of void pointer

我的代码需要将数组传递给 void 指针(该结构具有 (void *) 无法修改)。下面两个版本的代码产生相同的输出,但后者有两个警告。我的问题是这两种方法中哪一种是首选?有没有办法通过类型转换来删除警告?

此版本没有警告并按预期生成输出:

#include <stdio.h>

void test(void *var_arr, char var_1);

typedef struct {
    char chip;
    void *buffer;
}test_struct;

int main()
{
   int test_array[3] = {3,7,5};
    char var_1 = 0x20;

    printf("Hello, World!\n");

    test(&test_array, var_1);
    return 0;
}

void test(void *var_arr, char var_1)
{
    int i;

    test_struct var_ts;

    var_ts.chip = var_1;
    var_ts.buffer = var_arr;

    for (i=0; i<3; ++i)
        printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i));

}

Hello, World!

数据值为:3

数据值为:7

数据值为:5


下面的这个版本有两个警告,但编译并产生了预期的输出:

Warning(s): source_file.c: In function ‘main’: source_file.c:17:10: warning: passing argument 1 of ‘test’ from incompatible pointer type test(&test_array, var_1); ^ source_file.c:3:6: note: expected ‘int ’ but argument is of type ‘int ()[3]’ void test(int *var_arr, char var_1);

#include <stdio.h>

void test(int *var_arr, char var_1);

typedef struct {
    char chip;
    void *buffer;
}test_struct;

int main()
{
   int test_array[3] = {3,7,5};
    char var_1 = 0x20;

    printf("Hello, World!\n");

    test(&test_array, var_1);
    return 0;
}

void test(int *var_arr, char var_1)
{
    int i;

    test_struct var_ts;

    var_ts.chip = var_1;
    var_ts.buffer = (void *)var_arr;

    for (i=0; i<3; ++i)
        printf("\nThe data values are : %X \n\r", *((int *)var_ts.buffer+i));

}

低版本告诉你第一个问题是什么:传递一个指向数组的指针而不是第一个元素的指针。

传递指向数组的指针,其类型为 int(*)[3]:

test(&test_array, var_1);

传递指向类型为 int*:

的第一个元素的指针
test(test_array, var_1);   

代码恰好可以运行,因为两个指针指向同一个地址,所以指向数组的指针似乎可以运行,但代码仍然未定义。

将指针传递给第一个元素是正确的,因为数组 test_array 的类型 int[3] 在传递给函数时会衰减为类型 int*

显示警告是因为编译器对代码进行了静态分析并确定了错误的可能原因。

使用 void 指针时,编译器无法执行此静态分析,因为它不知道使用的是什么类型。

如果数据类型已知,我总是更喜欢使用此类型作为指针而不是 void 指针。只有当指针可以指向任何东西是可以接受的时候,我才会使用 void 指针。最后,这是关于个人品味和您遵循的代码指南。