1.預處理命令#define
#define SECONDS_PER_YEAR (60*60*24*365)UL
(因為數值超過65535,產生溢出,因此需要用到長整型,而且不會是負數,所以使用無符號整型UL)
2.死循環的方案(3種)
a:while(1){循環體}
b:for(;;){循環體}
c:Loop:循環體 goto Loop
3.變量定義
a:一個整型
b:一個指向整型的指針
c:一個指向指針的指針
d:一個指向10個整型數的數組
e:一個指向有10個整型指針的數組
f:一個指向有10個整型數數組的指針
g:一個指向函數的指針,該函數有一個整型參數並返回一個整型數
h:一個有10個指針的數組,該指針指向一個函數,該函數有一個整型參數並返回一個整型數
答案:
1 a) int a; 2 b) int *a; 3 c) int **a; 4 d) int a[10]; 5 e) int *a[10]; 6 f) int (*a)[10]; 7 g) int (*a)(int); 8 h) int (*a[10])(int);
4.關鍵字static的三個明顯作用
a:在函數體,一個被聲明為靜態的變量在這一函數被調用過程中維持其值不變。
b:在模塊內(但在函數體外),一個被聲明為靜態的變量可以被模塊內所用函數訪問,但不能被模塊外其它函數訪問。它是一個本地的全局變量。
c:在模塊內,一個被聲明為靜態的函數只可被這一模塊內的其它函數調用。那就是,這個函數被限制在聲明它的模塊的本地范圍內使用。
5.關鍵字const的含義:意味着該變量是一個“只讀”變量,別說是常數
a:Const int a; a是一個常整型數
b:int const a; a是一個常整型數
c:const int *a; a是一個指向常整型數的指針(整型數是不可修改的,但指針可以)
d:int * const a; a是一個指向整型數的常指針(指針指向的整型數是可以修改的,但指針是不可修改的)
e:int const * a const; a是一個指向常整型數的常指針(指針指向的整型數是不可修改的,同時指針也是不可修改的)
6.關鍵字volatile
一個定義為volatile的變量是說這變量可能會被意想不到地改變,這樣,編譯器就不會去假設這個變量的值了。精確地說就是,優化器在用到這個變量時必須每次都小心地重新讀取這個變量的值,而不是使用保存在寄存器里的備份。
volatile變量的幾個例子:
1). 並行設備的硬件寄存器(如:狀態寄存器)
2). 一個中斷服務子程序中會訪問到的非自動變量(Non-automatic variables)
3). 多線程應用中被幾個任務共享的變量
一個參數既可以是const還可以是volatile,一個例子是只讀的狀態寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它
7.對變量或者對寄存器進行位操作:
寫兩段代碼:第一段代碼進行置位操作:(寄存器)的bit3,第二段代碼進行清位操作:(寄存器)的bit3
1 #define BIT3 (0x1<<3) 2 static int a; 3 void set_bit3(void) 4 { 5 a |= BIT3; 6 } 7 void clear_bit3(void) 8 { 9 a &= ~BIT3; 10 }
8.設置一絕對地址為0x67a9的整型變量的值為0xaa66,編譯器是一個純粹的ANSI編譯器
1 int *ptr; 2 ptr = (int *)0x67a9; 3 *ptr = 0xaa55;
9.關鍵字_interrupt
中斷是嵌入式系統中重要的組成部分,ISP(中斷服務子程序) 注意點:
a:ISR 不能返回一個值
b:ISR 不能傳遞參數
c:在許多的處理器/編譯器中,浮點一般都是不可重入的,ISR應該是短而有效率的,在ISR中做浮點運算是不明智的。
d:與第三點一脈相承,printf()經常有重入和性能上的問題
10.C語言中的整數自動轉換原則
當表達式中存在有符號類型和無符號類型時所有的操作數都自動轉換為無符號類型
1 Void foo(void) 2 { 3 unsigned int a = 6; 4 int b = -20; 5 (a+b > 6) puts("> 6") : puts("<= 6"); 6 }
11.注意
1 unsigned int zero = 0; 2 unsigned int compzero = 0xFFFF; 3 /*1's complement of zero */ 4 5 對於一個int型不是16位的處理器為說,上面的代碼是不正確的。應編寫如下: 6 7 unsigned int compzero = ~0;
12.分析
1 Char *ptr; 2 if ((ptr = (char *)malloc(0)) == NULL) 3 puts(“Got a null pointer”); 4 else 5 puts(“Got a valid pointer”); 6 7 代碼的輸出是“Got a valid pointer
13.typedef和define在C語言中頻繁用以聲明一個已經存在的數據類型的同義字(別名)
假設目的要定義dPS 和 tPS 都是一個指向結構s指針
1 #define dPS struct s * 2 typedef struct s * tPS; 3 4 dPS p1,p2; 5 tPS p3,p4; 6 7 第一個擴展為: 8 struct s * p1, p2;
上面的代碼定義p1為一個指向結構的指針,p2為一個實際的結構,顯然錯誤了。第二個例子正確地定義了p3 和p4 兩個指針。
14.編程風格問題
1 Int a = 5, b = 7, c; 2 c = a+++b;
實際為:c = a++ + b
程序運行后結果為:a = 6、b = 7、c = 12
15.static有什么用途
16.引用與指針有什么區別
1) 引用必須被初始化,指針不必。
2) 引用初始化以后不能被改變,指針可以改變所指的對象。
3) 不存在指向空值的引用,但是存在指向空值的指針。
17.描述實時系統的基本特征
在特定時間內完成特定的任務,實時性與可靠性
18.全局變量和局部變量在內存中有什么區別
19.什么是平衡二叉樹
20.冒泡排序的時間復雜度
O(n^2)
21.寫出float x 與 “零值” 比較的if語句
if(x>-0.000001 && x<0.000001)
22.Internet采用哪種網絡協議?該協議的主要層次結構
TCP/IP:應用層/傳輸層/網絡層/數據鏈路層/物理層
23.Internet物理地址和IP地址轉換采用什么協議
ARP協議(Address Resolution Protocol):地址解析協議
24.IP地址的編碼分為哪兩部分
網絡號和主機號
25.局部變量能否和全局變量重名
26.如何引用一個已經定義過的全局變量
在變量前面加上 extern
27.語句for(;1;)有什么問題?它是什么意思
while(1)
28.static函數/全局變量/局部變量 與 普通的函數/全局變量/局部變量有什么區別
29.程序的局部變量存在於(堆棧)中,全局變量存在於(靜態區 )中,動態申請數據存在於( 堆)中
30.隊列和棧的區別
隊列:先進先出 棧:后進先出
堆棧溢出一般原因:1.沒有回收垃圾資源 2.層次太深的遞歸調用
31.對於一個頻繁使用的短小函數,在C語言中應用什么實現,在C++中應用什么實現
C語言:宏定義
C++:inline(內聯函數):必須定義在頭文件中
32.進程和線程的差別
線程:是進程內的一個執行單元,也是進程內的可調度實體
33.測試方法
人工測試:個人復查、抽查和會審
機器測試:黑盒測試/白盒測試
黑盒測試和白盒測試,二者最大的區別應該是測試時關注的對象不同
黑盒測試:主要針對的是程序展現給用戶的功能(測試功能)
白盒測試:主要針對的是程序的代碼邏輯(測試后台程序)
34.Heap與stack的差別
heap:堆 手動分配空間/釋放空間 空間較大
stack:棧 系統自動分配空間/釋放空間 空間有限
35.用宏定義寫出swap(x,y)
#define swap(x, y) (x=x+y;y=x-y;x=x-y;)
36.數組a[N],存放了1至N-1個數,其中某個數重復一次。寫一個函數,找出被重復的數字.時間復雜度必須為o(N)函數原型
37.一語句實現x是否為2的若干次冪的判斷
(x&(x-1))? flase:true
38.sizeof如用於數組,只能測出靜態數組的大小,無法檢測動態分配的或外部數組大小
39.一個32位的機器,該機器的指針是多少字節
指針是多少字節,只要看該機器的數據總線的位數,若為32位數據總線,則指針就為4字節
40.c和c++中的struct有什么不同
C中的struct不可以含有成員函數
C++中權限權限 struct(public)和class(private)
41.已知一個數組table,用一個宏定義,求出數據的元素個數
#define KST (sizeof(table)/sizeof(table[0]))
42.線程與進程的區別和聯系? 線程是否具有相同的堆棧? dll是否有獨立的堆棧?
43.寫一個“標准”宏,這個宏輸入兩個參數並返回較小的一個
#define Min(X, Y) ((X)>(Y)?(Y):(X)) // 結尾沒有;
44.寫一個標准的宏定義:返回兩個數中較小的一個
#define MIN(A, B) ((A) <= (B)?(A): (B))) // 參數要用括號括起來
45. sizeof和strlen的區別
sizeof()是運算符,編譯時就已經計算好了,而strlen()是函數,要在運行時才能計算
46.PWM:脈沖寬度調制
47.STM32F107的集成A/D的特性輸入:輸入范圍:VREF-≤VIN≤VREF+
48.程序的局部變量存在於哪里,全局變量存在於哪里,動態申請數據存在於哪里。
程序的局部變量存在於棧區;
全局變量存在於靜態區;
動態申請數據存在於堆區。
49.進程之間通信的途徑有哪些
1.無名管道
2.高級管道
3.有名管道
4.消息隊列
5.信息量
6.信號
7.共享內存
8.套接字
50.死鎖:多個並發進程因爭奪系統資源而產生相互等待的現象
本質原因:1.系統資源有限 2.進程推進順序不合理
51.進程與線程
18.進程和線程有什么區別?
答:進程是並發執行的程序在執行過程中分配和管理資源的基本單位。線程是進程的一個執行單元,是比進程還要小的獨立運行的基本單位。一個程序至少有一個進程,一個進程至少有一個線程。兩者的區別主要有以下幾個方面:
1. 進程是資源分配的最小單位。
2. 線程是程序執行的最小單位,也是處理器調度的基本單位,但進程不是,兩者均可並發執行。
3. 進程有自己的獨立地址空間,每啟動一個進程,系統就會為它分配地址空間,建立數據表來維護代碼段、堆棧段和數據段,這種操作非常昂貴。而線程是共享進程中的數據,使用相同的地址空間,因此,CPU切換一個線程的花費遠比進程小很多,同時創建一個線程的開銷也比進程小很多。
4. 線程之間的通信更方便,同一進程下的線程共享全局變量、靜態變量等數據,而進程之間的通信需要以通信的方式(IPC)進行。不過如何處理好同步與互斥是編寫多線程程序的難點。但是多進程程序更健壯,多線程程序只要有一個線程死掉,整個進程也跟着死掉了,而一個進程死掉並不會對另外一個進程造成影響,因為進程有自己獨立的地址空間。
5. 進程切換時,消耗的資源大,效率低。所以涉及到頻繁的切換時,使用線程要好於進程。同樣如果要求同時進行並且又要共享某些變量的並發操作,只能用線程不能用進程。
6. 執行過程:每個獨立的進程有一個程序運行的入口、順序執行序列和程序入口。但是線程不能獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
優缺點:
線程執行開銷小,但是不利於資源的管理和保護。線程適合在SMP機器(雙CPU系統)上運行。
進程執行開銷大,但是能夠很好的進行資源管理和保護,可以跨機器遷移。
何時使用多進程,何時使用多線程?
對資源的管理和保護要求高,不限制開銷和效率時,使用多進程。
要求效率高,頻繁切換時,資源的保護管理要求不是很高時,使用多線程。
52.TCP和UDP的區別
答:TCP和UDP是OSI模型中的運輸層中的協議。TCP提供可靠的通信傳輸,而UDP則常被用於廣播和細節控制交給應用的通信傳輸,兩者主要的不同體現在一下幾個方面:
1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的,即發送數據之前不需要建立連接
2、TCP提供可靠的服務。它通過校驗和,丟包時的重傳控制,序號標識,滑動窗口、確認應答,次序亂掉的分包進行順序控制實現可靠傳輸。即通過TCP連接傳送的數據,無差錯,不丟失,不重復,且按序到達; UDP盡最大努力交付,即不保證可靠交付。
3、UDP具有較好的實時性,工作效率比TCP高,適用於對高速傳輸和實時性有較高要求的通信或廣播通信場景。
4、每一條TCP連接只能是點到點的; UDP支持一對一,一對多,多對一和多對多的交互通信方式。
5、TCP對系統資源要求較多,UDP對系統資源要求較少。
UDP有時比TCP更有優勢:
UDP以其簡單、傳輸快的優勢,在越來越多場景下取代了TCP, 如實時游戲。
(1)網速的提升給UDP的穩定性提供可靠網絡保障,丟包率很低,如果使用應用層重傳,能夠確保傳輸的可靠性。
(2)TCP為了實現網絡通信的可靠性,使用了復雜的擁塞控制算法,建立了繁瑣的握手過程,由於TCP在內置的系統協議棧中,極難對其進行改進。
采用TCP,一旦發生丟包,TCP會將后續的包緩存起來,等前面的包重傳並接收到后再繼續發送,延時會越來越大。
基於UDP對實時性要求較為嚴格的情況下,采用自定義重傳機制,能夠把丟包產生的延遲降到最低,盡量減少網絡問題造成的影響。
53.線程是否具有相同的堆棧
答:真正的程序執行都是線程來完成的,程序啟動的時候操作系統就幫你創建了一個主線程。
每個線程有自己的堆棧。
54..h頭文件中的#ifndef/#define/endif
防止該頭文件被重復引用
55.#include<stdio.h>和#include"stdio.h"的區別
前者是從Standard Library(標准庫)的路徑尋找和引用stdio.h, 后者是從當前用戶的工作路徑搜索並引用stdio.h
56.程序的內存分配:
1、棧區(stack):由編譯器自動分配釋放,存放函數的參數值,局部變量的值等。其操作方式類似於數據結構中的棧。
2、堆區(heap):一般由程序員分配釋放,若程序員不釋放,程序結束時可能由OS回收。
注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表,呵呵。
3、全局區(靜態區):(static)全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域,未初始化的全局變量和未初始化的靜 態變量在相鄰的另一塊區域。程序結束后由系統釋放。
4、文字常量區:常量字符串就是放在這里的。程序結束后由系統釋放。
5、程序代碼區:存放函數體的二進制代碼
57.聯合體union所占內存的計算方式
1 union U 2 { 3 char s[9]; 4 int n; 5 double d; 6 };
系統采用覆蓋技術,共用體變量中起作用的成員是最后一次存放的成員,在存入一個新的成員后原有的成員就失去作用
s占9字節,n占4字節,d占8字節,因此其至少需9字節的空間。
然而其實際大小並不是9,用運算符sizeof測試其大小為16.
這是因為這里存在字節對齊的問題,9既不能被4整除,也不能被8整除。因此補充字節到16,這樣就符合所有成員的自身對齊了。
從這里可以看出聯合體所占的空間不僅取決於最寬成員,還跟所有成員有關系,即其大小必須滿足兩個條件:
1)大小足夠容納最寬的成員;
2)大小能被其包含的所有基本數據類型的大小所整除。
58.32位、64位編譯器各類型大小和字節對齊
| 編譯器 | 32位 | 64位 |
| char | 1字節 | 1字節 |
| char* void*(指針都一樣) | 4字節 | 8字節 |
| short int | 2字節 | 2字節 |
| int | 4字節 | 4字節 |
| unsigned int | 4字節 | 4字節 |
| float | 4字節 | 4字節 |
| double | 8字節 | 8字節 |
| long | 4字節 | 8字節 |
| longlong | 8字節 | 8字節 |
| unsigned long | 4字節 | 8字節 |
59.ifndef/define/endif的作用
主要用於防止頭文件的重復包含和編譯
60.一個數組名代表的含義是數組中第一個元素的位置,即地址
61.靜態變量和全局變量的區別
靜態變量:靜態存儲區,被static關鍵字修飾過的變量具有文件作用域,只可以用於定義它的函數或者文件中
全局變量:靜態存儲區,可以被文件外的extern關鍵字調用
局部變量:棧
62.函數的定義和聲明
定義:是為變量分配存儲空間,還可以為變量指定初始值 需要申請存儲空間
聲明:是為程序表明變量的類型和名字 不需要申請存儲空間
63.面向對象的基本特征:封裝、繼承、多態
封裝:封裝是指將客觀事物抽象成類,每個類對自身的數據和方法進行保護。類可以把自己的數據和方法只讓可信的類或者對象操作,對不可信的進行信息隱藏,C++中,類是一種封裝手段,采用類來描述客觀事物的過程就是封裝,本質上是對客觀事物的抽象。
繼承:繼承是指可以使用現有類的所有功能,而不需要重新編寫原來的類,它的目的是為了進行代碼復用和支持多態。它一般有3種形式:實現繼承、可視繼承、接口繼承。
多態:多態是指同一個實體同時具有多種形式,它主要體現在類的繼承體系中,它是將父對象設置成為和一個或更多的它的子對象相等的技術,賦值以后,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作,簡單的說:就是允許將子對象的指針賦值給父類類型的指針,在運行時根據具體指向對象的類型來調用對應類。
64.排序算法

65.
66.
67.
68.
69.
70.
