0

Char是 1 个字节 unsigned short是 2 个字节

因此,如果我将 achar *转换为unsigned short *,它会改变缓冲区的长度吗?

例如,我正在将char *长度传递给 VUMeter 函数。该函数将转换char *unsigned short *

short* pln = (short*) buffer;`

现在我遍历缓冲区,所以我可以使用传递的相同长度吗?

int peak=0;
short* pln = (short*) buffer;
for (int i=0; i<len; i++)
{
  if(abs(pln[i]) > peak)
     peak = abs(pln[i]);
}  

出于某种原因,我在循环中遇到了应用程序错误。

4

3 回答 3

1

如果元素的大小加倍,那么你有空间容纳一半的元素。投射指针不会调整它的大小,基本上假设你知道你在用指针做什么。

所以不,你不能真正将一个 char * 转换为一个短 * 并期望一切正常。如果您需要一个与 char * 具有相同值的短 *,则需要分配一个短数组并从 char * 中单独复制元素。

于 2010-02-07T18:51:01.357 回答
0

unsigned short可能是也可能不是 2 个字节。让我们看看您的示例的内存。

+---+---+---+     +---+---+---+
|   |   |   | ... |   |   |   |
+---+---+---+     +---+---+---+

|<-------- len bytes -------->|

如果unsigned short是 2 个字节长,则您有空间len/2 unsigned short值。或者,更一般地说,您有len/n unsigned short值的空间,其中n等于sizeof(unsigned short)

你不能投一个unsigned char *tounsigned char *并期望事情可以便携。现在,要计算peak,这取决于您要执行的操作。如果您想找到最大值len unsigned char并将其保存到peak中,则循环这些值将起作用:

size_t i;
unsigned short peak = 0;
for (i=0; i < len; ++i) {
    if (buffer[i] > peak) {
        peak = buffer[i];
    }
}

但是,如果您想将值“组合”sizeof(unsigned short)成一个unsigned short值,那么最好的办法是手动计算数字。

假设它len可以被 , 和大端存储整除n,您可以执行以下操作(未经测试):

#include <stdio.h>
#include <limits.h> 

size_t factor = sizeof(unsigned short);
size_t n = len / factor;
size_t i;
unsigned short peak = 0;
if (len % factor != 0) {
    fprintf(stderr, "Extra data at the end\n");
}   
for (i=0; i < n; ++i) {
    size_t j;
    unsigned short test = 0;
    for (j=0; j < factor; ++j) {
        test = (test << CHAR_BIT)  + buffer[i*factor+j];
    }
    if (test > peak) {
        peak = test;
    }
}
于 2010-02-07T19:56:01.867 回答
0

在调用 *alloc() 之前,分配的内存不会改变。数据类型大小不同的事实只会影响“步长”(“x+1”将指向 x + 2 个字节),但您将有空间容纳一半的元素。

就个人而言,我会避免简单地投射指针。它可能会使内存块中已经存在的数据被误读(两个单独的字节现在将作为单个值读取,这与您在用 1 字节值填充缓冲区时的想法完全不同:两个后续值 127, 127 将成为单个值:65535,诸如此类)。而且我认为它也会在编译器中引发警告(至少 GCC 抱怨这样的演员表)。我认为你应该做的是:

int x = SOMEVAL;
char * cptr = malloc(x*sizeof(char));
/* some code here - fill cptr with data */
uint16 * sptr = malloc(x*sizeof(uint16));
int i;
for (i = 0; i < x; i++) {
    *(sptr+i) = (uint16)(*(cptr+i));
}
free(cptr);

除非我快速编写的代码中有一些错误(我没有费心检查它),否则它应该做你想要实现的:将指针从 char*“转换”到 uint16*,但也可以安全地复制数据而无需改变值(除非字符之间有负值,ofc)。

于 2010-02-07T20:06:31.313 回答