unsigned是c语言关键字吗(C语言关键字unsigned和signed意义的探讨与学习)

前言

我们都知道在计算机中最终所有的数据都会被转化为0和1,存在磁盘里面也是0和1,那不知道你们会不会有疑问,一个负数怎么存?刚刚我们也说了所有的数据都会是0和1的去存那我们的“—”负号也是一样被转换成了,因为我们的负号不能以“—”存在磁盘里面。

其实在我们电脑里面对于存取数据都会把基本说一句类型的最高为腾出来用来装我们的符号,然后规定是这样的:如果是有符号的数据类型,最高位是1那就说明这个数是负数,如果是0的话那就说明这个数是正数。

signed 关键字

被修饰的变量说明是有符号位的,当我们从内存拿到这个变量的时候我们要根据最高为是0还是1来判断数据的正负。

这样的话我们一个32位的signed int类型整数可以表示的范围只有 -2^31~((2^31)-1),8位char 类型数,它的值表示范围为 :-2^7~((2^7-)1)。反正我们要记住有符号的数据我们在判断值的时候要把最高位舍弃掉,因为它不是值,而是表示正负的。

unsigned关键字

我们再来说一下我们的无符号整型数据,当被这个关键字修饰的时候就说明数据是没有符号位的那到的数据全部都是真实的值。

我们一个32 位 unsigned int 可以表示的值的范围在0~(2^32)-1,我们 8位的unsigned char类型的数值范围是0~((2^8)-1)。

可能我们在声明变量的时候很少用这两个关键字来修饰变量,更多时候直接 int chat float ……等就开始定义变量了,那么这时候它到底是有符号还是无符号数据类型的,其实如果我们没有假关键字系统会默认给我们添加了signed 类型的,所以你可以忽略它的存在,但是要注意一点的是,我们的(char)类型的数据编译器并不会自动给你加上。

趣味代码

1#include<stdio.h> 2 #include<string.h> 3 4 5 int main () 6 { 7 signed char a[100]; 8 int i; 9 for(i=0;i<512;i ) 10 { 11 12 a[i]=-1-i; 13 //printf("a[%d]=%d",i,a[i]); 14 printf("%d ",a[i]); 15 if(((i 1)8)==0) 16 printf("\n\n"); 17 } 18 printf("\n数组长度%ld\n",strlen(a)); 19 return 0; 20 }

结果分析

你们觉得在这个代码最后的结果会是什么?我们很多人一看,就是数组长度呀,那不是100么?但是我想告诉你的是代码是255,为什么?

我们先来分析一下程序是怎么跑的,for循环中,当我们的 i 的值是0 的时候值是-1,关键是我们要知道我们的-1是怎么存储在我们的电脑中的,我们上过计算机系统的都知道存入电脑的数据都是以补码的形式来存的,主要原因是使用补码可以将我们的符号位和其他位统一处理,同时减法也可以按加法来处理,另外两个补码表示数的相加时,如果最高位(符号位)有进位则进位会被对齐,正数的 补码和原码一样,我们负数的补码:符号位是1,其余位是该数值绝对值的原码按位取反,然后整个数加1;

unsigned是c语言关键字吗(C语言关键字unsigned和signed意义的探讨与学习)(1)

计算机中的负一

按照我们负数补码的规则,我们可以知道 -1 的补码是0xff,-2的补码是0xfe……

我们看一下如果是八位的系统我们负一最高位是1。

第一步:1000 0000

第二步我们-1的绝对值是1,原码:0000 0001

第三步按位取反:1111 1110

第四步 加1 :1111 1111

到这里我们的-1的补码就表示好了存在系统里面的就是八个1,这时候我们验证一下我们知道(-1) 1=0

那我们的:(1111 1111) 1=?

是不是:0000 0000 全部是0了,这和我们计算的一样。

unsigned是c语言关键字吗(C语言关键字unsigned和signed意义的探讨与学习)(2)

回到刚刚的程序

当我们的i的值为127的时候 a[127]的值是-128(1000 0001) 是char类型数据能表示的最小的负数了, 当 i 继续增加a[128]的时候它的值肯定不是 -129 ,因为这时候发生溢出了呀,-129我们是需要9位才能存下来,但是我们的char类型只有8位,所以这时候最高位的符号位被丢弃了,剩下的8位是原来9位补码的低8位的值 0x7f(0 111 1111)(127) 这时候值是127 然后我们的i继续走 执行(-1-i)=126,(0111 1110)……直到变为0000 0000 ,这时候随着i的增加我们的 a的值有编程了最开始的 (-1-0)=-1(1111 1111)然后(-1-1)=-2(1111 1110)说起来比较绕我们看看程序跑的结果我们可以分析出来程序是怎么跑的了。

unsigned是c语言关键字吗(C语言关键字unsigned和signed意义的探讨与学习)(3)

回到刚刚的-129的时候,我们把最高位丢弃,然后就变成了0x7f ,当我们的i继续增加到255的时候,-256的补码的低位为0,然后当i增加到256的时候,-127的补码全为1,低8位的补码为0xff,如此新的一轮循环开始……

结论

按照我们上面的分析a[0]~a[254]里面的值都是不为0的,而a[255]的值为0,strlen函数是计算我们字符串长度的并不包含字符串后面的“\0”,判断一个字符串的结束标志的是有没有遇到“\0”,如果遇到了就停止计算了。所以我们说到这里我们的值为什么是255应该清楚了吧。但是今天并不是要讨论strlen的用法,希望大家知道的是signed char 类型范围是[-128,127]超出这个范围就会溢出了。另外你还要清楚负数的补码该怎么表示和计算。

unsigned是c语言关键字吗(C语言关键字unsigned和signed意义的探讨与学习)(4)

哎呦终于说完了,你们慢慢消化吧,有什么想法可以说出来大家一起学习一下!

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页