C語言中的名字層次

2021-04-18 15:08:43 字數 1694 閱讀 5973

p.j plauger的"the standard c library"一書的chapter0的章後練習中有這樣的一道題:編寫乙個包含如下一行語句的正確的程式: x:      ((struct x*)x)->x=x(5);

並描述這行語句中x的5種截然不同的use,這裡其實涉及到這麼乙個知識或者說概念:c語言的命名空間(namespace),在"c語言參考手冊"中還被稱作: overloading class。 這 裡namespace,並非c++中的那個keyword "namespace",這裡的namespace更多是編譯器為了識別不同範圍下的識別符號而進行的劃分,而不是提供給應用程式設計師的類似c++中的那個 namespace facility。再次注意:c的namespace不是乙個關鍵字。

簡單分析一下這行語句:x:      ((struct x*)x)->x=x(5); 這裡有5個x,第一印象:這樣的語句能編譯過去麼?那既然p.j plauger提出了這樣的問題,那麼自然有solution。

從左到右順序:

第乙個x -- 毋庸置疑,這是乙個標號(label) ;

第二個x -- 這裡的x顯然是乙個struct tag(結構體標誌);

第三個x -- 這裡的x 無法確定其具體身份,可能是一指標型別,也可能就是乙個整型;

第四個x -- x前面有->,顯然這個x是某結構體的乙個成員變數;

第五個x -- x(5)讓人"浮想聯翩",第一印象是函式呼叫,細緻一想還可能是乙個巨集哦(你肯定會說不可能,呵呵,別著急,慢慢來) 到底如何增加一些語法元素能讓這一行能順利通過編譯,並執行後得到合理結果呢?

1) 預處理器巨集名

2) 語句標號

3) 結構、列舉、聯合結構的標誌

4) 成員名

5) 其他名稱 包括變數名、函式名、typedef名稱和列舉常量

有了以上的說明,我們有了第一種方案:上面說了,語句x:      ((struct x*)x)->x=x(5)中有三個x都是可以確定的,不確定的是第三個x和最後乙個x。我們先考慮讓最後乙個x為乙個函式。 考慮到最後乙個命名空間的說明,一旦最後乙個x為函式的話,第三個x就不能為變數名、typedef名稱和列舉常量了。如果x是物件巨集(不帶引數的巨集),顯然也不合理;那麼我們先將x實現為函式看看:

struct x ;

int x(int a)

int main()

x:      ((struct x*)x)->x=x(5);

這個在gcc(sunos or mingw on windows下)下編譯能順利通過。但是執行一下編譯出的程式,會出現致命錯誤。初略分析一下也不奇怪。函式x的位址是在**段,那塊記憶體區域是唯讀且受保護的,嘗試強制賦值顯然os是不允許的。 第一種方案雖然能通過編譯,但是執行結果不合理。

我們來做第二種嘗試:試著將最後乙個x實現為乙個函式巨集(帶引數的巨集)。

struct x ;

struct x ax;

#define x(a)  (a);

int main() {

int x = (int)(&ax);

x:      ((struct x*)x)->x=x(5);

printf("%d/n", ((struct x*)x)->x); //output: 5

這回,我們得到了正確的且合理的solution了。在p.j plauger的"the standard c library"一書中還有一張關於c語言命名空間的圖,記起來更形象。

C 語言的幾個層次

接到一位前不久c 培訓學員的來信,這位學員雖然以前功底欠缺,但學習勁頭很足,在培訓中成長很快。即便基本吃透 net框架 修訂版 還嫌不夠過癮,一心要成為高手中的高手。來信的目的是希望我來指點高階方向。說實話,我一般不想在這些有關個人發展的大是大非的問題上給人指導,因為太多親身或眼見的經歷告訴我人生實...

C 語言的幾個層次

接到一位前不久c 培訓學員的來信,這位學員雖然以前功底欠缺,但學習勁頭很足,在培訓中成長很快。即便基本吃透 net框架 修訂版 還嫌不夠過癮,一心要成為高手中的高手。來信的目的是希望我來指點高階方向。說實話,我一般不想在這些有關個人發展的大是大非的問題上給人指導,因為太多親身或眼見的經歷告訴我人生實...

C 語言的幾個層次

接到一位前不久c 培訓學員的來信,這位學員雖然以前功底欠缺,但學習勁頭很足,在培訓中成長很快。即便基本吃透 net框架 修訂版 還嫌不夠過癮,一心要成為高手中的高手。來信的目的是希望我來指點高階方向。說實話,我一般不想在這些有關個人發展的大是大非的問題上給人指導,因為太多親身或眼見的經歷告訴我人生實...