【问题标题】:Explain difference between the use of void pointer解释使用void指针的区别
【发布时间】:2017-03-09 01:55:06
【问题描述】:

我的代码需要将一个数组传递给一个 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));

}

你好,世界!

数据值为:3

数据值为:7

数据值为:5


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

警告: source_file.c:在函数“main”中: source_file.c:17:10:警告:从不兼容的指针类型传递“测试”的参数 1 测试(&test_array,var_1); ^ source_file.c:3:6:注意:预期为“int ”,但参数的类型为“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));

}

【问题讨论】:

  • 删除 test() 调用中的 & 符号。
  • 注意:您不需要从void* 中转换一个指针。如果这样做,如果错误地使用了不同级别的间接,它可能会隐藏问题。
  • 我认为这对于我们这些使用不太聪明的编译器的人来说是一个有用的问题。几十年前,当我第一次学习 C 时,股票编译器(即使在当时也有点过时)实际上生成了警告,用于将类型化指针分配给 void * 变量而不进行强制转换。这让很多人失败了。我记得有一次非常沮丧,因为我有一个函数可以很好地获取指向数组的指针,但不能获取指向指针的指针。正是这个问题,它被掩盖了,因为编译器警告了错误的事情。使用 gcc 显示了我的问题,让我解决它。

标签: c pointers casting void


【解决方案1】:

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

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

test(&test_array, var_1);

传递指向第一个元素的指针,其类型为int*

test(test_array, var_1);   

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

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

【讨论】:

  • "指向数组的指针..." - 句子不明确。指针的类型为int(*)[3],而不是数组。
  • 那么描述指针类型int(*)3的最佳方式是什么?它是一个指向 int 的三个指针的数组吗?
  • @kcinicx int(*)3 类型不是有效类型。 int(*)[3] 类型是一个指向三个整数数组的指针
【解决方案2】:

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

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

如果数据类型已知,我总是更喜欢使用这种类型作为指针而不是 void 指针。我只会在指针可以指向任何东西的情况下使用 void 指针。最后,这是关于个人品味和您遵循的代码指南。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-12-05
    • 2010-12-16
    • 2016-05-23
    • 2016-08-05
    • 2020-12-18
    • 2016-09-07
    相关资源
    最近更新 更多