18

人们经常需要一次从内存中读取一个字节,就像在这个幼稚的memcpy()实现中一样:

void *memcpy(void *dest, const void *src, size_t n)
{
    char *from = (char *)src;
    char *to   = (char *)dest;

    while(n--) *to++ = *from++;

    return dest;
}

但是,我有时会看到人们明确地使用unsigned char *而不是仅仅使用char *.

当然,charunsigned char可能不相等。但是,无论我使用char *,signed char *还是按unsigned char *字节读取/写入内存时,这有什么不同吗?

更新:实际上,我完全知道c=200根据c. 我在这里要问的是为什么人们有时会使用unsigned char *而不是仅仅char *在读取内存时使用,例如为了将 an 存储uint32_tchar[4].

4

5 回答 5

23

你应该使用unsigned char. C99 标准说这unsigned char是唯一保证密集的类型(无填充位),并且还定义您可以通过将任何对象(位域除外)复制到unsigned char数组中来精确复制它,这是以字节为单位的对象表示

对我来说,明智的解释是,如果您使用指针以字节形式访问对象,则应该使用unsigned char.

参考:http ://blackshell.com/~msmud/cstd.html#6.2.6.1 (来自C1x 草案C99)

于 2011-12-05T13:50:00.203 回答
14

这是 C++ 与 C 不同的一点。一般来说,C 只保证原始内存访问适用于unsigned char; char可能是有符号的,并且在 1 的补码或有符号幅度机器上,-0 可能会自动转换为 +0,从而更改位模式。出于某种原因(我不知道),C++ 委员会将支持透明复制(位模式不变)的保证扩展到char,以及unsigned char; 在 1 的补码或有符号幅度机器上,实现者别无选择,只能制作普通char 的无符号数,以避免这种副作用。(当然,今天的大多数程序员无论如何都不关心这些机器。)

无论如何,最终结果是来自 C 背景的年长程序员(并且可能实际上在 1 的补码或有符号幅度机器上工作过)将自动使用unsigned char. 为字符数据、非常小的整数值、 原始内存或打算进行位操作时char唯一地保留纯文本也是一种常见的约定。这样的规则允许读者区分不同的用途(只要它被虔诚地遵循)。signed charunsigned char

于 2011-12-05T14:15:51.967 回答
2

在您的代码示例中,它没有区别。但是如果你想显示/打印字节的值而不是它(因为最高位的解释不同),并且unsigned char似乎更合适

于 2011-12-05T13:22:04.817 回答
0

这取决于您要存储在字符中的内容。有符号字符的范围是 -127 到 127,而无符号字符的范围是 0 到 255。

对于指针算术,这无关紧要。

于 2011-12-05T13:15:09.437 回答
0
#include<stdio.h>
#include<string.h>

int main()
{

unsigned char a[4]={254,254,254,'\0'};
unsigned char b[4];
char c[4];

memset(b,0,4);
memset(c,0,4);

memcpy(b,a,4);
memcpy(c,a,4);
int i;
for(i=0;i<4;i++)
{
    printf("\noriginal is %d",a[i]);
    printf("\nchar %d is %d",i,c[i]);
    printf("\nunsigned char %d is %d \n\n",i,b[i]);
}

}

输出是

original is 254
char 0 is -2           
unsigned char 0 is 254 


original is 254
char 1 is -2
unsigned char 1 is 254 


original is 254
char 2 is -2
unsigned char 2 is 254 


original is 0
char 3 is 0
unsigned char 3 is 0 

所以这里 char 和 unsign 都具有相同的值,所以在这种情况下没关系

编辑

如果您在这种情况下仍将任何内容读取为已签名的字符,则最高位也将被复制,因此没关系

于 2011-12-05T13:25:19.437 回答