1)32位機上根據下面的程式碼,問哪些說法是正確的?(C)
signed char a = 0xe0;
unsigned int b = a;
unsigned char c = a;
A. a>0 && c>0 為真
B. a == c 為真
C. b 的十六進位制表示是:0xffffffe0
D.上面都不對
解析:這個題目涉及到 有符號數和無符號數之間的轉換0xe0的最高位是1,因此作為有符號數就是負數,作為無符號數就是正數
所以 A 肯定是錯的, B也錯,c = 0xe0是正數,原因是正數和負數怎麼可能相等呢,C是對的 負數的高位用1補齊,這樣分析的話 D 自然不會對
2)問下面的資料都存放在哪些儲存區?
int main()
{
char *p = "hello,world";
return 0;
}
解析:根據C語言中的特性和定義p是一個區域性變數,而C語言中區域性變數存在於棧中,"hello wrold"是一個字串字面常量,因此儲存於程式的只讀儲存區中,p在這裡其實只是指向了"hello wrold"在只讀儲存區中的地址而已。
3)關於 int a[10]; 問下面哪些不可以表示 a[1] 的地址?(A)
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1
D. (int*)((char*)&a+sizeof(int))A. a+sizeof(int)
解析:
A. a+sizeof(int)
// 不正確, 在32位機器上相當於指標運算 a + 4
B. &a[0]+1
// 正確,陣列首元素地址加1,根據指標運算就是a[1]的地址
C. (int*)&a+1
// 正確,陣列地址被強制型別轉換為int*,然後加1,這樣和B表示的一個意思
D. (int*)((char*)&a+sizeof(int))
// 正確,資料地址先被轉換為char*,然後加4,根據指標運算公式,向前移動4 * sizeof(char),之後被轉換為int*,顯然是a[1]的'地址
4)下面哪些說法正確?(B)
A. 陣列和連結串列都可以隨機訪問
B. 陣列的插入和刪除可以 O(1)
C. 雜湊表沒有辦法做範圍檢查
D. 以上說法都不正確
解析:陣列可以直接通過下標得到儲存的值 因此支援隨機,訪問連結串列是鏈式儲存結構時無法支援隨機訪問,要訪問一個指定位置的元素必須從頭開始做指標移動。雜湊表支援直接通過關鍵碼得到值 其實陣列就是一種雜湊表 下標就是關鍵碼 通過下標直接得到值 因此雜湊表肯定需要做範圍檢查也有辦法做範圍檢查的
5)基於比較的排序的時間複雜度下限是多少?(C)
A. O(n)
B. O(n^2)
C. O(nlogn)
D. O(1)
解析:大家記住這個結論就好 在當前計算機科學界對於基於比較的排序 最快只是O(n*logn)
6)有兩個執行緒,最初 n=0,一個執行緒執行 n++; n++; 另一個執行 n+=2; 問,最後可能的 n 值?(BCD)
A. 1
B. 2
C. 3
D. 4
解析:大家要知道 C語言中的 ++ 和 += 並不是原子操作,而是通過多條微程式組成的,因此 ++ 和 += 在執行過程中可能被中斷的
第一種可能情況:現在假設兩個執行緒沒有並行順序執行的那麼結果顯然是 4。
第二種可能情況:再假設現在第一個n++ 已經執行完了 但是結果還沒有寫回記憶體 這個時候 n+=2 已經全部執行完 2 寫進了記憶體 結束 然後回到n++的寫回操作 這個時候記憶體就從2被改回1了,後面再來一次n++ 結果就為2。
第三種可能情況: 第n+=2 先讀取n的值到暫存器 即0入暫存器 這個時候被中斷 第一個n++開始執行 並直到結束 記憶體被改成了1 ,然後 n+=2 繼續執行 結束後記憶體變為2 第二個n++再執行 結果就是3了。
我個人認為 不可能得到1的執行結果
7)下面哪些函式呼叫必須進入核心才能完成?(AB)
A. fopen
B. exit
C. memcpy
D. strlen
解析:我覺得這題 肯定是 fopen 和 exit
fopen是開啟檔案的函式,檔案也可以看成是一個裝置,開啟一個裝置將導致給裝置所屬的驅動程式傳送一個IRP,而與真實硬體相關的驅動程式都運行於核心.
exit函式是結束程序的函式,結束程序需要訪問PCB(程序控制塊)和TCB(執行緒控制塊)等等一些資料結構,而這些資料都存在於核心中.原因很簡單 memcpy 和 strlen 我們可以直接不呼叫任意函式寫出來這種函式肯定不會實現在核心的
8)死鎖發生的必要條件?(ABCD)
A. 互斥條件
B. 請求和保持
C. 不可剝奪
D. 迴圈等待
解析:互斥條件,請求和保持,不可剝奪 ,迴圈等待,這些都可能發生死鎖 所以以後大家在做多執行緒程式時一定要注意了。
9)填空題
#include
#include
#define M 3
#define N 4
int get(int *a, int i, int j)
{
return *(a+i*N+j);
}
int main()
{
int a[M][N] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int v;
v = get(a, 2, 1);
printf("a[2][1] == %dn", v );
return 0;
}
解析:大家注意原型中的指標是int* a,所以必須用二維陣列在記憶體中是一維排布這個知識點來做,直接 return *(a+i*N+j);
而不是 return *(*(a+i)+j);