C語言---總結

基礎

  • 程序結構是三種: 順序結構、選擇結構(分支結構)、循環結構。
  • 讀程序都要從 main()入口, 而後從最上面順序往下讀(碰到循環作循環,碰到選擇作選擇),有且只有一個main函數。
  • 計算機的數據在電腦中保存是以二進制的形式. 數據存放的位置就是他的地址.
  • bit是位,指爲0或1。byte是指字節,一個字節=八個位。

常考

  • 編譯預處理不是 C語言的一部分,不佔運行時間不要加分號
    C語言編譯的程序稱爲源程序,它以ASCII數值存放在文本文件中。
  • define PI 3.1415926; 這個寫法是錯誤的,必定不能出現分號
  • 每一個C語言程序中main函數是有且只有一個。
  • 在函數中不能夠再定義函數。
  • 算法:能夠沒有輸入,可是必定要有輸出。
  • break可用於循環結構和switch語句。
  • 逗號運算符的級別最低,賦值的級別倒數第二。
  • int *p 中 *p 和 p 的差異:簡單說*p 是數值,p 是地址
    • *p:能夠當作變量來用;*的做用是取後面地址 p 裏面的數值。
    • p:是看成地址來用。能夠用在 scanf 函數中:scanf(「%d」,p);
  • *p++ 和 (*p)++的之間的差異:(筆試重點)
    • *p++:地址會變化。
      口訣:取當前值,而後再移動地址!
    • (*p)++:數值會要變化。
      口訣:取當前值,而後再使數值增長 1。算法

      例題:int *p,a[]={1,3,5,7,9};
      p=a;
      請問*p++和(*p)++的數值分別爲多少?
      *p++:這個自己的數值爲1。因爲是地址會增長一,因此指針指向數值3了。
      (*p)++:這個自己的數值爲1。因爲++表示數值會增長,指針不移動,但數值1因爲自加了一次變成了2。數組

  • 二級指針:
    • *p:一級指針:存放變量的地址。
    • **q:二級指針:存放一級指針的地址。函數

      常考題目:int x=7;int*p=&x,**q=p;
      問你:*p 爲多少?*q爲多少?**q爲多少?
      *p=7,*q=p,**q=7
      再問:**q=&x 的寫法能夠嗎?不能夠,二級指針只能存放一級指針的地址。指針

  • 程序進行編譯時,並不爲形式參數分配存儲穿間。只有在被調用時形式參數才臨時地佔有存儲空間。形式參數用關鍵字auto做存儲類別的聲明時,關鍵字「auto」能夠省略,auto 不寫則隱含肯定爲「自動存儲類別」,它屬於動態存儲方式。
  • 函數的存儲類型是函數定義時函數名前面的數據類型前面的存儲類型,缺省時應該是:extern,表示該函數屬外部函數(即 能夠被本 C 文件外的其餘 C 源程序文件中的函數調用
    • extern:
      整個工程可見,其餘文件可使用extern外部聲明後直接使用。也就是說其餘文件不能再定義一個與其相同名字的變量了(不然編譯器會認爲它們是同一個變量)
    • static:表明靜態全局
      僅對當前文件可見,其餘文件不可訪問,其餘文件能夠定義與其同名的變量,二者互不影響。

重點

  • strlen 和 sizeof 的區別(重點):
    • sizeof:(求實際存儲空間
      至關因而個宏同樣的東西,由於它只是一個運算符,而不是函數,編譯時展開爲常數,編譯的時候有每一個變量的定義表,sizeof經過查表肯定變量佔用的空間,這是分配內存給process 以前要肯定的。
      其實能夠簡單的理解sizeof針對"類型"的,而非"變量",但此時不能這樣看如:sizeof("HELLO");中括號中爲const char *,而是一個"字符串",因此結果大小爲 5.但:
    char *ps = "HELLO";
    sizeof(ps) = 4  //只是指針的大小,即 地址(整數類型佔4個字節)
    sizeof(*ps) = 1 //*ps+0表明數組第一個元素的大小,即ps[0]
    
    char as[8];
    sizeof(as) = 8  //由於as的類型爲 char [8],這個大小的確是8
    sizeof(*as) = 1 //*as+0表明數組第一個元素的大小,即as[0]
    
    char aa[8][9];
    sizeof((char *)aa) = 4  //仍是 char *
    
    char arr[100] = "HELLO";
    sizeof(arr) = 100   //和賦什麼值沒什麼關係,關鍵是"類型"是什麼
    
    int func(char p[100]) {
        sizeof(p) = 4;
        /*C/C++中不能傳數組,只能傳指針,因此任何數組都會隱式轉成指針形式進行操做。*/
    }
    • strlen:(求字符串長度,即 字符個數,不包括結束符)
      它是一個函數,參數是 const char*,搞清楚它的實現,就是碰到‘\0‘(字符串結尾,就中止計數,但不包括‘\0‘)。因此它不是看類型而是看變量,取決於變量賦的什麼值。
  • 函數的遞歸必定會考。
  • 兩種重要的數組長度:
    char a[]={‘a’,’b’,’c’}; 數組長度爲3,字符串長度不定(由於沒有'\0'結束符)。sizeof(a)爲3。
    char a[5]={ ‘a’,’b’,’c’}; 數組長度爲5,字符串長度3。sizeof(a)爲5。
    char a[]={'a','b','c'}; 這是一個字符數組,佔3個字節
    char a[]="abc" 則不一樣,它是一個字符串,最後還有一個'\0'結束符,佔4個字節code

  • scanf 和 gets 的區別:
    若是輸入的是 good good study!
    • scanf(「%s」,a);
      只會接收 good。 考點:不能夠接收空格。(遇到空格或回車就終止)
    • gets(a);
      會接收 good good study! 考點:能夠接收空格。(遇到回車終止)
  • 指針考點:
    char ch[]=」iamhandsome」;
    char *p=ch;
    問你:*(p+2) 和 *p+2 的結果是多少?
    *(p+2) = ‘m’ *p+2 = ‘k’遞歸

    解析:
    第一個是地址+2,因此取m;
    第二個則是數值+2,即 ASCII碼值+2,ijk,因此取k。內存

  • 字符串的賦值:
    C語言中沒有字符串變量,因此用數組和指針存放字符串:
    1. char ch[10]={「abcdefgh」};
    2. char ch[10]=「abcdefgh」;
    3. char ch[10]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’};
    4. char *p=「abcdefgh」;
    5. char *p;
    6. ch=「abcdefgh」; !數組名不能夠賦值!(只能一個一個循環賦值)
    7. char *p={「abcdefgh」}; !不可以出現大括號!

宏定義defind

問題:#define f(x)(x*x) 和 #define f(x) x*x 之間的差異。字符串

define是C語言中的宏定義關鍵字,其定義格式以下:get

#define [MacroName] [MacroValue]宏定義分爲普通宏定義和帶參數的宏定義編譯器

  • 普通宏定義:#define PI (3.1415926)

  • 帶參數的宏定義 (宏函數):#define max(a,b) ((a)>(b)? (a),(b))
    注意:變量在宏中要用括號括起來
    由於,在C語言中define宏定義在編譯時,會被展開,進行「傻瓜式」替換,也稱爲「字面」替換,若是沒有括號有可能會產生歧義。

    如:

    int a,b,c,d,e;
    a=1;b=2;c=6;d=4;
    e=f(a+b) * f(c+d) ;  //理論值e=9*100=900
    
    #define f(x)(x*x)
    替換結果爲:e=(a+b*a+b)*(c+d*c+d) = 5*34=170
    
    #define f(x) x*x 
    替換結果爲:e=a+b*a+b*c+d*c+d=1+2+12+24+4=43
    
    #define f(x) ((x)*(x))
    替換結果爲:e=( (a+b)*(a+b)*(c+d)*(c+d) )=3*3*10*10=900

    這個纔是咱們想要的結果!

相關文章
相關標籤/搜索