深入理解计算机系统学习之信息的表示和处理

1 ,c语言的位级运算

分为:或,与,非,异或,取反
常见用法为掩码运算。
x & 0xFF 生成一个由x的低位有效字节的值,其他的字节被设置为0.
x | 0xFF 生成一个最低位为1,其他不变。

2,c语言的移位运算

在于逻辑右移和算术右移的区别
逻辑右移:左端补0
算术右移:左端补k个最高有效位的值
对于无符号数,右移必须是逻辑的,对于有符号数,两种都可以,一般都是算术右移。

3,无符号数编码和有符号数的补码

无符号数编码:整型数据w位,范围从{0~2^w-1}
有符号补码:{-2^w ~ 2^w-1},将最高有效位解释为负权,权重为-2^w-1.
为什么补码范围不对称?
因为一半的位模式(符号位设置为1)表示负数,一半的数(符号位设置为0)表示非负数。然而0为非负数,意味着正数比负数少一个。
c库中头文件limits.h,定义了一组常量来限定不同整型数据类型的范围:INT_MAX,INT_MIN,UINT_MAX

4,无符号数与有符号数之间的相互转换

有符号数-》无符号数:
位值不变,只是改变了解释这些位的方式,对于数x,w位
x = x+2^w ;x<0
x = x; x>=0
无符号数-》有符号数
数u,w位,
u= u; u < 2^(w-1)
u = u - 2^w; u>=2^(w-1)

5,为什么宏INT_MIN要写成-2147483647-1?

-2147483648 被看做为一个常量表达式,而不是一个常量。
2147483648超出了int,long int的范围,所以变成了unsigned long int,写成-2147483647-1可以精确的表示成为32位有符号数的最小数。

6,注意c语言中无符号和有符号数的表达式

执行一个运算时,一个数是有符号数,一个是无符号数,c语言将进行隐式类型转换,将有符号数转换为无符号数。
比如在

int sum(int a[i] ,unsigned length)
{
     sum = 0;
     int i;
     for(i = 0;i< length-1;i++)
         sum +=a[i];
     return sum;
}

当无符号数length= 0 时,0-1,将转换为最大的数,数组溢出,访问到不定的内存中去。

7,size_t 的安全漏洞

原型: size_t strlen(const char * s)
编写函数判断一个字符串是否比另一个更长。

int strlonger(char * s,char * t)
{
    return strlen(s)-strlen(t) > 0;
}

在头文件stdio.h中数据类型size_t 是定义为unsigned int 的。
如果strlen(s) < strlen(t) ,会产生负数,转换为无符号数是,变为一个很大的正数。
应该改为:return strlen(s) > strlen(t)

你可能感兴趣的:(计算机操作系统)