c - 有没有办法将未知类型的数组作为参数传递给 C 中的函数?
问题描述
我一直在努力提高我在 C 语言中的技能和知识。今天我尝试创建一个接受任何类型数组的函数,但我还没有找到成功的方法,我使用的是 ANSI C,我试过了将它作为 void 指针传递,但是当我试图通过使用参数操作的内存时,编译器会抱怨。有没有办法实现它?我在想可能可以通过预处理器指令来完成,但我不确定。
PS:我的目标不是用数据填充数组,这只是一个函数,而是理解和学习如何在我不知道数据类型的情况下传递数据,或者允许我的函数使用不止一种类型的数据。
这是编译过程的输出:
array_test.c:在函数“array_fill”中:
array_test.c:34:13:警告:算术中使用的“void *”类型指针 [-Wpointer-arith]
*(数组 + i) = 数据;
^
array_test.c:34:5:警告:取消引用“void *”指针
*(数组 + i) = 数据;
^~~~~~~~~~~~
array_test.c:34:5: 错误:无效使用无效表达式
*(数组 + i) = 数据;
^
这是我的代码:
#include <stdio.h>
#define array_length(array) (sizeof(array)/sizeof(array[0]))
#define ARBITRARY_SIZE 10
typedef enum
{
false,
true
} bool;
int array_fill(void*, int, int);
int main(int argc, char* argv[])
{
int array[ARBITRARY_SIZE];
int i;
array_fill(array, array_length(array), 0);
for(i = 0; i < array_length(array); i++)
{
printf("array[%d]: %d\n", i, *(array + i));
}
return 0;
}
int array_fill(void* array, int size, int data)
{
int i;
for(i = 0; i < size; i++)
{
*(array + i) = data;
}
/*I will implement a check later, in case of errors.*/
return 0;
}
解决方案
指针指向内存中某个对象的开头。大多数指针还通过类型知道该对象在内存中的大小,但void *
.
例如,如果指向 32 位整数的指针的值为 0,我们知道位 0 到 31 包含对应于该 32 位整数的数据。
0 31
|---| <- 32 bits storing the data for a 32-bit integer
对于您的问题,更重要的是,如果我们知道这个指针指向一个 32 位整数序列,我们知道我们可以通过将指针向前移动 32 位来获得下一个整数。例如,第二个整数将从 32 开始。
0 31 32 63
|---| |---|
This is what int[2]. might look like in memory on a 32-bit system
这就是指针算法的工作原理。使用 void 指针void *array
,您无法做到这一点array++
,甚至*array
因为无法知道指针前进多少位或对应于多少位array
。
0 ??
|----
We don't know how many bits a void pointer points to
从技术上讲,您也可以通过传递对象的大小来解决这个问题,尽管这可能不是一个好主意。
// array points to the memory to be filled
// len is the number of elements in the array
// size is the size of an element (in bytes)
// fill points to an object to be used to fill array
void array_fill(void* array, int len, size_t size, void* fill) {
// char is always a single byte
char* byte_ptr = (char*) array;
for (int i = 0; i < len; i++) {
// Fill the current element
memcpy(byte_ptr, fill, size);
// Advance byte_ptr the correct number of bytes
byte_ptr += size;
}
}
如果您不想使用memcpy
,也可以一次手动将fill
对象复制到byte_ptr
一个字节。
推荐阅读
- svg - 如何获取里面一个角色的风格
- python - 如何在 Tensorflow 中创建自定义图像数据集
- python - 通过 pandas 操作访问特定组中的组
- java - 如何将 Or 标准与限制列表一起使用
- python - 如何将不规则的时间序列重新采样为每日频率并跨越到今天?
- api - 如何在获取成功响应中呈现 react-native 组件?
- python - datetime 与 date 的时间差为 0 秒
- azure - 使用 Azure 托管的 Godaddy 域电子邮件帐户
- c - 为什么我必须在等待特定信号之前设置 pthread_sigmask
- tabulator - 是否可以在不将其附加到 DOM 的情况下创建 Tabulator 表?