char转unsigned char_C中signed与unsigned之间的区别

本文详细介绍了C语言中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, %cn", c, uc);

    printf("%%X: %X, %Xn", c, uc);

    printf("%%u: %u, %un", a, b);

    printf("%%d: %d, %dn", 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时,则有区别了。

在C和C++中,`float*` `unsigned char*`、`uint32_t*` `signed char*`、`uint32_t*` `char*` 这些操作本身并不违反编程规范,但存在潜在的风险和需要考虑的问题。 ### `float*` `unsigned char*` 这种换可能违反编程规范,因为它绕过了类型系统。`float` 类型通常用于表示浮点数,而 `unsigned char` 用于表示无符号的字节。直接换可能会导致数据的错误解释。例如: ```c #include <stdio.h> int main() { float num = 3.14f; unsigned char* ptr = (unsigned char*)&num; for (int i = 0; i < sizeof(float); i++) { printf("%02x ", ptr[i]); } return 0; } ``` 这里只是简单地将 `float` 的内存表示按字节输出,没有考虑浮点数的实际意义,可能会导致数据的错误使用。 ### `uint32_t*` `signed char*` 同样存在风险,`uint32_t` 是无符号的32位整数,而 `signed char` 是有符号的8位整数。换可能会导致数据截断和符号问题。例如: ```c #include <stdio.h> #include <stdint.h> int main() { uint32_t num = 0xFFFFFFFF; signed char* ptr = (signed char*)&num; printf("%d\n", ptr[0]); return 0; } ``` 这里将一个32位无符号整数换为8位有符号整数,可能会产生意外的结果。 ### `uint32_t*` `char*` `char` 在C和C++中可能是有符号的也可能是无符号的,具体取决于编译器。这种换同样可能导致数据截断和解释错误。例如: ```c #include <stdio.h> #include <stdint.h> int main() { uint32_t num = 0xFFFFFFFF; char* ptr = (char*)&num; printf("%d\n", ptr[0]); return 0; } ``` 综上所述,这些换都可能违反编程规范,因为它们绕过了类型系统,可能导致数据的错误解释和使用。在实际编程中,应该尽量避免这种直接的指针类型换,除非有明确的需求和充分的理由。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值