<dfn id="is4kg"></dfn>
  • <ul id="is4kg"></ul>
  • <abbr id="is4kg"></abbr>
  • <ul id="is4kg"></ul>
    <bdo id="is4kg"></bdo>

    曙海教育集團論壇開發語言培訓專區C++語言開發 → 給粗心的C語言初學者(1)


      共有6909人關注過本帖樹形打印

    主題:給粗心的C語言初學者(1)

    美女呀,離線,留言給我吧!
    wangxinxin
      1樓 個性首頁 | 博客 | 信息 | 搜索 | 郵箱 | 主頁 | UC


    加好友 發短信
    等級:青蜂俠 帖子:1393 積分:14038 威望:0 精華:0 注冊:2010-11-12 11:08:23
    給粗心的C語言初學者(1)  發帖心情 Post By:2010-12-10 14:48:11

    0 簡介

    C語言及其典型實現被設計為能被專家們容易地使用。這門語言簡潔并附有表達力。但有一些限制可以保護那些浮躁的人。一個浮躁的人可以從這些條款中獲得一些幫助。


    在本文中,我們將會看一看這些未可知的益處。這是由于它的未可知,我們無法為其進行完全的分類。不過,我們仍然通過研究為了一個C程序的運行所需要做的事來做到這些。我們假設讀者對C語言至少有個粗淺的了解。


    第一部分研究了當程序被劃分為記號時會發生的問題。第二部分繼續研究了當程序的記號被編譯器組合為聲明、表達式和語句時會出現的問題。第三部分研究了由多個部分組成、分別編譯并綁定到一起的C程序。第四部分處理了概念上的誤解:當一個程序具體執行時會發生的事情。第五部分研究了我們的程序和它們所使用的常用庫之間的關系。在第六部分中,我們注意到了我們所寫的程序也不并不是我們所運行的程序;預處理器將首先運行。最后,第七部分討論了可移植性問題:一個能在一個實現中運行的程序無法在另一個實現中運行的原因。


    1 詞法缺陷

    編譯器的第一個部分常被稱為詞法分析器(lexical analyzer)。詞法分析器檢查組成程序的字符序列,并將它們劃分為記號(token)一個記號是一個有一個或多個字符的序列,它在語言被編譯時具有一個(相關地)統一的意義。在C中, 例如,記號->的意義和組成它的每個獨立的字符具有明顯的區別,而且其意義獨立于->出現的上下文環境。


    另外一個例子,考慮下面的語句:


    if(x > big) big = x;


    該語句中的每一個分離的字符都被劃分為一個記號,除了關鍵字if和標識符big的兩個實例。


    事實上,C程序被兩次劃分為記號。首先是預處理器讀取程序。它必須對程序進行記號劃分以發現標識宏的標識符。它必須通過對每個宏進行求值來替換宏調用。最后,經過宏替換的程序又被匯集成字符流送給編譯器。編譯器再第二次將這個流劃分為記號。


    在這一節中,我們將探索對記號的意義的普遍的誤解以及記號和組成它們的字符之間的關系。稍后我們將談到預處理器。


    1.1 = 不是 ==

    從Algol派生出來的語言,如Pascal和Ada,用:=表示賦值而用=表示比較。而C語言則是用=表示賦值而用==表示比較。這是因為賦值的頻率要高于比較,因此為其分配更短的符號。


    此外,C還將賦值視為一個運算符,因此可以很容易地寫出多重賦值(如a = b = c),并且可以將賦值嵌入到一個大的表達式中。


    這種便捷導致了一個潛在的問題:可能將需要比較的地方寫成賦值。因此,下面的語句好像看起來是要檢查x是否等于y:


    if(x = y)
    foo();


    而實際上是將x設置為y的值并檢查結果是否非零。在考慮下面的一個希望跳過空格、制表符和換行符的循環:


    while(c == ' ' || c = '\t' || c == '\n')
    c = getc(f);


    在與'\t'進行比較的地方程序員錯誤地使用=代替了==。這個“比較”實際上是將'\t'賦給c,然后判斷c的(新的)值是否為零。因為'\t'不為零,這個“比較”將一直為真,因此這個循環會吃盡整個文件。這之后會發生什么取決于特定的實現是否允許一個程序讀取超過文件尾部的部分。如果允許,這個循環會一直運行。


    一些C編譯器會對形如e1 = e2的條件給出一個警告以提醒用戶。當你趨勢需要先對一個變量進行賦值之后再檢查變量是否非零時,為了在這種編譯器中避免警告信息,應考慮顯式給出比較符。換句話說,將:


    if(x = y)
    foo();


    改寫為:


    if((x = y) != 0)
    foo();


    這樣可以清晰地表示你的意圖。


    1.2 & 和 | 不是 && 和 ||

    容易將==錯寫為=是因為很多其他語言使用=表示比較運算。 其他容易寫錯的運算符還有&和&&,或|和||,這主要是因為C語言中的&和|運算符于其他語言中具有類似功能的運算符大為不同。我們將在第4節中貼近地觀察這些運算符。


    1.3 多字符記號

    一些C記號,如/、*和=只有一個字符。而其他一些C記號,如/*和==,以及標識符,具有多個字符。當C編譯器遇到緊連在一起的/和*時,它必須能夠決定是將這兩個字符識別為兩個分離的記號還是一個單獨的記號。C語言參考手冊說明了如何決定:“如果輸入流到一個給定的字符串為止已經被識別為記號,則應該包含下一個字符以組成能夠構成記號的最長的字符串”。因此,如果/是一個記號的第一個字符,并且/后面緊隨了一個*,則這兩個字符構成了注釋的開始,不管其他上下文環境。


    下面的語句看起來像是將y的值設置為x的值除以p所指向的值:


    y = x/*p /* p 指向除數 */;


    實際上,/*開始了一個注釋,因此編譯器簡單地吞噬程序文本,直到*/的出現。換句話說,這條語句僅僅把y的值設置為x的值,而根本沒有看到p。將這條語句重寫為:


    y = x / *p /* p 指向除數 */;


    或者干脆是


    y = x / (*p) /* p指向除數 */;


    它就可以做注釋所暗示的除法了。


    這種模棱兩可的寫法在其他環境中就會引起麻煩。例如,老版本的C使用=+表示現在版本中的+=。這樣的編譯器會將


    a=-1;


    視為


    a =- 1;



    a = a - 1;


    這會讓打算寫


    a = -1;


    的程序員感到吃驚。


    另一方面,這種老版本的C編譯器會將


    a=/*b;


    斷句為


    a =/ *b;


    盡管/*看起來像一個注釋。


    1.4 例外

    組合賦值運算符如+=實際上是兩個記號。因此,


    a + /* strange */ = 1



    a += 1


    是一個意思。看起來像一個單獨的記號而實際上是多個記號的只有這一個特例。特別地,


    p - > a


    是不合法的。它和


    p -> a


    不是同義詞。


    另一方面,有些老式編譯器還是將=+視為一個單獨的記號并且和+=是同義詞。


    1.5 字符串和字符

    單引號和雙引號在C中的意義完全不同,在一些混亂的上下文中它們會導致奇怪的結果而不是錯誤消息。


    包圍在單引號中的一個字符只是書寫整數的另一種方法。這個整數是給定的字符在實現的對照序列中的一個對應的值。因此,在一個ASCII實現中,'a'和0141或97表示完全相同的東西。而一個包圍在雙引號中的字符串,只是書寫一個有雙引號之間的字符和一個附加的二進制值為零的字符所初始化的一個無名數組的指針的一種簡短方法。


    線面的兩個程序片斷是等價的:


    printf("Hello world\n");


    char hello[] = {
    'H', 'e', 'l', 'l', 'o', ' ',
    'w', 'o', 'r', 'l', 'd', '\n', 0
    };
    printf(hello);


    使用一個指針來代替一個整數通常會得到一個警告消息(反之亦然),使用雙引號來代替單引號也會得到一個警告消息(反之亦然)。但對于不檢查參數類型的編譯器卻除外。因此,用


    printf('\n');


    來代替


    printf("\n");


    通常會在運行時得到奇怪的結果。


    由于一個整數通常足夠大,以至于能夠放下多個字符,一些C編譯器允許在一個字符常量中存放多個字符。這意味著用'yes'代替"yes"將不會被發現。后者意味著“分別包含y、e、s和一個空字符的四個連續存貯器區域中的第一個的地址”,而前者意味著“在一些實現定義的樣式中表示由字符y、e、s聯合構成的一個整數”。這兩者之間的任何一致性都純屬巧合


    支持(0中立(0反對(0單帖管理 | 引用 | 回復 回到頂部

    返回版面帖子列表

    給粗心的C語言初學者(1)








    簽名
    主站蜘蛛池模板: 国产一在线精品一区在线观看 | 成年女人男人免费视频播放| 任你躁国产自任一区二区三区| 麻豆一卡2卡三卡4卡网站在线| 好吊妞在线观看| 亚洲av第一网站久章草| 爱情鸟第一论坛com高清免费| 国产成人三级经典中文| tube6xxxxxhd丶中国| 日本videos18高清hd下| 亚洲精品免费在线| 精品欧美一区二区三区久久久| 国产精品电影一区二区| 中文无码人妻有码人妻中文字幕| 欧洲美女与动zooz| 免费高清小黄站在线观看| 脱了美女内裤猛烈进入gif| 国产精品igao视频| japanesexxxx乱子老少配另类| 性欧美大战久久久久久久野外| 九色视频最新网址| 欧美xxxx做受欧美精品| 亚洲黄色网站视频| 粉色视频在线观看www免费| 国产亚洲欧美日韩亚洲中文色| 黄页网站在线播放| 国产精品黄大片观看| 丁香六月色婷婷| 扒开女人内裤边吃奶边摸| 亚洲av永久无码嘿嘿嘿| 欧美人成在线观看| 伊人蕉久中文字幕无码专区| 精品中文字幕一区二区三区四区| 国产办公室gv西装男| 麻豆精品一区二区综合av| 国产精品永久免费视频| hqsexmovie| 好大好硬好爽免费视频| 中文字幕在线一区二区三区| 日本一区免费观看| 亚洲AV午夜精品一区二区三区|