一些有趣的C語言題目
阿新 • • 發佈:2019-01-10
問題2:寫一個“標準”巨集,這個巨集輸入兩個引數並返回較小的一個
答:#define MIN(x,y)((x)<(y)?(x):( y))//結尾沒有; (注意幾個括號)
問題3:#與##的作用?
答:#是把巨集引數轉化為字串的運算子,##是把兩個巨集引數連線的運算子。
例如:
#define STR(arg)#arg則巨集STR(你好)展開時為“你好”
#define NAME(y)name_y則巨集NAME(1)展開時仍為name_y
#define NAME(y)name _ ## y則巨集NAME(1)展開為name_1
#define DECLARE(name,type)typename ## _ ## type ## _ type,
則巨集巨集DECLARE(val,int)展開為int val_int_type
15 Typedef在C語言中頻繁用以宣告一個已經存在的資料型別的同義字。也可以用前處理器做類似的事。例如,思考一下下面的例子:
#define dPS struct s *
typedef struct s * tPS;
以上兩種情況的意圖都是要定義dPS和tPS作為一個指向結構s指標。哪種方法更好呢?(如果有的話)為什麼?
這是一個非常微妙的問題,任何人答對這個問題(正當的原因)是應當被恭喜的。答案是:typedef更好。思考下面的例子:
dPS p1,p2; // p1為結構體指標 p2為結構體
tPS p3,p4; // p3 p4為結構體指標
第一個擴充套件為
struct s * p1,p2;
上面的程式碼定義p1為一個指向結構的指,p2為一個實際的結構,這也許不是你想要的。第二個例子正確地定義了p3和p4兩個指標。晦澀的語法
問題4:結構體成員陣列大小為0
結構體陣列成員的大小為0是GNU C的一個特性。好處是可以在結構體中分配不定長的大小。如
typedef struct st
{
inta;
int b;
char c[0];
}st_t;
sizeof(st_t)等於8,即char c[0]的大小為0.
34、位操作(Bit manipulation) 答: 嵌入式系統總是要使用者對變數或暫存器進行位操作。給定一個整型變數a,寫兩段程式碼,第一個設定a的bit 3,第二個清除a 的bit 3。在以上兩個操作中,要保持其它位不變。 對這個問題有三種基本的反應 1)不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。 2) 用bit fields。Bit fields是被扔到C語言死角的東西,它保證你的程式碼在不同編譯器之間是不可移植的,同時也保證了的你的程式碼是不可重用的。我最近不幸看到 Infineon為其較複雜的通訊晶片寫的驅動程式,它用到了bit fields因此完全對我無用,因為我的編譯器用其它的方式來實現bit fields的。從道德講:永遠不要讓一個非嵌入式的傢伙粘實際硬體的邊。 3) 用 #defines 和 bit masks 操作。這是一個有極高可移植性的方法,是應該被用到的方法。最佳的解決方案如下: #define BIT3 (0x1 << 3) static int a; void set_bit3(void) { a |= BIT3; } void clear_bit3(void) { a &= ~BIT3; } 一些人喜歡為設定和清除值而定義一個掩碼同時定義一些說明常數,這也是可以接受的。我希望看到幾個要點:說明常數、|=和&=~操作。