按顺序读取内存:“signed char *”vs“unsigned char *”

时间:2011-12-05 13:09:46

标签: c++ c coding-style char unsigned-char

通常需要一次一个字节地从内存中读取,就像在这个天真的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 *,例如为了在uint32_t中存储char[4]

5 个答案:

答案 0 :(得分:21)

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

对我来说明智的解释是,如果你使用指针来访问对象作为字节,你应该使用unsigned char

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

答案 1 :(得分:12)

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

无论如何,最终的结果是来自C的老程序员 背景(也许实际上是在1的补码或者 签名量级机器)将自动使用unsigned char。它的 也是为字符数据保留普通char的常用惯例 唯一的,signed char表示非常小的积分值,和 unsigned char表示原始内存,或意图进行位操作。 这样的规则允许读者区分不同的用途 (如果遵循宗教信仰)。

答案 2 :(得分:2)

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

答案 3 :(得分:0)

这取决于你想要存储在char中的内容。 带符号的char给出的范围是-127到127,而unsigned char的范围是0到255。

对于指针算术而言无关紧要。

答案 4 :(得分: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都有相同的值,所以在这种情况下无关紧要

修改

如果您在某种情况下阅读任何已签名的字符,那么大多数高级位也会复制,因此无关紧要