C/C++ - 常見C 語言觀念題目總整理(適合考試和面試)
文章推薦指數: 80 %
標籤: Software Development-C/Cpp. 常見的C/C++ 問題總整理,增強C 語言觀念並練習一些題目,努力脫離考試苦海吧! (非從零開始,適合稍有C/C++ ...
Pages
Home
About
Contact
skiptomain|
skiptosidebar
2017年8月7日星期一
C/C++-常見C語言觀念題目總整理(適合考試和面試)
於
8/07/201704:56:00下午
標籤:
SoftwareDevelopment-C/Cpp
常見的C/C++問題總整理,增強C語言觀念並練習一些題目,努力脫離考試苦海吧!
(非從零開始,適合稍有C/C++基礎的人閱讀。
)
2017.08.07初版
2018.01.28新增部分內容
一、指標
指標(pointer):一個指向某個儲存位址的變數,語法為
int*ptr=&var;
其中
&:取變數位址
*:表示為指標變數
也可用於函數變為函式指標(functionpointer),語法為
void(*fptr)(type_a,type_b)=&func;
常用的地方如下
函式sort時傳入判斷準則
multithread傳函數進入建立thread的API中
callbackfunction(一種事件導向的函式)
1.基礎指標判讀
指標判讀大原則為「從右讀到左」,例如:
inta;//一個整型數
int*a;//一個指向整數的指標
int**a;//一個指向指標的指標,它指向的指標是指向一個整型數
inta[10];//一個有10個整數型的陣列
int*a[10];//一個有10個指標的陣列,該指標是指向一個整數型的
int(*a)[10];//一個指向有10個整數型陣列的指標
int(*a)(int);//一個指向函數的指標,該函數有一個整數型參數並返回一個整數
int(*a[10])(int);//一個有10個指標的陣列,該指標指向一個函數,該函數有一個整數型參數並返回一個整數
注意宣告兩個指標時不能寫做int*a,b;因為前式等價於int*a;intb;。
連續宣告兩個指標用int*a,*b;
2.指標與其他關鍵字混用
一樣右讀到左,例如:
constint*foo;//一個pointer,指向constint變數。
intconst*foo;//一個pointer,指向constint變數。
int*constfoo;//一個constpointer,指向int變數。
intconst*constfoo;//一個constpointer,指向constint變數。
關鍵字volatile等等判讀方式相同。
二、callbyvalue,callbyreference
1.callbyvalue:最常見的函式寫法,呼叫者和被呼叫者的變數各自佔有記憶體,將參數複製再傳給函式。
2.callbyreference:呼叫者和被呼叫者的變數使用相同的記憶體位址,因此在被呼叫函式中改變變數時,變動結果會保留。
(C++才有,寫法為typefunc(type&var){...})
[用心去感覺]callbyaddress(?)
C語言之父明確表示C語言只有callbyvalue。
坊間有callbyaddress的說法其實是方便教學,指的是對指標變數進行操作的callbyvalue,具體的執行效果和callbyreference一樣。
下面兩篇文章對這個觀念講得很清楚:
MLab-什麼是傳值callbyvalue、傳址callbyaddress、傳參考callbyreference
http://wp.mlab.tw/?p=176
郭晉魁教授-c語言有沒有callbyreference(orcallbyaddress)?
http://eportfolio.lib.ksu.edu.tw/~T093000170/blog?node=000000119
三、變數範圍和生命周期(關鍵字static)
1.local變數:local變數僅活在該函式內,存放位置在stack或heap記憶體中。
2.static變數:static變數生命周期(lifetime)跟程式一樣長,而範圍(scope)則維持不變,即在宣告的函式之外仍無法存取static變數。
3.global變數:所有區段皆可使用此變數。
[用心去感覺]staticvsglobal
除了範圍不同,static變數只有宣告的檔案可以使用;而global變數可加上extern關鍵字修飾,即可在其他檔案以.h標頭檔方式使用該變數(也就是internallinkage和externallinkage的不同)。
[用心去感覺]記憶體的配置
Stack:存放函數的參數、區域變數等,由空間配置系統自行產生與回收。
(會稱作stack是由於其配置遵守LIFO)
Heap:一般由程式設計師分配釋放,執行時才會知道配置大小,如malloc/new和free/delete。
(注意其資料結構不是DS中的heap而是link-list)
Global : 包含 BSS(未初始化的靜態變數)、datasection(全域變數、靜態變數)和text/code(常數字元)。
[重要!]process在記憶體中的配置圖
[例題]配置練習
inta=0;//global初始化區
char*p1;//global未初始化區
main(){
intb;//stack
chars[]="abc";//stack
char*p2;//stack
char*p3="123456";//123456\0在常量區,p3在stack。
staticintc=0;//global(static)初始化區
p1=(char*)malloc(10);
p2=(char*)malloc(20);//分配得來得10和20位元組的區域在heap
strcpy(p1,"123456");
//123456\0在常量區,編譯器可能會將它與p3中的123456\0優化成一個地方。
}
[例題]static練習
staticintnum_a;
//專屬於整個檔案的全域變數,其他檔案不能存取
voidfunc(intnum_b){//stack區
intnum_c;//stack區
staticintnum_d;
//scope不變,只能在函數func內呼叫,但lifetime是整支程式執行的時間。
}
四、關鍵字const
const通常表示只可讀取不可寫入的變數,常用來宣告常數。
使用const有以下好處:
提升程式碼可讀性
使編譯器保護那些不希望被改變的參數
給優化器一些附加的資訊
[用心去感覺]constvs#define
編譯器處理方式:define在預處理階段展開;const在編譯階段使用。
類型和安全檢查:const會在編譯階段會執行類型檢查,define則不會。
存儲方式:define直接展開不會分配記憶體,const則會在記憶體中分配。
五、關鍵字volatile
由於嵌入式系統常處理I/O、中斷、即時操作系統(RTOS)相關的問題,因此在嵌入式系統開發中volatile尤為重要。
被volatile修飾的變數代表它可能會被不預期的更新,因此告知編譯器不對它涉及的地方做最佳化,並在每次操作它的時候都讀取該變數實體位址上最新的值,而不是讀取暫存器的值。
volatile常見的應用:
修飾中斷處理程式中(ISR)中可能被修改的全域變數。
修飾多執行緒(multi-threaded)的全域變數。
設備的硬體暫存器(如狀態暫存器)
[用心去感覺]const和volatile合用
externconstvolatileunsignedintrt_clock;
這是在RTOSkernel常見的一種宣告:rt_clock通常是指系統時鐘,它經常被時鐘中斷進行更新。
所以它是volatile。
因此在用的時候,要讓編譯器每次從記憶體裡面取值。
而rt_clock通常只有一個寫者(時鐘中斷),其他地方對其的使用通常都是唯讀的。
所以將其聲明為const,表示這裏不應該修改這個變數。
所以volatile和const是兩個不矛盾的東西,並且一個物件同時具備這兩種屬性也是有實際意義的。
六、關鍵字inline
inline可以將修飾的函式設為行內函式,即像巨集(define)一樣將該函式展開編譯,用來加速執行速度。
inline和#define的差別在於:
inline函數只對參數進行一次計算,避免了部分巨集易產生的錯誤。
inline函數的參數類型被檢查,並進行必要的型態轉換。
巨集定義盡量不使用於複雜的函數
用inline後編譯器不一定會實作,僅為建議。
七、前處理器相關
前處理器主要處理加入檔案#include、巨集定義#define和#undef條件編譯。
1.巨集#define
#define是巨集,在前置處理器(preprocessor)執行時處理,將要替換的程式碼展開做文字替換。
define語法範例如下:
#definePI3.1415926//常數巨集
#defineA(x)x//函數巨集
#defineMIN(A,B)((A)<=(B)?(A):(B))
注意把參數用括號括起來,不然容易發生以下錯誤:
#defineSUM(a,b)a+b
當SUM(2,5)*10時,因為沒有括弧先乘除後加減,得輸出為52,錯誤。
2.引入防護和條件編譯
引入防護(Includeguard)是一種條件編譯,用於防範#include指令重複引入的問題。
/*避免重複引入*/
#ifndefMYHEADER
#defineMYHEADER
...
#endif
第一次被引入時會定義巨集MYHEADER,再次引入時判斷#ifndef測試失敗,因此編譯器會直接跳到#endif,由此避免了重複引用。
另有非標準的指令#pragmaonce提供相同效果,但由於可攜性不如上例,因此大多時候還是上面提到的方法為主。
條件編譯還有一些其它應用:
/*若前處理器已經defineMYHEADER,就編譯partA,否則編譯partB。
*/
#ifdefMYHEADER
#defineMYHEADER
//partA
#else
//partB
#endif
/*DEBUGflag*/
#ifdefDEBUG
print("device_open(%p)",file);
#endif
八、bitwiseoperator
邏輯上的運算子在C中的語法分別如下:
AND(&)
OR(|)
NOT(!)
XOR(^)//bit值不一樣為1
complement(~)
shift(<>)
bitwise的操作常與"0x"這種16進位表示法,方便轉換操作。
[例題]基本運算
unsignedlongnum_a=0x00001111;
unsignedlongnum_b=0x00000202;
unsignedlongnum_c;
num_c=num_a&(~num_b);
num_c=num_c|num_b;
printf("%lx",num_c);//00001313
[例題]mask方法做bitwise操作
a=a|7//最右側3位設為1,其餘不變。
a=a&(~7)//最右側3位設為0,其餘不變。
a=a^7//最右側3位執行NOToperator,其餘不變。
九、複製:memcpy和strcpy
1.記憶體複製
void*memcpy(void*dest,constvoid*src,size_tcount);
memcpy()可以複製任何類型資料,不處理字串結束'\0'的情況,當*src長度大於*dest時會bufferoverflow(編譯時不會錯誤)。
2.字串複製
void*strcpy(void*dest,constvoid*src);
strcpy()只能用於字串複製,不需要指定長度,因為會自動偵測以'\0'為結尾,當*src長度大於*dest時會bufferoverflow(*dest將沒有\0)。
舉例
#include
struct[structName]{
charname[16];
intage;
struct[structName]*ptr;
//不能含有自己,但可以有自己型別的指標。
};
intmain(){
struct[structName]person1={"Amy",20};//初始化
person.age=21;//操作
}
2.重新定義型態名稱typedef
typedef保留字可以為資料型態建立別名,使程式更易閱讀理解。
例如:
typeofstruct[structName]{
charname[16];
intage;
struct[structName]*ptr;
}PERSON;
intmain(){
PERSONperson1={"Amy",20};
person.age=21;
}
3.列舉enum
enum是一種常數定義方式,可以提升可讀性,enum裡的識別字會以int的型態,從指定的值開始遞增排列(預設為0)。
typedefenum{SUN=0,MON,TUE,WED,THU,FRI,SAT}week_type;
week_typeweek=WED;
if(week==WED)
cout<
延伸文章資訊
- 1做MTK筆試的總結(一)_關於C語言 - 程式師世界
今年要開始找工作了,本著積累經驗的目的,跑去做了下MTK的筆試題,筆試的內容主要是C++。 因為開發中一直使用C++,而且對C++裡的高級特性: ...
- 2聯發科c考題在PTT/Dcard完整相關資訊 - 健康急診室
為英文Resume written on behalf of ptt?tw英文的「履歷代寫ptt?tw」 在.聯發科c考題-2021-04-10 | 星星公主聯發科c考題相關資訊,C/C++ -...
- 3聯發科上機考c++、聯發科面試內容、聯發科面試被電在PTT ...
聯發科上機考c++在PTT/mobile01評價與討論, 提供聯發科面試內容、聯發科面試被電、聯發科英文考題就來台鐵車站資訊懶人包,有最完整聯發科上機考c++體驗分享訊息.
- 4聯發科c語言考古題 - 軟體兄弟
很多群暉、台積電、聯發科等考題都有Linked List、Thread/Process等必考題,但版 ... ,2017年8月7日— 常見的C/C++ 問題總整理,增強C 語言觀念並練習一些題目...
- 5聯發科c語言考古題、聯發科面試內容 - 露營資訊懶人包
公司內部主要程式語言是C++ 跟Python。 [Kronos Research 團隊長怎樣] 高頻交易需要相當深的專業:統計跟機器學習預測短時間的行情波動,計算機科學在 ...