赞
踩
前提:
- 不改变值的正负
- 不改变值的大小
规则:
- 无符号整数,直接补0。
- 有符号整数,扩充符号位。
- 与左值的有无符号无关(例:
short x = a; 与x是否有符号无关
)
- 规则:无论有无符号,丢弃
高位
数据
类型相容:
- 类型不同,但系统(编译器在编译阶段)可以自动类型转换(低精度——>高精度,小范围——>大范围),只针对
基本数据类型
- 基本数据类型:char、short、 int、long、long int、long long、unsigned char、unsigned short、unsigned int、 unsigned long int、unsigned long long,float、double类型
- 特定类型:指针、数组、结构体类型(不支持强转)、联合体类型、枚举类型不适用
#include <stdio.h> int main() { char a = -5; unsigned int b = 10; if (a > b) { printf("%d > %d\n", a, b); //无符号输出 printf("%u > %u\n", a, b); } else { printf("%d < %d\n", a, b); } return 0; }
分析:
- a和b进行比较时,signed char类型的a会自动转换成 unsigned int类型
- a = -5对应一字节补码
1111 1011
, 将补码扩充到4字节,对应的补码就是1111 1111 1111 1111 1111 1111 1111 1011
- 再将扩充后的补码
1111 1111 1111 1111 1111 1111 1111 1011
解析成无符号类型(正数),对应的原码就是1111 1111 1111 1111 1111 1111 1111 1011
对应的十进制 远远大于10
结果:
#include <stdio.h> int main() { char a = -5; //int 4字节补码1111 1111 1111 1111 1111 1111 1111 1011(-5) unsigned short b = 10; //int 4字节补码0000 0000 0000 0000 0000 0000 0000 1010(10) //char 和short都转成int 类型 if (a > b) { printf("%d > %d\n", a, b); //无符号输出 printf("%u > %u\n", a, b); } else { printf("%d > %d\n", a, b); } return 0; }
分析:
当char类型和short类型进行转化时,都会转成signed int类型
char a = -5; //int 4字节补码1111 1111 1111 1111 1111 1111 1111 1011(-5)
unsigned short b = 10; //int 4字节补码0000 0000 0000 0000 0000 0000 0000 1010(10)
结果:
#include <stdio.h> int main() { /* 分析: sizeof(int)== 4的值是一个unsigned int类型 比较时,signed int 会转成 unsigned int类型 -3补码:1111 1111 1111 1111 1111 1111 1111 1101 4补码:0000 0000 0000 0000 0000 0000 0100 以无符号来解读1111 1111 1111 1111 1111 1111 1111 1101就是很大的数 > 4 所以不进入循环 */ for (int i = -3; i < sizeof(int); i++) { printf("%d ", i); }`在这里插入代码片` return 0; }
#include <stdio.h> int main() { char a = 100; char b = 200; char c = a + b; /* 有符号 100: 0110 0100 -56: 1100 1000 c = 44: 1 0010 1100(截取低地址8位) %d输出表示再对c进行int类型扩充: 0000 0000 0000 0000 0000 0000 0010 1100(44) */ //%d格式符代表以有符号整型输出 a + b /* 分别将char的a、b扩充成int,在对其补码进行运算 a`: 0000 0000 0000 0000 0000 0000 0110 0100 b`: 1111 1111 1111 1111 1111 1111 1100 1000 1 0000 0000 0000 0000 0000 0000 0010 1100(截取低地址32位) 结果:`a + `b = 44 */ printf("c = %d, a + b = %d\n", c, a + b); unsigned char ua = 100; unsigned char ub = 200; unsigned char uc = ua + ub; /*无符号 100: 0110 0100 200: 1100 1000 uc:1 0010 1100(截取低地址8位) 以%d输出uc 0000 0000 0000 0000 0000 0000 0010 1100(44) ------------------------------------------- 以%d输出 ua + ub 先将ua、ub扩充成int ua`: 0000 0000 0000 0000 0000 0000 0110 0100 ub`: 0000 0000 0000 0000 0000 0000 1100 1000 ua` + ub`: 0000 0000 0000 0000 0000 0001 0010 1100(300) */ printf("uc = %d, ua + ub = %d\n", uc, ua + ub); return 0; }
#include <stdio.h> int main() { char c = 128; unsigned char uc = 128; unsigned short usum = 0; /* 有符号c: 1000 0000(魔鬼数-128) 无符号uc: 1000 0000 无符号short usum: 扩充后: c: 1111 1111 1000 0000 uc:0000 0000 1000 0000 补码运算:1 0000 0000 0000 0000(取低地址16位)->0 */ usum = c + uc; printf("%x\n", usum); /* 有符号c: 1000 0000(魔鬼数-128) 无符号uc: 1000 0000 强转无符号c: 1000 0000 无符号uc: 1000 0000 无符号char usum: 扩充: c: 0000 0000 1000 0000 uc:0000 0000 1000 0000 补码运算:0000 0001 0000 0000(取地址16位)->(0x100) */ usum = (unsigned char)c + uc; printf("%x\n", usum); /* 有符号c: 1000 0000(魔鬼数-128) 无符号uc: 1000 0000 uc强制转成有符号:1000 0000 c和uc再转成unsigned short c: 1111 1111 1000 0000 uc:1111 1111 1000 0000 补码运算: 1 1111 1111 0000 0000(取低地址16位0xff00) */ usum = c + (char)uc; printf("%x\n", usum); /* 有符号c: 1000 0000(魔鬼数-128) 无符号uc: 1000 0000 c扩充无符号short c: 1111 1111 1000 0000 uc扩充成无符号short uc: 0000 0000 1000 0000 补码运算: 1 0000 0000 0000 0000(取低地址16位 0x00) */ usum = (unsigned short)c + uc; printf("%x\n", usum); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。