在C中将Char数组转换为Long

Aja*_*ayR 4 c memory

这个问题可能看起来很傻,但请指导我,我有一个函数将长数据转换为char数组

void ConvertLongToChar(char *pSrc, char *pDest)
{
    pDest[0] = pSrc[0];
    pDest[1] = pSrc[1];
    pDest[2] = pSrc[2];
    pDest[3] = pSrc[3];
}
Run Code Online (Sandbox Code Playgroud)

我将上述函数称为这样

long lTemp = (long) (fRxPower * 1000);
ConvertLongToChar ((char *)&lTemp, pBuffer);
Run Code Online (Sandbox Code Playgroud)

哪个工作正常.我需要一个类似的功能来反转过程.将char数组转换为long.我不能使用atol或类似的功能.

Vin*_*ura 11

你可以做:

union {
 unsigned char c[4];
 long l;
} conv;

conv.l = 0xABC;
Run Code Online (Sandbox Code Playgroud)

和访问c[0] c[1] c[2] c[3].这很好,因为它不浪费任何内存并且非常快,因为除了最初的一个之外没有任何移位或任何分配,它可以双向工作.

  • 根据C++标准,它也是未定义的行为.:) (4认同)
  • ^ 编译器所做的实际上根本没有提供关于标准所说的内容的信息,尽管您碰巧是正确的。@jalf 不,C 通过 C99 中明确指定的“联合”进行类型双关:/sf/ask/814796321/然而,它已经成为指定的 C++ **没有**继承这一点。 (3认同)
  • 最好的方法. (2认同)
  • @jalf 这是一个 C 问题。 (2认同)
  • @NickWiggil 很公平。根据 C 标准,这也是未定义的行为。:) (2认同)

Eti*_*tel 7

一个简单的方法是使用memcpy:

char * buffer = ...;
long l;
memcpy(&l, buff, sizeof(long));
Run Code Online (Sandbox Code Playgroud)

但是,这并不考虑字节序,因此请注意,如果必须在多台计算机之间共享数据.


Ker*_* SB 7

将端点与您的其他功能相匹配的负担留给您,这是一种方式:

unsigned long int l = pdest[0] | (pdest[1] << 8) | (pdest[2] << 16) | (pdest[3] << 24);
Run Code Online (Sandbox Code Playgroud)

为了安全起见,这是相应的其他方向:

unsigned char pdest[4];
unsigned long int l;
pdest[0] = l         & 0xFF;
pdest[1] = (l >>  8) & 0xFF;
pdest[2] = (l >> 16) & 0xFF;
pdest[3] = (l >> 24) & 0xFF;
Run Code Online (Sandbox Code Playgroud)

char[4]长到长都是完全可逆的; char[4]对于高达2 ^ 32-1的值,从长时间返回到后方是可逆的.

请注意,所有这些只是为无符号类型定义良好.

(如果你从左到右阅读,我的例子是pdest.)

附录:我也是这样认为的CHAR_BIT == 8.通常,用CHAR_BIT代码中的倍数代替8的倍数.