4月份的笔试,考得不好,经过暑期的磨砺,回头再看那些题目,有些就豁然开朗了
1.关于类型转换
1.32位机上根据下面的代码,问哪些说法是正确的?
signedchar a = 0xe0;
unsignedint b = a;
unsignedchar c = a;
A.a>0 && c>0为真B.a == c为真C.b的十六进制表示是:0xffffffe0D.上面都不对
我总结了一个规律:
1.任何数在计算机中是以补码的形式存在的,所以如果我们printf输出则是补码输出
2.signed转换为unsigned的时候,最高位的1加入计算,最高位位0的不变
3.unsigned转换为signed的过程和上面的相反
4.char型转换为int的时候,先做类型提升,提升的时候,无论char是有符号还是无符号,要保证该数的正负性,即如果原数是正,提升补0,原数为负,提升补1,然后在转换到第2.3两种情况下
5.int型转换为char型,可能要考little endian/big endian,不管哪种,只要取最低位置的那个字节就可以了
下面的测试程序可以的出上面的结论:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
/*-signed -> unsigned*/
signed char s0 = 0xe0;
unsigned char t0 = s0;
printf("s0:%d\nt0:%d\n",s0,t0 );
/*+signed -> unsigned*/
signed char s1 = 0x0e;
unsigned char t1 = s1;
printf("s1:%d\nt1:%d\n",s1,t1 );
/*unsigned(最高位1) -> signed*/
unsigned char s2 = 0xe0;
signed char t2 = s2;
printf("s2:%d\nt2:%d\n",s2,t2 );
/*unsigned(最高位0) -> signed*/
unsigned char s3 = 0x0e;
signed char t3 = s3;
printf("s3:%d\nt3:%d\n",s3,t3);
/*+signed -> signed int -> unsigned int */
signed char m = 0x0e;
signed int n = m;
unsigned int p = m;
printf("m:%d\nn:%d\np:%d\n", m, n,p);
/*-signed -> signed int -> unsigned int*/
signed char a = 0xe0;
signed int b = a;
unsigned int c = a;
printf("a:%d\nb:%0x\nc:%0x\n",a ,b, c);
unsigned char a1 = 0xe0;
signed int b1 = a1;
unsigned int c1 = a1;
printf("a1:%d\nb1:%0x\nc1:%0x\n",a1 ,b1 , c1);
int x = 0x1234;
char y = *((char*)&x);
printf("%0x\n",y);
return 0;
}
2.关于little endian和big endian
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端
测试程序:
#include <stdio.h>
void main()
{
int x = 0x12345678, i = 0;
for(i = 0; i < 4; i++)
printf("%0x\n", *((char*)&x+i));
}
小端字节输出:78 56 34 12
大端字节输出:12 34 56 78
判断小端大端还有可以使用联合体,例如:
int main()
{
union{
int x;
char c;
}u;
u.x = 1;
if(u.c == 1)
printf("little endian\n");
else
printf("big endian\n");
return 0;
}
3.关于虚拟内存调度的算法
在内存有限的情况下,扩展一部分外存作为虚拟内存,真正的内存只存储当前运行时所用得到信息,虚拟页式存储管理减少了进程所需的内存空间,却也带来了运行时间变长这一缺点:进程运行过程中,不可避免地要把在外存中存放的一些信息和内存中已有的进行交换,由于外存的低速,这一步骤所花费的时间不可忽略。因而,采取我们要采取好的算法来减少这部分话费的时间
常见的算法有以下几种:
LRU:近期最少使用算法,每次替换的是最早替换进来的
FIFO:先进先出算法,维护一个队列,每次替换的是最早进入队列的那一页
OPT:最优替换算法,根据未来的替换页来替换,说明见图下说明
先说明一下缺页的概念,当CPU访问内存中的数据时,数据不存在就会发生缺页,此时如果数据在虚拟内存中,我们需要把数据从虚拟内存中置换到内存中,上面三种算法产生的缺页次数是不一样的
看如下三个图(从网上找的,不是自己画得,但都能很好的说明问题)
说明:当请求2时,2已在内存中,我的理解是做了一个替换2->2,所以下次请求1的时候,2是最近才进入队列的,需要替换掉2->1
缺页次数:16次
缺页次数:15
说明:例如,替换4的时候,我们看到4后面我们需要2和1页,所以我们此时就不要把2和1替换出来,应该把3替换出来,即3->4,再比如,请求6页的时候,看到6后面需要2和1,我们就把5替换出来
缺页次数:11次
我们可以看到OPT算法的效率最高,但是要实现OPT算法,唯一的办法是让程序先执行一遍,记录下实际的页地址流情况,很明显实际,实际上,经常把这种算法用来作为评价其它页面替换算法好坏的标准。