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算法,唯一的辦法是讓程序先執行一遍,記錄下實際的頁地址流情況,很明顯實際,實際上,經常把這種算法用來作爲評價其它頁面替換算法好壞的標準。