C 反向空洞阵列&;要转换到的数据类型是什么

C 反向空洞阵列&;要转换到的数据类型是什么,c,casting,void-pointers,C,Casting,Void Pointers,我已经为如下数组分配了内存: void *buf; buf = calloc(8192, 1); static void reverseBuffer(size_t size, void * buf) { for (size_t a = 0; a < size >> 1; a++) { uint8_t temp = ((uint8_t*) buf)[a]; ((uint8_t*) buf)[a] = ((uint8_t*) buf)[si

我已经为如下数组分配了内存:

void *buf;
buf = calloc(8192, 1);
static void reverseBuffer(size_t size, void * buf) {
    for (size_t a = 0; a < size >> 1; a++) {
        uint8_t temp = ((uint8_t*) buf)[a];
        ((uint8_t*) buf)[a] = ((uint8_t*) buf)[size - a - 1];
        ((uint8_t*) buf)[sizeof- a - 1] = temp;
    }
} 
现在,我从原始文件的文件流中读取8192字节到数组:

uint32_t fpos = 0;
int n;
n = fread(buf,1,8192,file);
fpos += n;
我将使用如下函数:

static void reverseBuffer(void *buf){
        for(int a = 0; a < sizeof(buf)>>1; a++){
            uint8_t temp = (uint8_t) buf[a];
            buf[a] = buf[sizeof(buf) - a - 1];
            buf[sizeof(buf) - a - 1] = temp;
        }
} 
静态无效反向缓冲(无效*buf){
对于(inta=0;a>1;a++){
uint8_t temp=(uint8_t)buf[a];
buf[a]=buf[sizeof(buf)-a-1];
buf[sizeof(buf)-a-1]=温度;
}
} 
很明显,它实际上不起作用,我需要如何转换数组,我需要使用什么数据类型?我试着将它铸造到uint_8,因为它的大小保证为1字节


在您的循环中,可能是
sizeof(buf)>>1而不是
sizeof(buf)>>2
可以使您的代码工作。

在不知道类型的情况下,不可能反转数组

考虑反转数组意味着什么。我们要交换第一个和最后一个元素,第二个和第二个到最后一个元素,依此类推

[0, 1, 2, 3] => [3, 2, 1, 0]
这是因为我们知道每个元素的大小。事实上,数据以1和0的形式存在

只有知道第一个和最后一个元素有多大,我们才能交换第一个和最后一个元素

// Element size is 3 bits
[000, 001, 010, 100] => [100, 010, 001, 000]
如果不知道每个元素的大小,就不可能知道第一个元素在哪里停止以及应该交换什么

// Unknown element size
000001010100

// Element size 1
[0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0] => [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]

// Element size 2
[00, 00, 01, 01, 01, 00] => [00, 01, 01, 01, 00, 00]

// Element size 4
[0000, 0101, 0100] => [0100, 0101, 0000]
这些类型定义一个元素的位数(例如,int可能是32位,long可能是64位)

如果不知道类型,就不可能知道元素大小,如果不知道元素大小,就不可能反转列表

我需要如何强制转换数组,需要使用什么数据类型?我试着将它转换为uint_8,因为它的大小保证为1字节

你就快到了

只是您不能取消引用
void
-指针,因为它指向
void
,所以不清楚应该计算哪种类型

解决方案是将指针强制转换为特定的指针类型。在您的情况下,请转到
uint8\u t*
,然后才取消引用它

另外,您的代码假定
sizeof buf
会给出数组的大小,而它没有给出。它给出了
buf
的大小,而
buf
是一个指针(
void*
),根据运行此代码的操作系统,您可以得到指针的大小,即4字节或8字节

因此,您需要让函数知道数组的大小。这可以通过传递来完成

然后,函数可能如下所示:

void *buf;
buf = calloc(8192, 1);
static void reverseBuffer(size_t size, void * buf) {
    for (size_t a = 0; a < size >> 1; a++) {
        uint8_t temp = ((uint8_t*) buf)[a];
        ((uint8_t*) buf)[a] = ((uint8_t*) buf)[size - a - 1];
        ((uint8_t*) buf)[sizeof- a - 1] = temp;
    }
} 

如果它是一个字节数组,为什么要将其键入
void*
?首先把它做成一个
uint\u 8*
。如果需要强制转换,请在尝试索引到指针之前强制转换指针;P你的意思是温度=(uint8)buf[a]?对不起,意思是(uint8*)buf[a]。看起来很管用,谢谢。
sizeof(buf)
不是你所期望的
buf
是一个指针,因此它的大小是4还是8取决于您是在32位还是64位操作系统上运行它。
buf
点的位置是不相关的。你是对的,它应该是>>2除以2。但这不是错误。编译器说我试图取消对void*的引用。还应避免使用divide运算符“/”,因为它在我使用的平台上效率极低。假设一个元素有8位/1字节,那么uint8_t类型是合理的。有没有一种方法可以分配像buf[index]=x这样的新值?我可以通过访问阵列。((uint8_t*)buf)[索引]。我是否需要像uint8_t temp=(uint8_t)buf;那样预先强制转换数组?“在不知道数组类型的情况下,不可能反转数组。”如果您不知道数组的类型,也不可能反转数组,OP的代码就是这样。干杯。这三种方法在性能上是否存在差异?除了必须在第二个方法中声明另一个变量之外。我认为第三个是最快的,因为编译器已经知道它所处理的类型了吗?@liquid:任何一个好的编译器都会从我怀疑的三个编译器中创建大致相同的汇编代码。尽管如此,我的选择还是第三种,因为函数的声明已经告诉了它期望的类型,即(指向)
uint8\t
。去3号,谢谢。目前正在使用编译器优化关闭tho。尽管如此,还是选择了option3,并为8/16位创建了功能,因为im以8位进行缓冲,而dsp以16位进行处理。让我可以选择在缓冲后直接反转整个块,或者在处理过程中以较小的块进行反转。
  reverseBuffer(8192, buf);