C程序設計語言筆記

第一章

  • float 單精度浮點數(shù)
    由下面三部分組成,占位32位

    | 符號位 | 指數(shù)位(8 bit) | 尾數(shù)位(23 bit) | 
    | :-:   | :-:           | :-:           |
    

    符號位(1位)

    1 : 表示負數(shù)
    0 : 表示正數(shù)
    

    指數(shù)位(8位) 使用EXCESS系統(tǒng)表現(xiàn),值域位[-127,128]


    image.png

    尾數(shù)位(24位)
    先把小數(shù)轉成二進制小數(shù),比如11.1875的二進制小數(shù)為1011.0011


    image.png

    值域表示區(qū)間為
    正數(shù): [1.401298 * 10^-45, 3.402823 * 10^38]
    負數(shù): [-3.402823 * 10^38, -1.401298 * 10^-45]
    
  • int 整型
    同樣是32位,int的十進制精度是10位,表示的區(qū)間為

    有符號:  [-2,147,483,648, 2,147,483,647]
    無符號:  [0, 4,294,967,295]
    
  • double 雙精度浮點數(shù)
    跟float類似,位數(shù)不同

    | 符號位 | 指數(shù)位(11 bit) | 尾數(shù)位(52 bit) | 
    | :-:   | :-:           | :-:           |
    

    值域表示區(qū)間為

    正數(shù): [4.94065645841247 * 10^-324, 1.79769313486232 * 10^308]
    負數(shù): [-1.79769313486232 * 10^308, -4.94065645841247 * 10^-324]
    
  • 輸出右對齊,第一個數(shù)字至少占3格,第二個至少占6格

    printf("%3d %6d\n", fahr, celsius);
    //output
      0    -17
     20     -6
     40      4
     60     15
     80     26
    100     37
    
  • 浮點數(shù)和整形算數(shù)運算,整形會自動轉成浮點數(shù)

  • printf 參數(shù) %o八進制 %x十六進制 %c字符 %s字符串 %%百分號

  • define 定義常量不用分號

    #define LOWER 0
    #define UPPER 300
    #defind STEP 20
    
  • 聲明函數(shù)的時候返回值默認為int,不寫就是int

  • '\0' 空字符標記字符串結束,這一約定已被C語言采用

  • 如果全局變量定義在函數(shù)之前哟玷,可以省略extern關鍵字辐宾;但如果全局變量定義在不同文件中豫喧,則需要使用extern關鍵字。

  • 為了兼容老版本ANSI C,定義函數(shù)的時候如果沒有參數(shù)需要傳個void

    int get_line(void);
    

第二章

  • short int 最少16位, short int 永遠小于等于int, long int至少32位
  • 'x' 和 "x" 是不同的, 'x'是一個整數(shù), "x" 是一個包含'x'以及一個'\0'的字符數(shù)組
  • %取余操作不能應用于浮點數(shù)float double
  • 參數(shù)通過函數(shù)原型聲明時,當函數(shù)被調(diào)用時,將對參數(shù)進行自動強制轉換
    double sqrt(double);
    root = sqrt(2); //2會自動轉成double
    
  • 位運算符只能應用于整型,char,short,int,long,有無符號都可以
  • & 運算符通常用來屏蔽某些位
    n = n & 0177  
    也就是
    n = n & 01111111 
    結果除了最后7個位,其他都設置成0
    
  • | 運算符通常用于將某些位設置為1
  • ^ 運算發(fā)把兩個操作數(shù)對應位不相同時將該位設置為1,相同時設置為0
  • x << 2 操作位左移兩位,空出來的位補0, 相當于乘以4
  • ~ 運算符求反碼,1變0,0變1
    x = x & ~077
    相當于
    x = x & ~(00111111)
    x = x & 11000000 //把x最后6位都變成0
    
  • (x >> (p + 1 - n)) & (0 << n) 返回x中從右邊數(shù)第p位開始向右數(shù)n位的值

第三章

  • switch case 的值只能是整數(shù)值或者是結果是整數(shù)的表達式,break和return都可以終止switch
  • break,continue 只能控制退出最近一層的循環(huán)
  • goto可以跳出多層循環(huán),能不用就不用

第四章

  • 外部變量和函數(shù)的作用域從聲明處開始硅确,直到所在文件的末尾。如果需要在變量定義之前使用該變量潜的,或者變量的定義與使用不在同一個源文件中狰域,就需要使用extern關鍵字來強制聲明邦蜜。

  • 外部變量的定義中必須指定數(shù)組長度,但extern聲明則不一定要指定數(shù)組的長度

    double val[MAXVAL]; //定義
    extern double val[];  // 引用
    
  • static 靜態(tài)變量
    使用"static"關鍵字可以將變量或函數(shù)的作用域限制在聲明它們的文件內(nèi)依鸥,其他文件無法直接訪問。對于全局變量悼沈,這使得它們具有靜態(tài)屬性贱迟。在函數(shù)內(nèi)部聲明的靜態(tài)變量在函數(shù)調(diào)用結束后仍然保持其值姐扮,并且在下一次調(diào)用時繼續(xù)使用。使用"static"關鍵字修飾函數(shù)時衣吠,函數(shù)的鏈接屬性為內(nèi)部鏈接茶敏,只能在定義它的文件中訪問。

  • register 寄存器變量
    register告訴編譯器把變量放在寄存器中,只適用于自動變量以及函數(shù)的形參,現(xiàn)代編譯器一般都忽略這個特性

  • 外部變量和靜態(tài)變量初始化為空值,自動變量和寄存器變量的初值則沒有定義

  • 對于外部變量與靜態(tài)變量來說,初始化表達式必須是常量表達式,且在程序開始執(zhí)行前初始化一次,對于自動變量和寄存器變量,則在每次進入函數(shù)或程序塊時才會初始化

  • 宏替換

    #define  forever for (;;)
    forever { //直接替換成 for(;;)
    }
    // 最好不要這樣用  比如 max(i++,j++)  這里i++ 會執(zhí)行兩次
    #define max(A, B) ((A) > (B) ? (A) : (B))
    int main ()
    {
      printf("%d", max(1, 3)); //輸出3
    }
    
    
  • undef forever 取消宏定義

  • #ifdef #ifndef 在預處理階段判斷常量是否定義

第五章

  • 指針只能應用于變量或者數(shù)組,不能應用于表達式,常數(shù),寄存器變量

  • void類型的指針可以指向任何類型,但不能指向自身

  • 指針,取指&的優(yōu)先級別比算數(shù)運算符+-/高

  • ++優(yōu)先級大于指針,所以(ip)++是必須的

  • 數(shù)組變量的指針和第0個元素的指針相同

  • 如果pa是一個數(shù)組指針,pa[i]與*(pa+i)

  • 當把數(shù)組傳遞給一個函數(shù)時,實際上傳遞的時該數(shù)組的第0個元素的地址,也就是該數(shù)組的指針

  • 在形參中,字符串常量,數(shù)組,字符指針傳遞給函數(shù)的時候都是字符指針, char s[] 和 char *s是等價的

  • 形參傳遞部分數(shù)組 f(&a[2]) 或者 f(a+2)

  • p是數(shù)組,p[-1]在語法上是合法的,在訪問邊界上是非法的

  • 指針和整形之間不能相互轉換,0例外

  • NULL 常量定義在<stddef.h>中,空指針經(jīng)常用NULL代替0

  • p,q 指向同一個數(shù)組時,pq之間可以進行==, !=, <, <=, >, >=等操作,pq指向不同數(shù)組時,沒法做運算,有個特例,指針運算中,p可以使用數(shù)組最后一個元素的下一個元素的地址

  • 如果p指針指向整型,因為整形占4個字節(jié),所以p+n相當于p + 4 * n,對應的n將按4倍來算

  • 以下指針運算合法:相同類型指針的賦值運算,指針和整數(shù)的加減法運算,指向相同數(shù)組中元素的兩個指針的減法或比較運算,指針賦值為0或者和0比較,除此之外其他都是非法的

  • 如果將二維數(shù)組作為參數(shù)傳遞給函數(shù),那么在函數(shù)的聲明中,必須指明數(shù)組的列數(shù),行數(shù)倒沒什么關系

    //函數(shù)帶二位數(shù)組參數(shù)的聲明,三種方式都可以
    f(int daytab[2][13]);
    f(int daytab[][13]);
    f(int (*daytab)[13]);
    
  • 二維數(shù)組和指針數(shù)組

    int a[10][20]; //分配了200個int類型的存儲空間
    int *b[10];  //分配了10個指針的存儲空間,指針指向的數(shù)組的長度可  以不同,字符串數(shù)組首選指針數(shù)組,節(jié)省內(nèi)存
    
  • main函數(shù)可以接收命令行參數(shù),第一個參數(shù)argc(argument count)表示參數(shù)數(shù)量,第二個參數(shù)argv(argument vector)表示字符串數(shù)組,數(shù)組第一個元素argv[0]是啟動該程序的程序名,另外 argv[argc]的值是空指針0

  • 函數(shù)指針

    int (*comp)(void *, void *) //表明comp是一個指向函數(shù)的指針
    if ((*comp)(1,2) < 0) {}  //調(diào)用
    
  • 復雜聲明
    1.[] 優(yōu)先級大于 *
    2.() 優(yōu)先級大于 *

    char **argv //argv是字符指針的指針
    int (*daytab)[13] //daytab是指向某個13位整形數(shù)組的指針
    int *daytab[13] /daytab/整形數(shù)組第14個元素的指針
    void *comp() //comp是一個返回void(*)指針的函數(shù)名
    void (*comp)() //comp是函數(shù)指針,返回void
    char (*(*x())[])() //x是一個函數(shù),它返回一個指針,該指針指向一個一維數(shù)組,該一維數(shù)組的元素為指針,這些指針分別指向多個函數(shù),這些函數(shù)的返回值為char類型
    char (*(*x[3])())[5] // // x是一個三個元素的數(shù)組,數(shù)組元素是函數(shù)指針,函數(shù)返回指向5個char元素的數(shù)組指針
    

第六章

  • 如果結構體聲明的后面不帶變量,則不需要為它分配存儲空間,因為沒有實例化(面向對象的說法)
  • 結構體的合法操作只有幾種:整體復制和賦值,&取址,訪問其成員,結構體之間不可以進行比較,
  • 結構體類型的參數(shù)和其他類型的參數(shù)一樣,都是通過值傳遞的,如果傳遞的結構體很大,建議傳指針
    -.的優(yōu)先級高于*, 所以 (*pp).x 的 ()是必須的,不過也可以簡寫為pp->x,只有pp是指針時才能用->
  • sizeof 函數(shù) 返回的是無符號整型,其類型為 size_t , 在stddef.h定義
  • 編譯時獲得數(shù)組個數(shù)
    struct key{
      char *word;
      int count;
    } keytab[NKEYS];
    #define NKEYS (sizeof keytab / sizeof keytab[0])
    
  • #if 中不能使用sizeof,因為預處理器不對類型名進行分析,但預處理器并不計算#define語句中的表達式,留到編譯的時候,因此,#define中使用sizeof是合法的
  • 兩個指針的加法運算時非法的,但是劍法運算卻是合法的,在C語言理,數(shù)組末尾之后的第一個元素(&arr[len])是可以訪問的,也就是說針對這個元素的指針運算是可以正確執(zhí)行的
  • 一個包含自身實例的結構是非法的,但是指向結構之身是合法的,比如二叉搜索樹
  • 哈希表相當于一個數(shù)組,數(shù)組元素是實現(xiàn)了鏈表功能的結構體,這種應該是開放鏈表法
  • typedef char *String 定義一個字符串類型String
  • typedef類似于#define,但由于typedef是由編譯器解釋的,define是由預處理器解釋的,編譯器的文本替換能力要超過預處理器
  • union只能用第一個成員的值進行初始化
  • 屏蔽碼必須是2的冪,方便使用位運算
    struct tnode {
      char *word;
      int count;
      struct tnode *left;
      struct tnode *right;
    }
    

第七章

  • 輸入重定向符
    prog < infile  // < infile 都不包含在命令行參數(shù)argv中
    prog > file  // prog 的標準輸出重定向到文件中
    prog | anotherprog //prog 的標準輸出重定向到 anotherprog 的標準輸入
    
  • printf和putchar一樣也向標準輸出設備上輸出數(shù)據(jù)
  • include <stdio.h>在unix中回去 /usr/include中查找
  • 打印字符
    printf("%.3s", s); //打印s字符串前面3個字符
    printf("%.*s", max, s); //打印s字符串前面max個字符,max必須為int
    printf(s); //打印字符串,如果s中包含%,則會報錯
    
  • sprintf執(zhí)行的轉換和printf相同,但它將輸出保存到一個字符串中
  • FILE 是由typedef定義的類型,而不是一個結構
  • 輸出文件通常使用緩沖區(qū)來提高寫入效率缚俏。當您使用putc函數(shù)或其他輸出函數(shù)寫入數(shù)據(jù)時惊搏,數(shù)據(jù)實際上是先存儲在內(nèi)存中的緩沖區(qū)中。當緩沖區(qū)滿了忧换、手動刷新緩沖區(qū)或關閉文件時恬惯,緩沖區(qū)的內(nèi)容才會被寫入到文件中。而fclose函數(shù)在關閉文件時會自動刷新緩沖區(qū)亚茬,將緩沖區(qū)中的內(nèi)容寫入到文件中宿崭。
  • 標準輸入輸出stdin stdout可以通過fclose關閉,守護進程會用到這個
  • exit(0) 表示正常 -exit(其他)表示不正常,exit參數(shù)可以被父進程獲取,exit為每個已打開的輸出文件調(diào)用fclose函數(shù),以將緩沖區(qū)中的所有輸出寫到相應的文件中才写。
  • 在main函數(shù)里面, return 0; 相當于 exit(0);
  • feof(FILE) 和 ferror(FILE) 類似
  • gets()在讀取一行字符串時將刪除結尾的換行符,puts()在寫入字符串時將在結尾添加一個換行符
  • 使用free()釋放一個不是由malloc/calloc得到的指針將是一個嚴重的錯誤

第八章

  • unix操作系統(tǒng)中,所有外圍設備都被看作是文件系統(tǒng)中的文件
  • 系統(tǒng)調(diào)用read/write一次可以轉換任意個字符,一次轉換多個字符減少系統(tǒng)調(diào)用更加有效率,比如1024/4096相當于一個物理塊大小的字節(jié)
  • 系統(tǒng)調(diào)用open 類似于fopen ,但是 open返回文件描述符,fopen返回文件指針
  • 系統(tǒng)調(diào)用creat創(chuàng)建新文件,如果文件已存在,則清空文件內(nèi)容,返回文件描述符
  • unix文件系統(tǒng)中,每個文件對應一個9bit的權限信息,使用3位八進制表示如0755
  • 系統(tǒng)調(diào)用lseek(int fd, long offset, int origin); origin的值0表示從文件開始,1表示從當前位置,2表示從文件末尾,offset表示偏移量
  • FILE指針指向struct,內(nèi)容包括:
    typedef struct _iobuf {
        int cnt;   //記錄緩沖區(qū)中剩余的字符數(shù)的計數(shù)器
        char *ptr;  //下一個字符的指針
        char *base; //緩沖區(qū)的位置指針
        int flag;  //文件訪問模式  :讀,寫,不對文件緩沖,已到文件的末尾,該文件發(fā)生錯誤
        int fd; //文件描述符  整型
    }
    
  • fopen 不自帶緩沖區(qū)
  • MS-DOC系統(tǒng)獲取文件名需要系統(tǒng)調(diào)用,unix不用
  • 目錄就是文件,包含了一個文件名列表和inode編號
  • stat 通過指定路徑遞歸獲取文件和文件夾信息
  • fstat 通過文件描述符獲取文件信息
  • malloc在編譯時沒有確定存儲空間,在執(zhí)行的時候才向操作系統(tǒng)申請
  • malloc管理的空間不一定是連續(xù)的,而是通過鏈表連接在一起
  • malloc函數(shù)返回的存儲空間滿足將要保存的對象和最受限的類型的內(nèi)存對齊要求,機器類型不同,最受限類型可能是double,long,int
  • 內(nèi)存對齊是由union實現(xiàn)的
    typedef long Align;
    union header {
      struct {
          union header *ptr;  //空閑鏈表中下一個指針
          unsigned size;  // block大小
      } s;
      Align x;    //最受限類型  long, x永遠都不會用到,僅僅用于強制每個頭部在最壞的情況下滿足對齊要求
    }
    
  • 空閑block是一個鏈表,每個block都包括一個空閑空間本身的指針(3)以及header,header里面有一個指向下一個block的指針(1),和block的大小(2)


    image.png
  • unix系統(tǒng)調(diào)用sbrk(n),返回一個指向n字節(jié)儲存空間的指針
  • malloc里面有個morecore會調(diào)用sbrk申請更多的空間,減少系統(tǒng)調(diào)用次數(shù),優(yōu)化性能

附錄

  • 預定義名字
__LINE__包含當前源文件行數(shù)的十進制常量。
__FILE__包含正在被編譯的源文件名字的字符串字面值奖蔓。
__DATE__包含編譯日期的字符串字面值赞草,其形式為“Mmm dd yyyy”。
__TIME__包含編譯時間的字符串字面值吆鹤,其形式為“hh:mm;ss
__STDC__整型常量1厨疙。只有在遵循標準的實現(xiàn)中該標識符才被定義為1。
  • 頭文件的包含順序是任意的,并可以包含任意多次
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末疑务,一起剝皮案震驚了整個濱河市沾凄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌知允,老刑警劉巖撒蟀,帶你破解...
    沈念sama閱讀 212,686評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厂抽,死亡現(xiàn)場離奇詭異歼捐,居然都是意外死亡官套,警方通過查閱死者的電腦和手機从绘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,668評論 3 385
  • 文/潘曉璐 我一進店門乾蓬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篡诽,“玉大人厂抖,你說我怎么就攤上這事并蝗◎疴” “怎么了切蟋?”我有些...
    開封第一講書人閱讀 158,160評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長榆芦。 經(jīng)常有香客問我柄粹,道長喘鸟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,736評論 1 284
  • 正文 為了忘掉前任镰惦,我火速辦了婚禮迷守,結果婚禮上,老公的妹妹穿的比我還像新娘旺入。我一直安慰自己兑凿,他們只是感情好,可當我...
    茶點故事閱讀 65,847評論 6 386
  • 文/花漫 我一把揭開白布茵瘾。 她就那樣靜靜地躺著礼华,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拗秘。 梳的紋絲不亂的頭發(fā)上圣絮,一...
    開封第一講書人閱讀 50,043評論 1 291
  • 那天,我揣著相機與錄音雕旨,去河邊找鬼扮匠。 笑死,一個胖子當著我的面吹牛凡涩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播活箕,決...
    沈念sama閱讀 39,129評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼力麸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了育韩?” 一聲冷哼從身側響起克蚂,我...
    開封第一講書人閱讀 37,872評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎筋讨,沒想到半個月后埃叭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,318評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡悉罕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,645評論 2 327
  • 正文 我和宋清朗相戀三年游盲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蛮粮。...
    茶點故事閱讀 38,777評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡益缎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出然想,到底是詐尸還是另有隱情莺奔,我是刑警寧澤,帶...
    沈念sama閱讀 34,470評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站令哟,受9級特大地震影響恼琼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜屏富,卻給世界環(huán)境...
    茶點故事閱讀 40,126評論 3 317
  • 文/蒙蒙 一晴竞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧狠半,春花似錦噩死、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,861評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至已日,卻和暖如春垛耳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背飘千。 一陣腳步聲響...
    開封第一講書人閱讀 32,095評論 1 267
  • 我被黑心中介騙來泰國打工堂鲜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人护奈。 一個月前我還...
    沈念sama閱讀 46,589評論 2 362
  • 正文 我出身青樓缔莲,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逆济。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,687評論 2 351

推薦閱讀更多精彩內(nèi)容