嵌入式或LINUX相關研發面試題目

 

http://blog.csdn.net/anxiongshan/archive/2007/10/11/1819511.aspx 

 

目錄

一、ANSI C/C++方面的知識 

二、POSIX方面的知識

三、Linux編程基本使用知識

四、C++題目

五、QT編程

六、MiniGUI編程 

七、Kernel & Driver 

八、用中文Linux辦公

九、娛樂

 

一、ANSI C/C++方面的知識 

(一.I).簡答題。下面的題目必須全部答對纔給分(20分): 

1、 如何在C中初始化一個字符數組。 

2、 如何在C中爲一個數組分配空間。 

3、 如何初始化一個指針數組。 

4、 如何定義一個有10個元素的整數型指針數組。 

5、 s[10]的另外一種表達方式是什麼。 

6、 GCC3.2.2版本中支持哪幾種編程語言。 

7、 要使用CHAR_BIT需要包含哪個頭文件。 

8、 對(-1.2345)取整是多少? 

9、 如何讓局部變量具有全局生命期。 

10、C中的常量字符串應在何時定義? 

11、如何在兩個.c文件中引用對方的變量。 

12、使用malloc之前需要做什麼準備工作。 

13、realloc函數在使用上要注意什麼問題。 

14、strtok函數在使用上要注意什麼問題。 

15、gets函數在使用上要注意什麼問題。 

16、C語言的詞法分析在長度規則方面採用的是什麼策略? 

17、a+++++b所表示的是什麼意思?有什麼問題? 

18、如何定義Bool變量的TRUE和FALSE的值。 

19、C語言的const的含義是什麼。在定義常量時,爲什麼推薦使用const,而不是#define。 

20、C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。 

 

(一.II).問答題。 

1、----------------------------------------------------------- 

"匈牙利命名法"有什麼優缺點?(2分) 

2、----------------------------------------------------------- 

下面x, y, *p的值是多少,有什麼問題?(2分) 

int x, y, z = 2; 

int *p=&z; 

x=sizeof*p; 

y=x/*p; /* x=?, *p=?, y=?, 有什麼問題?*/ 

 

3、----------------------------------------------------------- 

 

下面的語句是什麼意思?如何聲明或定義才使它們更易懂?(10分) 

int (*foo())(); 

int (*foo())[]; 

int (*foo[])(); 

(*(void(*)())0)(); 

void (*signal(int,void(*)(int)))(int); 

 

4、----------------------------------------------------------- 

 

本題(2分)。一般使用malloc時,需要進行強制類型轉換,如: 

char *s; s = (char *)malloc(31); 

下面中???該如何填寫,纔可以正確執行強制類型轉換? 

int (*monthp)[31]; monthp = (???)malloc(31); 

 

5、----------------------------------------------------------- 

 

關於C語言運算符優先級的記憶技巧是什麼?(2分) 

/* 下面r的值是多少 */ 

int hi, low, r; 

hi=7;low=3; 

r=hi<<4+low; 

 

6、----------------------------------------------------------- 

 

指針和數組的區別是什麼?用一個簡單的聲明把它們區分開。(2分) 

指針和數組的聲明在什麼情況下是相同的?(2分) 

 

7、----------------------------------------------------------- 

 

C語言的左值(lvalue)和右值(rvalue)的含義是什麼?(2分) 

 

8、----------------------------------------------------------- 

 

爲什麼C語言可以實現printf(char *format, ...)這樣可變參數的調用形式?這樣有什 

 

麼缺點?(2分) 

 

9、----------------------------------------------------------- 

 

說明C語言中術語"聲明""定義""原型"的含義?(2分) 

 

10、----------------------------------------------------------- 

 

舉一個例子,說明使用assert和防錯代碼的區別。(5分) 

 

11、----------------------------------------------------------- 

 

對語句 if else 與操作符 ? : 使用場合的比較。(2分) 

 

12、----------------------------------------------------------- 

 

編寫一個函數,輸入一個的整型數字,可以選擇按照8/10/16進制輸出字符串。 

注意邊界值。(5分) 

 

13、----------------------------------------------------------- 

 

本題(2分)。下面是一個16x16的黑白圖標: 

static unsigned short stopwatch[] = { 

0x07c6, 

0x1ff7, 

0x383b, 

0x600c, 

0x600c, 

0xc006, 

0xc006, 

0xdf06, 

0xc106, 

0xc106, 

0x610c, 

0x610c, 

0x3838, 

0x1ff0, 

0x07c0, 

0x0000, 

}; 

如何修改聲明,可以使之在源代碼中形象地表現出圖形的模樣。 

 

14、----------------------------------------------------------- 

說出可以使用calendar[11][30]變量的四種類型定義。(5分) 

如:int calendar[12][31]; /* 二維數組 */ 

 

15、----------------------------------------------------------- 

使用strcmp,當字符串相同時會返回'/0'。但'/0'一般作爲邏輯假, 

因此下面的語句不容易理解: 

if (!strcmp(s, "string")) return EQUATION; 

如何經過簡單修改,使之更易懂?(2分) 

 

16、----------------------------------------------------------- 

編寫一個自己的完全C語言版本的memset函數,並且評價這個實現的性能和可移植性。(5 

 

分) 

 

17、----------------------------------------------------------- 

在樹和圖這些數據結構中,通常使用指針來組織數據。如果我們要把這些數據保存到文 

 

件 

中,指針是沒有意義的。我們該如何解決這個問題。(2分) 

 

18、----------------------------------------------------------- 

用2種不同的方法計算long變量的"1"bit的個數。(2分) 

 

19、----------------------------------------------------------- 

任意給出一個C的基本數據類型,如何編碼判斷這個數據類型是有符號還是無符號的?(2 

 

分) 

不得上機實驗,寫出下面代碼的輸出。解釋這個行爲是標準定義的,還是依賴實現的。( 

 

2分) 

int i; 

for (i = 0; i < 10; i++) { 

int j = i; 

printf ("%d/n", j); 

 

20、----------------------------------------------------------- 

列出5種以上你所看過的C編程的書籍,並寫簡要書評。(5分) 

對C的評價。如果要你改造一把菜刀,使之更加安全,你是否會使用這樣的菜刀,爲什麼?(5分) 

 

(一.III)、分析題。 

本題(各5分)。假設下面代碼中的變量都是合法變量,調用外部的函數都是正確的。回答幾個問題: 

這些代碼意圖要幹什麼? 

是否有問題? 

如果有問題,該如何修改,或者如何避免類似錯誤發生? 

如果沒有問題,如果代碼有輸出,輸出是什麼? 

1、----------------------------------------------------------- 

 

int isvowel (char c) 

return c=='a'||c=='e'||c=='i'||c=='o'||c=='u'; 

 

2、----------------------------------------------------------- 

 

while (c=='/t'||c=' '||c=='/n') 

c=getc(f); 

 

3、----------------------------------------------------------- 

 

/* 當x=2, y=3, z=? */ 

if (x==0) 

if (y==0) 

       z=-1; 

else 

z=x+y; 

 

4、----------------------------------------------------------- 

 

/* 處理網絡事件 */ 

void process_network_code(int x, int y) 

/* 選擇modes_pointer資源 */ 

switch (line) { 

       case THING1: 

         /* 處理異常1#, 使用老的modes_pointer資源 */ 

         doit1(); 

         break; 

       case THING2: 

         /* 處理異常2#, 需要重新啓動服務 */ 

         if (x == STUFF) { 

            /* 重新申請modes_pointer資源,沒有初始化 */ 

            do_first_stuff(); 

            /* 在這種條件下,有些資源不用重新申請 */ 

            if (y == OTHER_STUFF) 

                   break; 

            /* 申請剩下的資源,並初始化 */ 

            do_later_stuff(); 

         } 

         /* 初始化modes_pointer資源 */ 

         initialize_modes_pointer(); 

         break; 

       default: 

         /* 處理普通事件, 使用老的modes_pointer資源 */ 

         processing(); 

/* 使用modes_pointer資源,處理事件 */ 

use_modes_pointer(); 

 

5、----------------------------------------------------------- 

 

int is_gb2312_char(char c1, char c2) 

if (c1 >= 0xa1 && c2 >= 0xa1) 

       return 1; 

else 

       return 0; 

 

6、----------------------------------------------------------- 

 

下面x, y的值是多少,有什麼問題? 

int x = 10, y = 3; 

x ^= y; 

y ^= x; 

x ^= y; 

/* x=?, y = ? */ 

 

7、----------------------------------------------------------- 

 

int days[]={31,28,31,30,31,30,31,31,30,31,30,31,}; 

int calendar[12][31]; 

int (*monthp)[31]; 

int *dayp; 

int i; 

 

memset(calendar, 0, sizeof(calendar)); 

i = 0; 

for (monthp = calendar; monthp < &calendar[12]; monthp++) { 

for (dayp = *monthp; dayp < &(*monthp)[31]; dayp++) { 

       if (dayp - *monthp < days[calendar - monthp]) { 

         *dayp = i++ % 7 + 1; 

       } 

 

8、----------------------------------------------------------- 

 

void printnum(long n) 

if (n < 0) { 

       putchar('-'); 

       n = -n; 

 

if (n >= 10) { 

       printnum(n/10); 

 

putchar ("0123456789"[n%10]); 

 

9、----------------------------------------------------------- 

 

void * memchr(void *pv, unsigned char ch, size_t size) 

unsigned char *pch = (unsigned char *) pv; 

unsigned char *pchEnd = pch + size; 

 

while (pch < pchEnd) { 

       if (*pch == ch) 

         return (pch); 

       pch++; 

 

return NULL; 

 

10、----------------------------------------------------------- 

 

void * memchr(void *pv, unsigned char ch, size_t size) 

unsigned char *pch = (unsigned char *) pv; 

unsigned char *pchPlant = pch + size; 

unsigned char chSave = *pchPlant; 

 

*pchPlant = ch; 

while (pch != ch) { 

       pch++; 

*pchPlant = chSave; 

 

return ((pch == pchPlant) ? NULL : pch); 

 

11、----------------------------------------------------------- 

 

void UnsToStr(unsigned short int u, char *str) 

char *pch; 

 

assert(u <= 65535); 

pch = &str[5]; 

*pch = '/0'; 

do { 

       *--pch = u % 10 + '0'; 

} while ((u / 10) > 0); 

 

strcpy(str, pch); 

 

12、----------------------------------------------------------- 

 

void *memmove(void *pvTo, void pvFrom, size_t size) 

char *pbTo = (char *)pvTo; 

char *pbFrom = (char *)pvFrom; 

 

((pbTo < pbFrom) ? tailmove : headmove) (pbTo, pbFrom, size); 

return (pvTo); 

 

13、----------------------------------------------------------- 

 

void *memcpy(void *pvTo, void pvFrom, size_t size) 

char *pbTo = (char *)pvTo; 

char *pbFrom = (char *)pvFrom; 

 

while (size-- > 0); 

       *pbTo++ = *pbFrom++; 

return (pvTo); 

 

14、----------------------------------------------------------- 

 

#include <stdio.h> 

 

int main(int argc, char *argv[]) 

char s[]="0123456789"; 

int i = 0; 

 

do { 

       printf ("%c", i++[s]); 

} while(s?1:printf("/n")-1); 

 

return 0; 

 

15、----------------------------------------------------------- 

 

int fibonacci(int x) 

if (x == 1 || x == 2) 

       return 1; 

return fibonacci(x - 2) + fibonacci(x - 1); 

 

16、----------------------------------------------------------- 

這裏有一個程序cdecl.c。寫出它的工作流程。寫出它的使用方法。 

給出一個典型輸入用例,記錄下它的輸出。 

 

(一.IV)、綜合編程題。 

要求: 

1、完成需求,程序運行正確。 

2、工作原理文檔,使用文檔完整。 

3、代碼規整優美。註釋得當。 

4、運行速度足夠快。 

5、用工具分析出是哪些代碼或函數造成速度瓶頸。 

 

1、----------------------------------------------------------- 

編寫一個排序程序。被排序的文件有8MB大小,一行一個隨機整數(ASCII格式)。要求對 

 

這些整數進行 

排序,並計算平均值,打印出排序所需的時間。(20分) 

 

2、----------------------------------------------------------- 

用dummy header技巧實現一個鏈表DEMO。要求具有create, insert, delete, search功 

 

能。 

編寫一個應用程序,使用上面的函數。使用dummy header技巧有什麼優點。(20分) 

 

3、----------------------------------------------------------- 

用heapsort算法實現優先隊列。要求具有create, insert, delete功能。 

編寫一個應用程序,使用上面的函數。使用heapsort算法有什麼優點。(20分) 

 

用trie(一種多叉樹)實現一個字典。要求具有create, insert, delete, search功能。 

 

編寫一個應用程序,使用上面的函數。使用trie樹有什麼優點。(20分) 

 

二、POSIX方面的知識。 

(二.I)、簡答題。下面的題目必須全部答對纔給分:(5分) 

1、在UNIX環境中,編譯流程是什麼? 

2、ABI,ELF的英文全稱是什麼 

3、一般UNIX的程序有多少段,舉一個實際的例子說明。 

4、如何在kernel二進制代碼中找一個字符串。 

5、段地址F000:FFF0轉換爲線形地址的值是多少(16進製表達)。 

6、在一個UNIX文件系統中,文件的唯一性標誌是什麼? 

 

(二.II)、問答題。 

1、----------------------------------------------------------- 

寫一些代碼。如何用文件實現信號燈?要求如果程序崩潰了,這個文件也將自動被刪除 

 

。 

爲什麼可以這樣實現信號燈?(5分) 

傳統的signal函數信號處理爲什麼是不可靠的,信號和系統調用有何關係?(5分) 

在圖形庫系統中往往提供timer的功能,除了使用ALARM信號外,你還可以使用什麼系統 

 

調用來實現timer?(5分) 

2、----------------------------------------------------------- 

寫一些代碼,演示如何正確使用write系統調用。注意看好手冊再回答。(2分) 

如果一個文件以rw模式打開,在進行read/write操作轉換時,需要進行什麼操作。(2分) 

 

 

3、----------------------------------------------------------- 

解釋終端結構termios.c_cc的MIN/TIME數值變化的帶來read/write的特性。(5分) 

如何理解終端、控制終端、虛擬終端、控制檯、tty等類同的概念?(5分) 

4、----------------------------------------------------------- 

 

解釋計算機中Copy-On-Write的概念。(2分) 

 

調用fork之後,子進程沒有繼承父進程的屬性有哪些?(5分) 

解釋爲什麼每個程序在裝入執行之後,總是已經預先打開了stdout、stdin、stderr?(2分) 

在fork之前,父進程打開了一個文件。在fork之後,如果子進程移動了文件指針, 

父進程的文件指針有什麼變化;如果子進程關閉了文件,父進程有什麼變化?爲什麼會這樣?(5分) 

標準輸入、輸出和錯誤輸出分別是什麼類型的緩衝,這些緩衝在用戶空間還是在覈心空間? 

怎樣關閉他們的緩衝?如果父進程關閉了緩衝,在fork之後建立的子進程是否也關閉了緩衝?(5分) 

vfork和fork相比,有什麼特色?(2分) 

system函數是否等同於fork+exec?(2分) 

 

wait系統調用有多少種條件可以退出?(2分) 

 

5、----------------------------------------------------------- 

系統調用和庫函數調用有什麼區別。(2分) 

在linux2.4.x上的glibc和newlib(一種嵌入式C庫)的系統調用有什麼不同?(2分) 

在linux2.4.x上,對系統調用execve如果調用成功,它返回的值是多少。(2分) 

 

6、----------------------------------------------------------- 

列出你所知道的2個內存跟蹤庫。(2分) 

設計一個內存跟蹤方案,爲什麼選擇這個方案(5分) 

 

(二.III)、綜合編程題。 

要求: 

1、完成需求,程序運行正確。 

2、工作原理文檔,使用文檔完整。 

3、代碼規整優美。註釋得當。 

4、運行速度足夠快。 

 

1、----------------------------------------------------------- 

這裏有一個8MB的文件,編寫一個copy程序,拷貝這個文件,並計算所需時間。用工具分析

出是哪些代碼或函數造成速度瓶頸。 

提示:如果只是使用read/write調用,不是一個好的實現。(20分) 

 

2、----------------------------------------------------------- 

Linux系統中,什麼時候會出現類似Y2K的問題。寫一個程序證明。(20分) 

 

3、----------------------------------------------------------- 

編寫一個程序,測試系統最小的睡眠時間間隔。(20分) 

 

4、----------------------------------------------------------- 

編寫一個pipe程序,測試有N個管道,size大小的buffer情況下,pipe的傳輸性能是多少?(20分) 

 

5、----------------------------------------------------------- 

在ext2文件系統上,單個文件最大可以達到多少? 

寫一個程序獲得這方面的限制。(20分) 

 

三、Linux編程基本使用知識。 

(三.I).命令和shell 

1)編寫一個腳本,統計一個目錄下面所有C代碼的行數。(2分) 

2)編寫一個sed腳本,去除HTML文件中的HTML標記。(2分) 

3)編寫一個腳本獲得當前系統eth0的IP地址。(2分) 

4)編寫一個腳本以交互的方式,進行DNS的設定。(2分) 

5)使用ls命令編寫一個腳本,實現ls -R,遞歸列出當前目錄下的所有目錄、文件。(2分) 

6)----------------------------------------------------------- 

在一個目錄下,找soft-link files,用下面的命令,原理是可行的,但無法操作, 

該如何解決?要2種方法。(2分) 

ls -l | grep -> 

 

7)----------------------------------------------------------- 

如何把標準錯誤輸出,重定向到標準輸出上。(2分) 

 

8)----------------------------------------------------------- 

我們的系統中的軟件包是使用RPM管理的。要求下面的問題寫出shell命令和運行結果。( 

 

5分) 

如何知道系統中安裝了幾個軟件包。 

如何知道系統中安裝了哪幾類(group)軟件包。 

如何知道kernel軟件包的簡述。 

如何知道kernel軟件包的Changelog。 

如何知道kernel軟件包有幾個文件。 

如何知道kernel軟件包安裝後有多大。 

 

(三.II)、編輯工具的使用。(各2分) 

1)如何使用vi進行塊拷貝、粘貼、刪除的操作 

2)如何設置Tab的長度,以及自動縮進的長度 

3)如何使用tag進行代碼閱讀 

4)如何在1~10行,有確認的進把所有的RedHat改爲RedFlag 

5)在SourceNavigator中,如何跳到一個變量的聲明處?如何得知光標當前的位置在那個函數體內? 

 

(三.III)、編譯器與調試器。(各2分) 

1)如何使用gcc得到宏展開的中間代碼 

2)如何通過gcc在命令行中傳入宏定義 

3)在那一級優化的情況下,內聯函數才真正的內聯到代碼中 

4)gdb的watch命令如何使用,有何缺點 

5)gdb中使用什麼命令可以顯式調用的棧幀,如何查看某個棧幀上的局部變量 

6)如何使用gdb調試多進程 

7)如何使能/禁止core dump? 

 

(三.IV)、庫。(各2分) 

1)如何知道XSetIMValues這個符號在那個X的庫文件中 

2)如何讀取C++的符號名,更具可讀性 

3)請解釋動態庫的soname概念 

4)解釋在鏈接時rpath選項的含義 

 

(三.V)、Makefile。(10分) 

如果有一個簡單的Test項目目錄如下: 

# tree Test 

Test 

|-- common.h 

|-- main.cpp 

|-- test.cpp 

`-- test.h 

 

1)使用wildcard、patsubst函數編寫一個C++項目的Makefile文件 

2)使用automake、autoconfig編寫一個支持configure選項的configure.in腳本 

 

(三.VI)、CVS。(10分) 

1)如果一個CVS項目中,甲添加了一個子目錄模塊,那麼乙在update時是否會自動檢 

出這個新添加的子模塊?如果不能,那麼你有什麼好的解決方案? 

2)如何在一個CVS項目中添加一個二進制文件,這個二進制文件可以進行增量的版本管理嗎? 

3)如何檢出標記(tag)爲milestone-1的版本,如何創建以milestone-1爲基礎的分支 

 

milestone-1-b1,並如何把分支的修改合併到milestone-1的主分支上 

 

(三.VII)、Linux/GNU編程基本知識 

1、----------------------------------------------------------- 

Linux2.4.x有多少種類型的設備文件?分別寫出來。(2分) 

 

2、----------------------------------------------------------- 

glibc動態庫的搜尋次序是什麼?(2分) 

glibc 2.1.x 與 2.2.x的動態庫的搜尋次序有什麼不同?爲什麼會採用現在的方案?(2分) 

 

 

3、綜合編程題。 

要求: 

1、完成需求,程序運行正確。 

2、工作原理文檔,使用文檔完整。 

3、代碼規整優美。註釋得當。 

4、運行速度足夠快。 

 

1、----------------------------------------------------------- 

本題(20分)。寫一個程序,有三個功能: 

a)取得CMOS中的當前時間,按照YY:MMD:HH:MM:SS格式輸出。 

b)取得物理內存的大小,格式化輸出。 

c)取得從物理段地址F000:FFF0起,16個字節的值,每字節按照16進制格式輸出。 

 

2、----------------------------------------------------------- 

本題(20分)。對串口編程,編寫一對類似ping的程序,作用在串口上,瞭解serial的聯 

 

通情況。 

定義協議 

要求: 

定義一個聯通和響應協議。至少具有:發送、回覆、超時三種狀態。除超時狀態外,所有 

狀態的數據必須經過校驗纔可使用。 

 

ping_serial_client 

要求: 

1,發送數據包; 

2,等待回覆數據包,直到超時; 

3,如果有回覆數據包,對數據包進行校驗; 

4,計算校驗通過的數據包之間的時間差; 

5,重複直到用戶退出; 

6,統計丟包率,時間。 

界面: 

bash# ping_serial_client /dev/ttyS0 baud_value 

??bytes from ttyS0, time=??ms 

...... 

^C 

--- ttyS0 ping statistics --- 

?? packets transmitted, ?? received, ??% loss 

time ??ms, min/avg/max = ??/??/?? ms 

 

ping_serial_server 

要求: 

1,等待對方的發送數據包; 

2,對發送數據包進行校驗; 

3,校驗通過則回覆數據包; 

4,重複直到用戶退出; 

 

界面: 

bash# ping_serial_server /dev/ttyS0 baud_value 

 

3、----------------------------------------------------------- 

編寫一對socket程序,要求類似於network echo procotol。 

Client每隔1秒把自己的IP地址輪流循環發送給一個Server. 

Server接到IP後,在屏幕上打印對方IP;然後把自己的IP發送回去。 

Client收到回覆後,在屏幕上打印對方IP。 

程序一直運行,直到用戶退出。各自分類統計接收到的各IP的數據包的個數。 

注意:Client可以向多個Server發送請求,Server也可以接收多個Client請求。 

注意:輸出信息的美觀,和對錯誤的處理。 

----------------------------------------------------------- 

 

 

四、C++題目。 

 

----------------------------------------------------------- 

 

1。給定下面的代碼: 

 

class Graph{ 

public: 

    Graph() { s_gCount++; } 

 

    virtual ~Graph() { s_gCount--;} 

 

    virtual int drawOut() = 0; 

 

    static int getTotalCount() { return s_gCount; } 

 

protected: 

    int m_x; 

    int m_y; 

    static int s_gCount; 

}; 

 

回答下列問題:(各5分) 

 

1)這個類能否生成實例,爲什麼? 

2)上述代碼中有什麼錯誤? 

3)如果有一個Rectangle類公共繼承該類,那麼s_gCount對Rectangle的成員屬性是什麼 

 

? 

4)對Graph及其子類的計數是否有效,如果無效應該採取什麼措施? 

5)請畫出該類的內存佈局結構示意圖 

 

 

----------------------------------------------------------- 

 

2。給定下面的代碼: 

class A 

    int a; 

}; 

 

class AA : public A 

    int aa; 

}; 

 

class X : public virtual A 

    int x; 

}; 

 

class Y : public virtual A 

    int y; 

}; 

 

class Z : public X, public Y { 

    int z; 

}; 

 

回答下列問題:(各5分) 

 

1)請畫出上述5個類的UML類圖 

2)請畫出A、AA、X、Z的內存佈局結構示意圖 

 

 

----------------------------------------------------------- 

 

3。給定下面代碼: 

#include <stdio.h> 

#include <stdlib.h> 

 

typedef struct _AAA 

    int a; 

}AAA, *PAAA; 

 

class CAAA 

public: 

    CAAA() { m_a.a = 0; } 

    CAAA(CAAA& in) { printf("CAAA(CAAA& in)/n"); } 

 

    CAAA(AAA in) { printf("CAAA(AAA in)/n"); } 

    CAAA(int in) { printf("CAAA(int in)/n"); } 

 

private: 

    AAA m_a; 

 

public: 

    operator PAAA () 

    { 

        return &m_a; 

    } 

}; 

 

void test0(PAAA pa) 

    printf("test0/n"); 

 

void test1(CAAA ca) 

    printf("test1/n"); 

 

void test2(CAAA ca) 

    printf ("test2/n"); 

 

void main(void) 

    CAAA a; 

    test0 (a); 

 

    AAA b; 

    test1 (b); 

 

    int i=0; 

    test2 (i); 

 

請回答下列問題:(各5分) 

 

1)找出程序中的錯誤 

2)test0函數聲明傳入的參數爲PAAA類型,而在main函數中,實際傳入的是CAAA類型, 

 

   這是否是一個錯誤?如果不是,請解釋原因。 

 

 

 

4。回答下列問題: 

1)C++中的struct和class類型有什麼區別?(2分) 

2)假定一個class名爲Test,具有構造函數、拷貝構造函數、operator =,那麼 

    Test a; 

    Test b=a; 

   分別執行的是哪一個函數?(2分) 

3)C++程序進行鏈接時是否必須鏈接stdc++函數庫,如果不必須情況下不需要,什麼情 

 

況下需要?(2分) 

4)你所熟悉的關於C++的中英文經典書籍都有哪些,它們分別都側重於什麼方面?(5分) 

 

 

五、QT編程。任選2題完成。(各20分) 

要求:按照綜合編程題目的要求編寫代碼和文檔。 

1.編寫一個簡單的clock控件, 要求從QWidget繼承, 有一個指針和錶盤,指針每12秒轉一 

 

圈, 

並且可以用鼠標左鍵,起動和停止指針的轉動. 

 

2.給定一個designer生成的UI文件, 讀取指定名字控件的幾何信息,計算出該控件的面積 

 

大小. 

(用Dom和SAX都可) 

 

3.設計一個程序, 建立個人信息庫,包括:姓名,年齡,性別,住址.建立完之後可以查處特 

 

定人 

的信息,用designer設計你的界面, 不要求把信息庫存在硬盤上. 

 

4.把第三題變成國際化程序, 要求兩種語言中文和英文.需要用qt-linquist等工具. 

 

5. 用QSocket實現兩臺不同機器間的收發, 收發要求用戶動態輸入. 

 

提示:以上各題需在qt3.0以上實現,推薦用qt-3.1.1,不限止qt-embedded或qt-desktop. 

 

 

六、MiniGUI編程 

要求:按照綜合編程題目的要求編寫代碼和文檔。 

1.裁剪MiniGUI字體庫,使它僅支持英文和繁體中文。(10分) 

2.描述MiniGUI/MPP的消息機制(20分) 

3.使用MPP和MySql,編寫一使用在商場POS機上的應用,要求如下:(50分) 

    1)收銀員帳戶管理:每臺POS機供若干個收銀員和一個系統管理員使用.收銀員憑密碼 

 

登錄POS機,密碼可修改.收銀員只能查看自己的銷售數據, 

    但不能刪除.系統管理員可以增加刪減收銀員帳戶,查詢銷售記錄. 

    2)收款管理:計算顧客購買商品總金額;計算找零 

    3)顧客會員管理:根據顧客ID,判斷會員等級及相應打折級別. 

    4)屏幕鎖定功能:特定按健觸發屏幕鎖定,輸入密碼後解鎖 

 

七、Kernel & Driver 

內核基礎試題 

1. 簡答題。(各10分) 

1.1  Spin Lock 相對於信號量的特點;在UP/MP/SMP這些不同環境下,Spin Lock的不同實現方法。 

1.2  簡要說明e2compr壓縮文件系統的壓縮策略;經其處理後,上層文件系統(EXT2/3等)是否會受到影響。 

1.3  比較linux操作系統內核態和用戶態的搶佔性,及兩者之間存在差異的原因。 

1.4  linux2.2支持的最大進程數是多少,演進至2.4後,這一制約是如何克服的。 

1.5  列舉中斷屏蔽的類型,並簡單比較。 

1.6  列舉linux所要處理的定時/計數器(實際的外圍硬件設備,不是指軟件定時器),及其用途。 

 

2. 問答題。(各20分) 

2.1  窮舉在用戶態空間,內核消息的獲取方式、差異、以及差異的原因。 

2.2  解釋linux進程調度中的epoch概念,該機制的目的。 

2.3  描述一個硬件中斷信號發生,到爲其註冊的中斷服務例程開始執行,之間所經過的內核處理過程。並進一步分析,制約linux

 

中斷響應時間的因素存在於哪些方面。 

2.4  比較底半機制(BH)和Tasklet的特點,及運行方面的差異。 

2.5  說明引導過程中initrd.img和linuxrc作用,給出製作initrd.img的僞代碼形式的流程。 

2.6  在VFS層中如何區分設備文件和正規文件? 

2.7  內核有幾種方式訪問硬件設備? 

2.8  內核如何訪問iomem?請舉例說明。 

 

3. 分析題。 

3.1  系統時間設置問題。(10分) 

     同樣採用date命令,目的在於修改系統時間,在不同的系統上卻有不同的現象: 

     假定初始時間(T1)爲 03月01日16:00 2003年,期望的修改後時間(T2)爲 12月31日00:00 2002年, 

     <1> 在EDK系統中,執行命令 #date 123100002002,系統時間立即會變爲T2; 

         但系統重新啓動之後,系統時間仍恢復爲T1的時間區間: 03月01日16:02

2003年,修改並未保留下來。 

     <2> 在RedHat7.2/8.0中,重複上述設置,系統重新啓動之後,時間設置得到了保 

 

留,系統運行於T2的時間區間:12月31日00:02 2002年。 

     請分析<1> 中所表現出的現象是由於什麼原因造成的; 

 

3.2  在大家相關於串口的工作中,可能會遇到這樣的問題:(20分) 

     串口在發送數據時,不是連續且迅速地發送,而是以一個固定的節拍(10秒),且 

 

 

每次只發送等長度的一段數據,請列舉可能造成這一問題的所有原因; 

 

3.3  Oops分析。(50分) 

     以下是一段經過符號解析過的Oops信息,我們知道造成這個Oops的直接原因在於對 

 

於 

內核函數__wake_up的調用過程之中出現了問題;基於上述判斷,請基於已經給出 

的__wake_up相關源碼和反彙編碼,大致分析問題出現在哪個源碼行,並給出分析結論; 

 

 

----------------------------------------------------------- 

ksymoops信息: 

ksymoops 2.4.4 on i686 2.2.19-rthal3.  Options used 

-v /usr/src/linux-2.2.19/vmlinux (specified) 

-k /proc/ksyms (specified) 

-l /proc/modules (specified) 

-o /lib/modules/2.2.19-rthal3/ (default) 

-m /usr/src/linux-2.2.19/System.map (specified) 

 

current->tss.cr3 = 07d29000, %cr3 = 07d29000 

*pde = 00000000 

Oops: 0000 

CPU:   0 

EIP:   0010:[<C01110C1>] 

Using defaults from ksymoops -t elf32-i386 -a i386 

eax: 00000014   ebx: c0eabf74  ecx: 00000013  edx: 00000021 

esi: 00000000   edi: 00000020  ebp: c0eabf6c  esp: c0eabf60 

ds: 0018   es: 0018  ss: 0018 

Process in.identd (pid: 828, process nr: 6, stackpage=c0eab000) 

Stack: 00000000 c807ca04 00000021 c0eabf74 c807be21 c0eabfb0 c807bf74 

c807c940 

       00000000 00000000 00000000 c803fb60 c807e000 00000e20 2b124c28 

0000027c 

       0010a000 c807c900 00000000 0000f944 bffff944 c803d2ec 00000000 

00000000 

Call Trace: [<c807ca04>] [<c807be21>] [<c807bf74>] [<c807c940>] 

[<c803fb60>] [<c807e000>] 

[<c807c900>] [<c803d2ec>] [<c803c0a0>] 

Code: 8b 02 85 45 fc 74 1b 85 ff 74 10 83 7a 44 00 74 0a 85 f6 75 

 

>>EIP; c01110c1 <__wake_up+2d/6c>   <===== 

 

Trace; c807ca04 <[rt_das]timeout+c4/c8> 

Trace; c807be21 <[rt_das]read_timeout+25/28> 

Trace; c807bf74 <[rt_das]pulse_isr+150/19c> 

Trace; c807c940 <[rt_das]timeout+0/c8> 

Trace; c803fb60 <[rtai]global_irq_handler+0/80> 

Trace; c807e000 <.bss.end+14a1/????> 

Trace; c807c900 <[rt_das]board+0/28> 

Trace; c803d2ec <[rtai]dispatch_global_irq+28/90> 

Trace; c803c0a0 <[rtai]GLOBAL0_interrupt+18/34> 

Code;  c01110c1 <__wake_up+2d/6c> 

00000000 <_EIP>: 

Code;  c01110c1 <__wake_up+2d/6c>   <===== 

   0:   8b 02                     movl   (%edx),%eax   <===== 

Code;  c01110c3 <__wake_up+2f/6c> 

   2:   85 45 fc                  testl  %eax,0xfffffffc(%ebp) 

Code;  c01110c6 <__wake_up+32/6c> 

   5:   74 1b                     je     22 <_EIP+0x22> c01110e3 

<__wake_up+4f/6c> 

Code;  c01110c8 <__wake_up+34/6c> 

   7:   85 ff                     testl  %edi,%edi 

Code;  c01110ca <__wake_up+36/6c> 

   9:   74 10                     je     1b <_EIP+0x1b> c01110dc 

<__wake_up+48/6c> 

Code;  c01110cc <__wake_up+38/6c> 

   b:   83 7a 44 00               cmpl   $0x0,0x44(%edx) 

Code;  c01110d0 <__wake_up+3c/6c> 

   f:   74 0a                     je     1b <_EIP+0x1b> c01110dc 

<__wake_up+48/6c> 

Code;  c01110d2 <__wake_up+3e/6c> 

  11:   85 f6                     testl  %esi,%esi 

Code;  c01110d4 <__wake_up+40/6c> 

  13:   75 00                     jne    15 <_EIP+0x15> c01110d6 

<__wake_up+42/6c> 

 

Unable to handle kernel paging request at virtual address 66fe4603 

current->tss.cr3 = 00e94000, %cr3 = 00e94000 

*pde = 00000000 

Oops: 0000 

CPU: 0 

EIP: 0010:[<c01113e6>] 

EFLAGS: 00010a83 

Warning (Oops_read): Code line not seen, dumping what data is available 

 

>>EIP; c01113e6 <interruptible_sleep_on+5a/78>   <===== 

 

 

 

1 warning issued.  Results may not be reliable. 

 

 

<附錄> 

1. __wake_up的源碼: 

    void __wake_up(struct wait_queue **q, unsigned int mode) 

    { 

        struct task_struct *p, *best_exclusive; 

        struct wait_queue *head, *next; 

        unsigned int do_exclusive; 

 

            if (!q) 

            goto out; 

        /* 

         * this is safe to be done before the check because it 

         * means no deference, just pointer operations. 

         */ 

        head = WAIT_QUEUE_HEAD(q); 

 

        read_lock(&waitqueue_lock); 

        next = *q; 

        if (!next) 

            goto out_unlock; 

 

        best_exclusive = 0; 

        do_exclusive = mode & TASK_EXCLUSIVE; 

        while (next != head) { 

            p = next->task; 

            next = next->next; 

            if (p->state & mode) { 

                if (do_exclusive && p->task_exclusive) { 

                    if (best_exclusive == NULL) 

                        best_exclusive = p; 

                } 

                else { 

                    wake_up_process(p); 

                } 

            } 

        } 

        if (best_exclusive) 

            wake_up_process(best_exclusive); 

    out_unlock: 

        read_unlock(&waitqueue_lock); 

    out: 

        return; 

    } 

 

 

2. __wake_up的反彙編碼: 

    c0111094 <__wake_up>: 

    c0111094:   55                      pushl  %ebp 

    c0111095:   89 e5                   movl   %esp,%ebp 

    c0111097:   83 ec 08                subl   $0x8,%esp 

    c011109a:   57                      pushl  %edi 

    c011109b:   56                      pushl  %esi 

    c011109c:   53                      pushl  %ebx 

    c011109d:   89 55 fc                movl   %edx,0xfffffffc(%ebp) 

    c01110a0:   85 c0                   testl  %eax,%eax 

    c01110a2:   74 50                   je     c01110f4 <__wake_up+0x60> 

    c01110a4:   8d 48 fc                leal   0xfffffffc(%eax),%ecx 

    c01110a7:   89 4d f8                movl   %ecx,0xfffffff8(%ebp) 

    c01110aa:   8b 18                   movl   (%eax),%ebx 

    c01110ac:   85 db                   testl  %ebx,%ebx 

    c01110ae:   74 44                   je     c01110f4 <__wake_up+0x60> 

    c01110b0:   31 f6                   xorl   %esi,%esi 

    c01110b2:   89 d7                   movl   %edx,%edi 

    c01110b4:   83 e7 20                andl   $0x20,%edi 

    c01110b7:   39 cb                   cmpl   %ecx,%ebx 

    c01110b9:   74 2d                   je     c01110e8 <__wake_up+0x54> 

    c01110bb:   90                      nop 

    c01110bc:   8b 13                   movl   (%ebx),%edx 

    c01110be:   8b 5b 04                movl   0x4(%ebx),%ebx 

    c01110c1:   8b 02                   movl   (%edx),%eax 

    c01110c3:   85 45 fc                testl  %eax,0xfffffffc(%ebp) 

    c01110c6:   74 1b                   je     c01110e3 <__wake_up+0x4f> 

    c01110c8:   85 ff                   testl  %edi,%edi 

    c01110ca:   74 10                   je     c01110dc <__wake_up+0x48> 

    c01110cc:   83 7a 44 00             cmpl   $0x0,0x44(%edx) 

    c01110d0:   74 0a                   je     c01110dc <__wake_up+0x48> 

    c01110d2:   85 f6                   testl  %esi,%esi 

    c01110d4:   75 0d                   jne    c01110e3 <__wake_up+0x4f> 

    c01110d6:   89 d6                   movl   %edx,%esi 

    c01110d8:   eb 09                   jmp    c01110e3 <__wake_up+0x4f> 

    c01110da:   89 f6                   movl   %esi,%esi 

    c01110dc:   89 d0                   movl   %edx,%eax 

    c01110de:   e8 2d f9 ff ff          call   c0110a10 <wake_up_process> 

    c01110e3:   3b 5d f8                cmpl   0xfffffff8(%ebp),%ebx 

    c01110e6:   75 d4                   jne    c01110bc <__wake_up+0x28> 

    c01110e8:   85 f6                   testl  %esi,%esi 

    c01110ea:   74 08                   je     c01110f4 <__wake_up+0x60> 

    c01110ec:   89 f0                   movl   %esi,%eax 

    c01110ee:   e8 1d f9 ff ff          call   c0110a10 <wake_up_process> 

    c01110f3:   90                      nop 

    c01110f4:   8d 65 ec                leal   0xffffffec(%ebp),%esp 

    c01110f7:   5b                      popl   %ebx 

    c01110f8:   5e                      popl   %esi 

    c01110f9:   5f                      popl   %edi 

    c01110fa:   89 ec                   movl   %ebp,%esp 

    c01110fc:   5d                      popl   %ebp 

    c01110fd:   c3                      ret 

    c01110fe:   89 f6                   movl   %esi,%esi 

 

----------------------------------------------------------- 

內核驅動題 

以下設計應該包括設計文檔,實現策略說明,代碼包,測試用例,使用說明. 

要求:按照綜合編程題目的要求編寫代碼和文檔。 

參考資料: <Linux設備驅動程序>第二版. 

 

1.設計並實現一個軟件watchdog設備,以監視系統運行情況.(50分) 

說明:watchdog設備用於監測系統運行狀態,正常運行的系統定期寫watchdog以使其 

不會超時,一旦超時,意味系統已掛起;watchdog應該重啓系統. 現在的軟件watchdog 

不重啓系統,只用於監視應用程序的運行. 

 

2.設計並實現一個簡化的、容量可以變化的內存FIFO設備.(50分) 

 

八、用中文Linux辦公。 

要求本考卷完全在Linux完成,並要求進行版面的格式化或美化。如果只提交TEXT版本,  

本題不得分。(各10分) 

本題要求是: 

1、提交進行版面的格式化或美化的PDF版本。爲方便修改和評分,還須提交一個lyx或te 

 

x版本。 

2、PDF內嵌的中文字體使用的是紅旗桌面版4.0所攜帶的新版宋體。 

 

九、娛樂。(沒有分數) 

不會娛樂的程序員不是好的程序員。本部分沒有分數,但是聰明的人在這裏是不會留下空白的。 

1、運行RedHat 7.3上面的推箱子游戲。用方向-數字的方式(如左3,右4)記錄下通過第一關 

的過程,同時記錄下過關的時間。看誰的步數少,時間短。 

2、運行emacs + doctor遊戲。摘錄下10句以上的對話,看誰的對話最精彩,同時也看誰的心理最變態。

************************************

 

答案

************************************

 

這部分是ANSI C的一些問題,題目的前提是必須都答對,看似很變態,但是細想一下,這些都是最基礎的,雖然我們在使用他們的

 

時候會犯這樣那樣的錯誤,但是最終目的是不犯錯誤,不是麼,那麼好,從最基礎的開始。

 

1、 如何在C中初始化一個字符數組。

這個問題看似很簡單,但是我們要將最簡單的問題用最嚴謹的態度來對待。關鍵的地方:初始化、字符型、數組。最簡單的方法是

 

char array[];。這個問題看似解決了,但是在初始化上好像還欠缺點什麼,個人認爲:char array[5]={'1','2','3','4','5'};

 

或者char array[5]={"12345"};或者char array[2][10]={"China","Beijing"};也許更符合“初始化”的意思。

 

2、 如何在C中爲一個數組分配空間。

最簡單的方法是:char array[5];意思是分配給數組array一個5個字節的空間。但是我們要知道在C中數組其實就是一個名字,其

 

實質含義就是指針,比如char array[];是到底分配的多少空間?所以我們要將其分成爲兩種不同的形式給出答案:

一種是棧的形式:char array[5];

一種是堆的形式:char *array; array=(char *)malloc(5);//C++: array=new char[5];

堆和棧的含義其實我也沒弄太透徹,改天明白了再發一篇。

我們要明白的是,第一種形式空間分配的大小可能會受操作系統的限制,比如windows會限制在2M;第二種形式成空間分配很靈活,

 

想分配多少分配多少,只要RAM夠大。

 

3、 如何初始化一個指針數組。

首先明確一個概念,就是指向數組的指針,和存放指針的數組。

指向數組的指針:char (*array)[5];含義是一個指向存放5個字符的數組的指針。

存放指針的數組:char *array[5];含義是一個數組中存放了5個指向字符型數據的指針。

按照題意,我理解爲初始化一個存放指針的數組,char *array[2]={"China","Beijing"};其含義是初始化了一個有兩個指向字符

 

型數據的指針的數組,這兩個指針分別指向字符串"China"和"Beijing"。

 

4、如何定義一個有10個元素的整數型指針數組。

既然只是定義而不是初始化,那就很簡單且沒有爭議了:int *array[10];。

 

5、 s[10]的另外一種表達方式是什麼。

前面說過了,數組和指針其實是數據存在形態的兩種表現形式,如果說對於數組s[],我們知道*s=s[0],那麼s[10]的另一種表達

 

方式就是:*(s+10)。

 

6、 GCC3.2.2版本中支持哪幾種編程語言。

這個問題實在變態,就像問你#error的作用是什麼一樣。不可否認,gcc是linux下一個亮點,是一個備受無數程序員推崇的編譯器

 

,其優點省略1000字,有興趣可以自己查,我翻了翻書,書上曰:支持C,C++,Java,Obj-C,Ada,Fortran,Pascal,Modula-3等語言,

 

這個“等”比較要命,不過我認爲已經很全了,如果認爲還是不全,乾脆把ASM也加上算了,不過那已經不算是編譯了。

 

7、 要使用CHAR_BIT需要包含哪個頭文件。

如果結合上面的問題,答題的人估計會認爲自己撞鬼了,這個問題實在是……搜索了一下,應該是limits.h。

 

8、 對(-1.2345)取整是多少?

其實不同的取整函數可能有不同的結果,不過這個數沒有太大的爭議,答案是-1。

 

9、 如何讓局部變量具有全局生命期。

具體的生命期的概念我覺得我還要好好深入的學習一下,但是這個題目還算比較簡單,即用static修飾就可以了,但是隻是生命期

 

延長,範圍並沒有擴大,除非把這個變量定義在函數體外的靜態區,不過那樣就變成全局變量了,彷彿不符合題目要求。

 

10、C中的常量字符串應在何時定義?

這個問題說實話不是很理解題乾的意思,據我理解,有兩種情況,一種是預處理階段,用#define定義;還有就是使用const修飾詞

 

,不過const修飾的是一個變量,其含義是“只讀”,稱之爲常量並不準確,但是確實可以用操作變量的方法當常量用。所以還是

 

第一種比較靠譜。

 

11、如何在兩個.c文件中引用對方的變量。

這個問題也問的挺含糊的,怎麼說呢,最簡單最直接的方法是爲變量添加extern修飾詞,當然,這個變量必須是全局變量。還有一

 

種就是利用函數調用來進行變量的間接引用,比如這個C文件中的一個函數引用另外一個C中的函數,將變量通過實參的形式傳遞過

 

去。不過題目既然說是引用,那麼還是用第一個答案好了。

 

12、使用malloc之前需要做什麼準備工作。

其實準備工作很多啊,比如你需要一臺計算機之類的。玩笑話,我們首先要知道malloc的用途,簡單的說就是動態的分配一段空間

 

,返回這段空間的頭指針。實際的準備工作可以這麼分:需要這段空間的指針是否存在,若不存在,則定義一個指針用來被賦值,

 

還要清楚要返回一個什麼類型的指針,分配的空間是否合理;如果指針已經存在,那麼在重新將新的空間頭地址賦值給這個指針之

 

前,要先判斷指針是否爲NULL,如果不是要free一下,否則原來的空間就會被浪費,或者出錯,free之後就按照前一種情形考慮就

 

可以了。

 

13、realloc函數在使用上要注意什麼問題。

這個函數我也才知道的,汗一個。據我的初步理解,這個函數的作用是重新分配空間大小,返回的頭指針不變,只是改變空間大小

 

。既然是改變,就有變大、變小和爲什麼改變的問題。變大,要注意不能大到內存溢出;變小,那變小的那部分空間會被徵用,原

 

有數據不再存在;爲什麼改變,如果是想重新挪作他用,還是先free了吧。

 

14、strtok函數在使用上要注意什麼問題。

這個問題我不知道能不能回答全面,因爲實在是用的很少。這個函數的作用是分割字符串,但是要分割的字符串不能是常量,這是

 

要注意的。比如先定義一個字符串:char array[]="part1,part2";,strtok的原形是char *strtok(char *string, char 

 

*delim);,我們將","作爲分隔符,先用pt=strtok(array,",");,得到的結果print出來就是"part1",那後面的呢,要寫成

 

pt=strtok(NULL,",");,注意,要用NULL,如果被分割的字符串會被分成N段,那從第二次開始就一直要用NULL。總結起來,需要

 

注意的是:被分割的字符串和分隔符都要使用變量;除第一次使用指向字符串的指針外,之後的都要使用NULL;注意使用這個函數

 

的時候千萬別把指針跟丟了,不然就全亂了。

 

15、gets函數在使用上要注意什麼問題。

這是一個鍵盤輸入函數,將輸入字符串的頭地址返回。說到要注意的問題,我還是先查了一下網上的一些情況,需要注意的就是

 

gets以輸入回車結束,這個地球人都知道,但是很多人不知道的是,當你輸入完一個字符串後,這個字符串可能依然存在於這個標

 

準輸入流之中,當再次使用gets的時候,也許會把上次輸入的東西讀出來,所以應該在使用之後用fflush(stdin);處理一下,將輸

 

入流清空。最後也還是要注意溢出的問題。關於這個答案我比較含糊,不知道有沒有高人高見?

 

16、C語言的詞法分析在長度規則方面採用的是什麼策略?

我無語……聞所未聞啊……還是搜索了一下,有一篇文章,地址是:

 

http://202.117.80.9/jp2005/20/kcwz/wlkc/wlkc/03/3_5_2.htm,是關於詞法分析器的。其中提到了兩點策略: (1) 按最長匹配

 

原則確定被選的詞型;(2) 如果一個字符串能爲若干個詞型匹配,則排列在最前面的詞型被選中。不知道是不是題乾的要求,還是

 

其他什麼。我乃一介草民,望達人指點迷津!

 

17、a+++++b所表示的是什麼意思?有什麼問題?

這個東西(稱之爲東西一點都不過分)其實並沒有語法錯誤,按照C對運算符等級的劃分,++的優先級大於+,那麼這句話會被編譯

 

器看做:(a++)+(++b),這回明白了吧。有什麼問題,語法上沒有問題,有的是道德上的問題!作爲一個優秀的程序員,我們要力

 

求語句的合法性和可讀性,如果寫這句的人是在一個team裏,那麼他基本會被打的半死……最後討論一下結果:假設a之前的值是3

 

,b是4,那麼運行完這個變態語句後,a的值是4,b是5,語句的結果是8。

 

18、如何定義Bool變量的TRUE和FALSE的值。

不知道這個題有什麼陷阱,寫到現在神經已經大了,一般來說先要把TURE和FALSE給定義了,使用#define就可以:

#define TURE 1

#define FALSE 0

如果有一個變量需要定義成bool型的,舉個例子:bool a=TURE;就可以了。

 

19、C語言的const的含義是什麼。在定義常量時,爲什麼推薦使用const,而不是#define。

首先,這個題幹抽了10題回答的一個大嘴巴。關於常量的概念看來我要好好看看書了……我說過了,const修飾詞可以將一個變量

 

修飾爲“只讀”,這個就能稱爲常量麼?姑且認爲可以。回到題目中,const是隻讀的意思,它限定一個變量不允許被改變,誰都

 

不能改!既然是修飾變量,那麼變量的類型就可以豐富多彩,int啊,char啊,只要C認識的都可以;但是#define就不可以了,在

 

預處理階段缺乏類型檢測機制,有可能會出錯。還有就是變量可以extern,但是#define就不可以。貌似const還可以節省RAM,這

 

個我倒是沒有考證過。至於const的用法和作用,有很多,我會總結後發上來。

 

20、C語言的volatile的含義是什麼。使用時會對編譯器有什麼暗示。

終於最後一題了,容易麼……如果這個測試是一個關於嵌入式的,那麼這道題非常重要!!從詞面上講,volatile的意思是易變的

 

,也就是說,在程序運行過程中,有一些變量可能會被莫名其妙的改變,而優化器爲了節約時間,有時候不會重讀這個變量的真實

 

值,而是去讀在寄存器的備份,這樣的話,這個變量的真實值反而被優化器給“優化”掉了,用時髦的詞說就是被“和諧”了。如

 

果使用了這個修飾詞,就是通知編譯器別犯懶,老老實實去重新讀一遍!可能我說的太“通俗”了,那麼我引用一下“大師”的標

 

準解釋:

volatile的本意是“易變的” 。

由於訪問寄存器的速度要快過RAM,所以編譯器一般都會作減少存取外部RAM的優化,但有可能會讀髒數據。當要求使用volatile 聲

 

明的變量的值的時候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據。而且讀取的數據立刻被

 

保存。

精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器裏的備份。

下面是volatile變量的幾個例子:

1). 並行設備的硬件寄存器(如:狀態寄存器)

2). 一箇中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)

3). 多線程應用中被幾個任務共享的變量

嵌入式系統程序員經常同硬件、中斷、RTOS等等打交道,所用這些都要求volatile變量。不懂得volatile內容將會帶來災難。

....

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章