C Void数组遍历

C Void Array Traversal

我对使用 void 指针时的编码风格有疑问。

此代码修改自代码极客

#include<stdio.h>
int main()
{
    int a[2] = {1, 2};
    void *ptr = &a;
    for(int i=0; i<2; i++) {
        printf("%d\n", *(int *)ptr+i);
    }
    return 0;
}

我在我的项目中使用通用循环缓冲区。该缓冲区有一个空指针,指向在初始化期间传入的静态缓冲区。我想遍历并打印循环缓冲区中的数据。在找到上面的代码之前,我不确定如何打印内容。

我有两个问题:

  1. 这是遍历我的数据的合适且广为接受的方式吗? PC-Lint 等工具是否会发出警告?
  2. 是否有更好的方法来遍历这些数据?

编辑: 感谢 Lev M。 我已经更新了我的代码以使用数据类型的大小正确地遍历数据。循环缓冲区是通用的,意味着我们传入缓冲区和数据类型大小。

更新后的测试代码如下

#include<stdio.h>
int main()
{
    int a[2] = {2, 1};
    void *ptr = &a;
    for(int i=0; i<2; i++) {
        printf("%d\n", *(int *)ptr);
        ptr = ptr + sizeof(int);
    }

    return 0;
}

我不确定你想用这个数组做什么,但基本上你不能 'use' void* 除非你将它转换成它的真实类型。 要做到这一点,你上面写的就很好 ((int*)ptr) 一旦你这样做了,你就可以用它来用这个 'int' 指针做任何你想要的合法操作。

您的代码中存在一个重大错误:

printf("%d\n", *(int *)ptr+i);

运算符优先级意味着此语句将首先执行 *(int*)ptr,而不是将 2 添加到数组第一个单元格中的值。

如果你真的想遍历数组,你需要这样做:

printf("%d\n", *(int *)(ptr+i));

但是,这会立即引发编译器警告:

warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]

这是有充分理由的:要进行指针运算,您的编译器需要知道所指向数据的大小。
但是 void 没有数据大小,因此在标准 C 中这是非法的。

一些编译器扩展支持它:http://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Pointer-Arith.html

但请注意,在 GCC 的情况下,大小为 1,因此您的数组将被视为 char 而非 int 的数组。

在你的应用程序中如何遍历缓冲区将取决于其中的数据是否统一。

如果您想要一个有效的遍历解决方案,您将需要提供实际的数据示例。