unsigned char 与char的区别

本文详细解释了C语言中char与unsigned char类型的本质差异,包括它们的表示范围、符号位处理方式以及在不同上下文中的行为表现。通过示例代码展示了在数值转换时这两种类型的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

char 与 unsigned char的本质区别

在C中,默认的基础数据类型均为signed,现在我们以char为例,说明(signed) char与unsigned char之间的区别 

首先在内存中,char与unsigned char没有什么不同,都是一个字节,唯一的区别是,char的最高位为符号位,因此char能表示-128~127, unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字。

在实际使用过程种有什么区别呢?

主要是符号位,但是在普通的赋值,读写文件和网络字节流都没什么区别,反正就是一个字节,不管最高位是什么,最终的读取结果都一样,只是你怎么理解最高位而已,在屏幕上面的显示可能不一样。

但是我们却发现在表示byte时,都用unsigned char,这是为什么呢?

首先我们通常意义上理解,byte没有什么符号位之说,更重要的是如果将byte的值赋给int,long等数据类型时,系统会做一些额外的工作。

如果是char,那么系统认为最高位是符号位,而int可能是16或者32位,那么会对最高位进行扩展(注意,赋给unsigned int也会扩展)

而如果是unsigned char,那么不会扩展。

这就是二者的最大区别。

同理可以推导到其它的类型,比如short, unsigned short。等等

具体可以通过下面的小例子看看其区别

include <stdio.h>

 

void f(unsigned char v)

{

    char c = v;

    unsigned char uc = v;

    unsigned int a = c, b = uc;

    int i = c, j = uc;

    printf("----------------\n");

    printf("%%c: %c, %c\n", c, uc);

    printf("%%X: %X, %X\n", c, uc);

    printf("%%u: %u, %u\n", a, b);

    printf("%%d: %d, %d\n", i, j);

}

 

int main(int argc, char *argv[])

{

    f(0x80);

    f(0x7F); 

    return 0;

}

 

输出结果:

----------------

%c: ?, ?

%X: FFFFFF80, 80

%u: 4294967168, 128

%d: -128, 128

----------------

%c: , 

%X: 7F, 7F

%u: 127, 127

%d: 127, 127

由此可见,最高位若为0时,二者没有区别,若为0时,则有区别了。

`static unsigned char` `unsigned char` 的区别可以从以下几个方面来理解: ### 1. 数据类型部分 (`unsigned char`) 无论是 `static unsigned char` 还是普通的 `unsigned char`,它们的数据类型都是相同的。`unsigned char` 表示一种无符号字符型数据类型,在大多数系统上占用一个字节 (8位) 并只能存储非负值。 - **范围**:0 到 255(即 \(2^8 - 1\)) - 它用于表示那些不需要考虑负数的情况,并且可以更有效地利用整个字节的存储空间 例如: ```c unsigned char a = 255; // 合法赋值 ``` --- ### 2. 存储类别部分 (`static`) 添加了关键字 `static` 就改变了变量的作用域、生命周期以及初始化规则等特性。下面是详细对比两者的差异点: #### (1)作用域的区别 - 普通的 `unsigned char`: 如果声明在一个函数内部,则它的作用域仅限于该块或函数内;如果是在全局范围内声明,则它在整个程序都可以访问到。 - 加入 `static` 关键字后的 `unsigned char`: 即使位于局部位置(如某个函数体内),其作用域仍然局限于当前源文件内或者是所在的那个特定函数中。换句话说,外部其他地方无法直接通过名字引用这个变量。 #### (2)生存期的不同 - 对于常规的自动存储分配类型的 `unsigned char`(比如作为函数内的局部变量时),当控制流离开定义它的区域之后就会销毁掉. - 而加上静态修饰符后(`static unsigned char`),即使处于函数里边,一旦创建完成就不会再被清除直到整个应用程序结束为止. 举个例子来看: ```c #include <stdio.h> void func() { unsigned char localVar = 0; printf("localVar=%d\n", ++localVar); static unsigned char staticLocalVar = 0; printf("staticLocalVar=%d\n", ++staticLocalVar); } int main(){ for(int i=0;i<3;i++)func(); } ``` 运行结果将显示每次调用`func()`都会对普通局部变量重置初值为零后再累加一次输出1; 而对于带了static标识的那个则会一直保留之前的数值并在下次基础上继续增加打印出连续递增的结果2->3依次类推... #### (3)默认初始值设定方式的变化 对于只简单地申明了一个`unsigned char`,除非特别指定否则不会给予明确的缺省起始状态; 但是若是运用到了`static`限定词的话那么即便用户没给出任何表达式来进行显式的设置,默认也会赋予相应基本整数系列的第一成员——也就是数字"0". 总结来说就是:`static unsigned char`相比单纯的`unsigned char`,拥有更大的存活时间长度同时限制了自己的可见性并且具备预设开启条件下的固定原始形态.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值