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;
}
我在我的项目中使用通用循环缓冲区。该缓冲区有一个空指针,指向在初始化期间传入的静态缓冲区。我想遍历并打印循环缓冲区中的数据。在找到上面的代码之前,我不确定如何打印内容。
我有两个问题:
- 这是遍历我的数据的合适且广为接受的方式吗? PC-Lint 等工具是否会发出警告?
- 是否有更好的方法来遍历这些数据?
编辑:
感谢 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
的数组。
在你的应用程序中如何遍历缓冲区将取决于其中的数据是否统一。
如果您想要一个有效的遍历解决方案,您将需要提供实际的数据示例。
我对使用 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;
}
我在我的项目中使用通用循环缓冲区。该缓冲区有一个空指针,指向在初始化期间传入的静态缓冲区。我想遍历并打印循环缓冲区中的数据。在找到上面的代码之前,我不确定如何打印内容。
我有两个问题:
- 这是遍历我的数据的合适且广为接受的方式吗? PC-Lint 等工具是否会发出警告?
- 是否有更好的方法来遍历这些数据?
编辑: 感谢 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
的数组。
在你的应用程序中如何遍历缓冲区将取决于其中的数据是否统一。
如果您想要一个有效的遍历解决方案,您将需要提供实际的数据示例。