用預處理命令#define宣告乙個常數,用以表明一年中有多少秒(忽略閏年問題)
#define year (60*60*24*365)ul
考點
1)#define語法的基礎知識
2)懂得預處理器將為你計算常數表示式的值,因此,直接寫出你是何年機斷一年中有多少秒而不是計算出實際的值,是更清晰沒有代價的。
3)意識到這個表示式將使用乙個16位機的整型數溢位,因此要使用到成整形符號l,告訴編譯器這是長整型數值。
4)如果在你使用表示式中用到ul(無符號長整形),表明有乙個良好的編譯習慣
#define 的作用
在c或c++語言源程式中允許用乙個識別符號來表示乙個字串,稱為「巨集」。被定義為「巨集」的識別符號稱為「巨集名」。在編譯預處理時,對程式中所有出現的「巨集名」,都用巨集定義中的字串去代換,這稱為「巨集代換」或「巨集展開」。巨集定義是由源程式中的巨集定義命令完成的。巨集代換是由預處理程式自動完成的。「巨集」分為有引數和無引數兩種。還可以防止重複定義。
#difine m (a)+(b)
m*m=
(a)+
(b)*
(a)+
(b)
上例提醒我們,需要在括號的使用上,一定注意
對於巨集定義還要注意:
1. 預處理程式對它不作任何檢查。如有錯誤,只能在編譯已被巨集展開後的源程式時發現。
2. 巨集定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起置換。
3. 巨集定義必須寫在函式之外,其作用域為巨集定義命令起到源程式結束。如要終止其作用域可使用#undef命令。
這個巨集輸入兩個引數並返回乙個較小的乙個
#define min(a,b) ((a)>=(b)?(b):(a))
1)懂得在巨集中小心的把引數用括號括起來。
2)指標越界可能是很嚴重的問題
3)了解巨集的***
例子:
least=min(*p++
,b)
有興趣的可以自行實踐
當預處理器預處理到#error命令時將停止編譯並輸出使用者自定義的錯誤訊息
用法示例:
檢查編譯此原始檔的編譯器是不是c++編譯器
如果使用的是c語言編譯器則執行#error命令
如果使用的是 c++ 編譯器則跳過#error命令
while(1)
for(;
;)
goto
loop
1與2的比較:
for(;;)死迴圈裡的兩個;;代表兩個空語句,編譯器一般會優化掉它們,直接進入迴圈體。 while(1)死迴圈裡的1被看成表示式,每迴圈一次都要判斷常量1是不是等於零。相對來說for式死迴圈更加高效一點 當然以上條件成立還要看編譯器的優化,一些編譯器優化的兩者並無區別,但是,並非所有的編譯器都做了這樣的優化。
執行到"goto**"的時候,程式會自動跳到goto後面跟著的字元標誌處,即"loop"處…但是"loop"處位於"goto"**之前,因此跳到了"loop"的**處向下走,會又一次碰到goto…如此迴圈反覆,因此會變為死迴圈
用變數a給出下面定義
1)乙個整型數
2)乙個指向整型資料的指標
3)乙個指向指標的指標,他指向的指標是指向乙個整形數
4)乙個有5個整型數的陣列
5)乙個有5個指標的陣列,該指標是指向乙個整型數
6)乙個指向有5個整形數陣列的指標
7)乙個指向函式的指標,該函式有乙個整形引數並返回乙個整型數
8)乙個有5個指標的陣列,該指標指向乙個函式,該函式有乙個象形引數並返回乙個整型數
1)
int a;
int
*a;
int
**a;
int a[5]
;
int
*a[5
];
int
(*a)[5
];
7)
int (*a)
(int
)
int
(*a[5]
)(int)
三個作用
1)在函式體內,被定義的變數是static的變數,在其他函式呼叫該函式的過程中,維持其值不變
2)在模組內,在函式體外,被定義位static的變數,可以被該模組內的所有函式訪問,他是乙個本地的全域性變數。
3)在模組內,乙個被宣告位static的變數被限制在不能在模組外的函式呼叫。
上面三個知識點在其他的部落格中有詳細說明,在這裡還要提供一下其他操作:
使用define來進行位操作的定義:
#define bit(x) (0x01<<(x))
我們可以使用這個bit(x)來進行置位和清零:
置位
uint8_t a=
0x11;a|
=bit(3
);
清零
uint8_t a=
0x11;a&
=~bit(3)
;
int
*p;p=
0x5678
;*p=
0x1234
;
或者:
*(int
*const)(
0x5678)=
0x1234
;
1)中斷函式中不能有引數
2)中斷函式中不能有返回值
3)中斷中應該盡量簡單,不要進行浮點運算,不同的編譯器效果不同,浮點一般都是不可重入的,列印函式printf()經常有重入和效能上的問題。
unsigned
int a=6;
signed
int b=-20
;(a+b)
>6?
puts
(">6"):
puts
("<=6"
);
答案是前者!
當表示式中存在有符號和無符號型別時,所有的運算元都自動轉換為無符號的。因此-20變成了乙個非常大的數。
unsigned
int zero=0;
unsigned
int compzero=
0xffff
;
對於不是16位的編譯器,第二個應該這樣:
unsigned
int compzero-~0
;
在堆中動態記憶體分配可能會存在記憶體碎片。
char
*p;if
((p=
(char*)
malloc(0
))==null
)puts
("null");
else
put(
"yes"
);
會輸出yes;
#define d struct s*
typedef
struct s * p
上面兩種typedef更好,為什麼呢?
d d1,d2;
p p1,p2;
第一題擴充套件為:
struct s* d1,d2;
自然就可能會出現錯誤 嵌入式經典面試題
這些題實在太經典了 預處理器 preprocessor 1 用預處理指令 define 宣告乙個常數,用以表明1年中有多少秒 忽略閏年問題 define seconds per year 60 60 24 365 ul 我在這想看到幾件事情 1 define 語法的基本知識 例如 不能以分號結束,括...
嵌入式軟體開發經典面試題
在嵌入式軟體開發的面試中,遇到筆試的機率非常大。一般來說,筆試的題目不會太難,但牽涉的知識面比較廣。若你年底有找工作的計畫,有必要找一些筆試題看看,這樣能讓你從題目中掌握並學到很多知識。1.用 define 宣告乙個常數,表明 1年中有多少秒 忽略閏年問題 答案 define seconds per...
嵌入式軟體面試題一
1 請寫出你所知道的c 語言關鍵字。auto 宣告自動變數 switch 用於開關語句 case 開關語句分支 break 跳出當前迴圈 default 開關語句中的 其它 分支 goto 無條件跳轉語句 do 迴圈語句的迴圈體 while 迴圈語句的迴圈條件 if 條件語句 else 條件語句否定...