龙空技术网

C语言signed和unsigned的使用与注意事项

霸都嵌入式 232

前言:

此刻兄弟们对“c语言default”大概比较关怀,各位老铁们都想要剖析一些“c语言default”的相关资讯。那么小编同时在网摘上收集了一些对于“c语言default””的相关文章,希望同学们能喜欢,你们快快来学习一下吧!

C语言中,signed和unsigned是两个类型修饰符,它们可以用来修饰整数类型,表示变量的符号属性。signed表示变量是有符号的,可以存储正数和负数;unsigned表示变量是无符号的,只能存储非负数。在使用signed和unsigned时,需要注意以下几个方面:

signed和unsigned的使用方法

- signed和unsigned可以修饰int、short、long和long long等整数类型。例如:

signed int a; //有符号整型unsigned int b; //无符号整型signed short c; //有符号短整型unsigned short d; //无符号短整型signed long e; //有符号长整型unsigned long f; //无符号长整型signed long long g; //有符号long long类型unsigned long long h; //无符号long long类型

- signed是默认的,如果不加任何修饰符,变量就是有符号的。因此,int等价于signed int,short等价于signed short,long等价于signed long,long long等价于signed long long。例如:

int i; //等价于signed int i;short j; //等价于signed short j;long k; //等价于signed long k;long long l; //等价于signed long long l;

- unsigned则需要显式给出,表示变量没有符号位。例如:

unsigned int m; //无符号整型unsigned short n; //无符号短整型unsigned long o; //无符号长整型unsigned long long p; //无符号long long类型

- 对于long和long long常量,可以使用后缀直接给出unsigned的属性。例如:

120L; //L后缀表示long常量120LU; //LU后缀表示unsigned long常量120LLU; //LLU后缀表示unsigned long long常量120ull; //ull后缀也表示unsigned long long常量
signed和unsigned的区别

- signed和unsigned的区别主要在于是否把存储的某一位看做符号位。对于n位的二进制数,如果是有符号的,最高位是符号位,0表示正数,1表示负数;如果是无符号的,没有符号位,所有位都表示数值。

- 有符号数在计算机中用补码表示。正数的补码是其本身;负数的补码是其绝对值取反加一。例如:

8位有符号数5的补码为:000001018位有符号数-7的补码为:11111001(|-7|=7 -> 00000111 -> 11111000 -> +1)

- 无符号数在计算机中用原码表示。原码就是二进制数本身。例如:

8位无符号数5的原码为:000001018位无符号数7的原码为:00000111

- 因此,同样一个二进制数,在不同的类型下可能表示不同的值。例如:

8位二进制数11111001,在有符号类型下表示-7,在无符号类型下表示249。

- 同样长度的有符号数和无符号数能够存储的数值范围也不同。对于n位的二进制数,如果是有符号的,最小值为-2^(n-1),最大值为2^(n-1)-1;如果是无符号的,最小值如果是无符号的,最小值为0,最大值为2^n-1。例如:

8位有符号数的范围是-128 ~ 1278位无符号数的范围是0 ~ 255
signed和unsigned的注意事项

- 在使用signed和unsigned时,需要注意以下几个方面:

- 在进行算术运算时,如果有符号数和无符号数混合运算,会发生隐式类型转换,导致结果不正确或者溢出。例如:

int a = -1;unsigned int b = 1;printf("%d\n", a + b); //输出0,因为a被转换为无符号数,其值为4294967295(2^32-1)printf("%u\n", a + b); //输出4294967296,因为结果溢出了无符号数的范围

- 在进行比较运算时,如果有符号数和无符号数混合比较,也会发生隐式类型转换,导致结果不正确。例如:

int a = -1;unsigned int b = 1;printf("%d\n", a < b); //输出0,因为a被转换为无符号数,其值为4294967295(2^32-1),大于bprintf("%d\n", a > b); //输出1,同理

- 在进行位运算时,如果有符号数和无符号数混合运算,也会发生隐式类型转换,导致结果不正确。例如:

int a = -1;unsigned int b = 1;printf("%d\n", a & b); //输出1,因为a被转换为无符号数,其值为4294967295(2^32-1),与b按位与后仍然是1printf("%d\n", a | b); //输出-1,因为结果被转换为有符号数,其值为4294967295(2^32-1),按照补码规则表示-1

- 在进行赋值运算时,如果有符号数和无符号数混合赋值,也会发生隐式类型转换,导致结果不正确。例如:

int a = -1;unsigned int b = 1;a = b; //a的值变为1b = a; //b的值变为4294967295(2^32-1)

- 为了避免这些问题,在使用signed和unsigned时,应该尽量保持类型一致,或者使用强制类型转换来明确表达意图。例如:

int a = -1;unsigned int b = 1;printf("%d\n", (int)(a + b)); //输出0,强制将结果转换为有符号数printf("%u\n", (unsigned int)(a + b)); //输出4294967296,强制将结果转换为无符号数printf("%d\n", (int)a < (int)b); //输出1,强制将两个操作数都转换为有符号数printf("%d\n", (unsigned int)a > (unsigned int)b); //输出0,强制将两个操作数都转换为无符号数

系列文章持续更新,如果觉得有帮助请点赞+关注!

标签: #c语言default