c语言中整数在内存中的储存形式,C语言中的整数在内存中的格式

本文探讨了Intel平台上采用的小端字节序,解释了正负整数、无符号整数的内存表示,并深入解析了左移和右移操作在不同类型的整数中的行为。通过实例展示了如何判断子网掩码的合法性,以及如何计算有效掩码的位数。
摘要由CSDN通过智能技术生成

big endian 和 small endian

在intel机器上都是采用的small endian即小端字节序,也就是地位的地址低,高位的地址高。

点击(此处)折叠或打开

int i = 0x12345678

char c1 = *(char*)(&i)一个int型整数的地址就是其最低位的地址,所以上例中c1的值就是0x78

那么整数的正数,负数,以及无符号整数的表示方法有什么区别呢

对于正整数来说,内存里装的就是它自己的二进制码

点击(此处)折叠或打开

0x12345678 = > 0001 0010 0011 0100 0101 0110 0111 1000

求反 1110 1101 1100 1011 1010 1001 1000 0111

+1 1110 1101 1100 1011 1010 1001 1000 1000

结果 0xedcba988

而负数呢,是对齐相应的整数,逐位求反,然后+1.

负数的最高位都是1,不是规定的,而是算出来的结果,最高位必为1.

根据上述算法-1 不是0x80000001 而是0xFFFFFFFF.

下面相应的介绍一下左移<>的计算.

左移:

点击(此处)折叠或打开

#include

#include

int main(){

int a = 0x80000001;

int b = 0x70000000;

int c = 1;

printf("a:%x(%d)\n", a<<1, a<<1);

printf("b:%x(%d)\n", b<<1, b<<1);

return 1;

}

a:80000000(-2147483648)

b:2(2)

左移相对比较简单,是不考虑符号位的,符号位也会被移除,正数可能左移成负数,负数也可能编程正数

而右移呢,就需要考虑符号位了。右移过程中符号位保持不变,但注意符号位如果是1也是右移给右侧一位的,虽然自己不变。

点击(此处)折叠或打开

int main(){

int b = 0x80000001;

printf("b:%x\n", b>>1);

return 1;

}

[zhouqz@fb119 ~]$ ./a.out

b:c0000000

上例的结果既不是0x40000000也不是0x00000000,居然是0xc0000000(1100 0000 0000 ....)

那么无符号有什么区别么?左移来说,没有任何区别,但对于右移来说,因为无符号整数表示最高位不是符号位,右移就可以移动了

所以0x80000000 >> 1 就是0x40000000了

利用上面的特点,我们可以很技巧的判断一个给定的子网掩码是不是合法的掩码,什么是合法的呢?就是从左开始一直是1,一旦遇到0后,后续的不能再有1的出现。

点击(此处)折叠或打开

int is_netmask_valid(int mask){

if(((mask >> 1) & mask) == mask){

return 1;

}

return 0;

}

注意参数必须是int不能是unsigned int,因为要利用右移保留符号位的特性。道理比较简单,就是子网掩码一定是1...10...0的格式,右移之后,1的个数会多一个,但是和原来的mask做&操作后还是mask,如果mask是非法的,0与0之间一定混有1,一旦 右移又与操作后,就会多出2个1,就会不等于原来的mask了

怎么求一个合法的掩码的位数呢?

点击(此处)折叠或打开

int get_bit_of_netmask(int mask){

int i = 0;

while(mask){

mask = mask << 1;

i++;

}

return i;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值