C語言學習筆記

    近日重讀譚浩強的《C程序設計》一書。因爲長時間不用,很多瑣碎的知識點已經忘記。在重讀的過程當中對知識點從新作了梳理,對於一些我的容易忽略和重要的知識點羅列出來,以便往後複習和快速回憶。  數組

1、 數據類型、運算符和表達式ide

  1. C語言提供的數據類型
    a. 基本類型:整型(int),字符型(char),浮點型(單精度,雙精度)
    b. 構造類型:數組類型,結構體類型,共用體類型
    c. 指針類型
    d. 空類型
  2. C語言中,採用符號定義常量,採用大寫字母表示。例如:#define PRICE 35
  3. 變量表明內存中具備特定屬性的內存單元。變量名用小寫字母表示,表明變量值在內存中的存儲地址。變量須要先聲明後使用。
  4. 數值在內存中的存儲形式是以補碼錶示的,求負數補碼的方式是:將該數的絕對值的二進制形式取反,再加1。無符號數和長整型數在定義時,須要在後面加上U和L。
  5. 浮點型數據在內存中按指數形式存儲。在編譯系統中,將浮點常量做爲雙精度處理,而後再根據賦予變量的類型,截取實型常量相應的有效數字。
  6. 字符常量用單引號括起來。字符變量只能存放一個字符,不能存放字符串。在所用的編譯系統中規定以一個字節來存放一個字符。因爲字符變量以ASCII碼形式存放在內存中,因此就使得字符變量與整型變量通用。既能夠以字符型輸出,又能夠一整數形式輸出。
  7. 字符串常量與字符常量的差異在於,系統對字符串常量的最後之後字符後面加上"\0"表示結束。
  8. 不一樣數據類型之間能夠混合運算,不一樣類型的數據轉換成同一類型。字符數據,短整型轉換爲整型,浮點型轉換爲雙精度型。
  9. 算術表達式的運算順序先按運算符的優先級,再按從左至右的順序。自增自減運算符的結合方式是自右至左。

 

        
        
                 
        
        
  1. int i=3; 
  2. printf("%d",-i++); 
  3. printf("%d",i); 
  4.  
  5. //輸出結果:-3 4 
  10. 賦值表達式的求解過程:先求賦值表達式右側表達式的值,而後賦值給賦值運算符左側的值。左值只能是變量。
  

 

       
       
                
       
       
  1. int a=12; 
  2. a+=a-=a*a; 
  3. prinf("%d",a); 
  4. //輸出結果:-264  
  11. 逗號表達式:表達式1,表達式2。先求解表達式1的值,再求解表達式2的值。整個表達式的值是表達式2的值。在全部運算符中,級別最低。

 

        
        
                 
        
        
  1. (a=3*5,a*4),a+5 
  2. //這個表達式的值是20 
 
 
2、順序、選擇程序結構以及循環控制
 
  1. C標準庫將一些經常使用的函數的放在其中,並已編譯成爲目標文件,在鏈接時直接使用,能夠減輕C語言的編譯負擔。
  2. 不一樣運算符的優先級(從高到低):非,算術運算符,關係運算符,賦值運算符。
  3. 關係表達式的值是一個邏輯值,C語言中沒有邏輯變量和邏輯常量,以1表明真,0表明假。例如:f=a>b>c,先執行a>b,即1>c,因此f=0。
  4. 條件運算符的通常形式:表達式1?表達式2:表達式3。結合方向自右向左,優先級低於算術符和關係運算符。
  5. 選擇,循環結構的幾種典型的語句這裏不作贅述。具體參看課本。
 
 
3、函數和預處理命令
 
  1. 主函數調用其它函數,其它函數也能夠相互調用。
  2. 若是在函數定義時不指定函數類型,系統會隱含指定其爲整型。
  3. 定義函數時,括號中的爲形參。調用函數時,括號中的爲實參。在函數被調用時,形參得到內存單元,在調用結束後釋放內存。實參仍然保留並維持原值,形參的變化並不會影響實參。
  4. 若是函數中,return語句返回,類型與函數類型不一致,以函數類型爲準。
  5. 若是使用用戶本身定義的函數,而該函數的位置在主調函數以後,則須要在主調函數中做聲明。聲明能夠不寫形參名,只寫類型。函數類型,函數名,參數個數,參數類型以及參數的順序必須保持一致。
  6. 變量的分類:從做用範圍劃分:
    局部變量:函數中定義,形參,複合體中。在局部變量的做用範圍內,外部同名  變量被屏蔽。
    全局變量:函數外定義,有效範圍是從定義處到文件結束。執行過程當中始終佔據   內存。
    從聲明週期劃分:
    auto:沒有通過static聲明的局部變量和形參,系統隱含將其定義爲auto類型,  表示動態分配內存空間;
    static:若是但願局部變量的值在下次調用時保存,可將該變量聲明爲static。  靜態變量在編譯時賦初值,而對於動態變量來講,若是不對其賦初值,它的值會是  一個不肯定的值。另外,使用static聲明外部變量,說明該變量只能供本文件使用。
    register:用於聲明寄存器變量。只能用於局部自動變量和和形參。
    extern:兩個做用:
     (1)擴展外部變量的做用範圍;
     (2)使用其餘文件中的外部變量前聲明,表示本文件中出現的extern聲明變量  已經在其餘文件中定義,本文件不須要爲其分配內存。改變影響另一個文件中該  變量的執行。
  7. 內部函數:定義函數時,前面加static,表示只能供本文件中的函數使用。
     外部函數:能夠供外部文件中使用的函數。在函數最左邊加上extern。不加該關鍵字,系統隱含處理爲外部函數。另外,在調用該函數的外部文件中,對該被調用函數聲明時,須加上該關鍵字。能夠理解爲將函數的做用範圍擴展到該文件中。
  8. 預處理命令,是指在編譯以前,首先對預處理語句進行處理,,使得文件中再也不包含預處理命令,而後統一編譯。
  9. 宏定義:#define PI 3.1415926 
             #define S(a,b) a*b
宏名用大寫表示,僅做簡單置換,不作正確性檢查。雙引號的部分不作置換。
  10. 文件包含:#include <文件名>  系統優先
               #include "文件名"   用戶優先  
  11. 條件編譯:對指定語句進行編譯。有如下三種形式:
      

 

       
       
                
       
       
  1. #ifdef PRINT 
  2.     printf(""); 
  3. #else SCANF 
  4.     scanf("%d",&a); 
  5. #endif 
  6. //若指定的標識符已經被定義過,則編譯對應程序段。 
  7.  
  8. #ifndef PRINT 
  9.     printf(""); 
  10. #else SCANF 
  11.     scanf("%d",&a); 
  12. #endif 
  13. //若指定的標識符沒有被定義過,則編譯對應程序段。 
  14.  
  15. #if PRINT 
  16.     printf(""); 
  17. #else SCANF 
  18.     scanf("%d",&a); 
  19. #endif 
  20. //若指定的標識符爲真或假,則編譯對應程序段。 
       

 4、 數組和指針函數

  1. 不容許對數組的大小做動態定義,數組的大小不依賴於程序運行過程當中變量的值。在定義時,須要指明數組元素的個數。能夠所有賦值(無需指明數組元素的個數),也能夠部分賦值。未賦值部分填充0 spa

  2. 二維數組能夠被認爲是元素爲一維數組的一維數組。首先存放第一行元素,再存放下一行元素。在定義時,既能夠部分定義,也能夠所有定義。在所有定義時,第一維的長度能夠不指定,但第二維的長度不能省。 設計

  3. 字符數組中的元素是一個字符。字符串做爲字符數組來處理。系統將字符串常量末尾自動加上一個"\0"做爲結束符,由此做爲結束的標誌。指針

 

        
        
                 
        
        
  1. char c[]="love"
  2. char c[]={"love"}; 
  3. char c[]={'l','o','v','e','\0'}; 
  4. //以上三種定義方法等價 

 

  4. 字符串輸出的兩種形式ip

 

        
        
                 
        
        
  1. //方法一:按字符輸出。 
  2. for(i=0;i<10;i++) 
  3.   printf("%c",c[i]); 
  4.  
  5. //方法二:將整個字符串總體輸出 
  6. printf("%s",c); 

  

  5. 指針是地址,指針變量是存放指針的變量。內存

  6. int p=3;int *pi=&p; ci

     p:3  字符串

     &p:p的地址

     pi: p的地址

     *p:p的內容,就是3.

  7. 指針變量做爲函數參數,能夠實如今函數中改變實參的值。由於將指針變量傳進函數之後,形參和實參都是指向同一變量的指針。

  8. 數組名錶明數組首元素的地址。所以能夠把數組名直接賦值給一個指針變量而無須加上取地址符號。數組名是一個常量,不能對其進行運算和改變。

  9. 指向數組的指針變量也能夠帶下標,如p[i]*(p+i)等價。

  10. 數組名做爲函數參數,形參數組各元素的變化會引發實參數組的變化。實際上,編譯器將形參中的數組名當作指針變量來處理。

  11. 對於二維數組,數組名是第一行(一個一維數組)的地址。加上指向符號(或者a[i])後,則是其包含的一維數組的首元素的地址。a,*a和a[0]指向的是同一個地址。可是包含的意義不一樣。在指向行的指針前面加上指向符號,就轉換爲指向列的指針。

  12. 指針能夠指向一個字符串,其實是把字符串的首元素地址賦值給指針變量。

  13. 使用數組名輸出的只能是字符串數組。能夠用%s對字符串進行總體輸出。

  14. 指向函數的指針:int (*p)(int,int);

      返回指針值的函數:int *p();

      指針數組:int *p[4]

      指向指針的指針:int **p;

 

5、結構體與共用體

  1. 結構體的聲明和定義

  

 

        
        
                 
        
        
  1. struct student { 
  2.   int id; 
  3.   char name[20]; 
  4.   int age; 
  5.     }student1,student2; 

  2. 結構體類型與變量:

a. 只能對變量操做而不能對類型進行操做;

b. 對結構體中成員能夠單獨使用。變量名.成員名;

c. 成員也能夠式結構體類型;

  3. 結構體變量能夠在定義時賦初值:

 

        
        
                 
        
        
  1. struct student {  
  2.   int id;  
  3.   char name[20];  
  4.   int age;  
  5.     }student1={1010,"liming",25}; 

  4. 結構體數組的定義和賦值:

 

        
        
                 
        
        
  1. struct student {   
  2.   int id;   
  3.   char name[20];   
  4.   int age;   
  5.     }; 
  6. struct student stu[3]; 

  5. 指向結構體的指針 

 

        
        
                 
        
        
  1. struct student {    
  2.   int id;    
  3.   char name[20];    
  4.   int age;    
  5.     }stu_1;  
  6. struct student * p; 
  7. p=&stu_1; 
  8.  
  9. p->id=101010; 

  6. 共同體類型的聲明定義和引用

共同體類型中的變量起始地址一致,只有一個成員瞬時起做用,同一個成員最後一個變量起做用。

 

        
        
                 
        
        
  1. union data{ 
  2. int i; 
  3. char ch; 
  4. float f; 
  5. }a; 
  6.  
  7. a.i=15 
  8. a.ch='a'
  9. a.f=1.5 

7. 使用tyepdef聲明新的類型名代替已有的類型名步驟:

      a. 寫出定義體:int i

      b. 將變量名替換成爲自定義名:int INT

      c. 加上typedef關鍵字:typedef int INT 

 

6、位運算

  1. 位運算只能是整型或者字符型數據,不能是實型。

  2. 經常使用的位操做:

&: 清零,取一個數的某些位

|: 1

^: 同號爲0,異號爲1。用於特定位翻轉(^1),保留原值(^0

~: 取反

<<: 溢出捨去,空缺補零

>>:溢出捨去,無符號空缺補零;有符號不定。

  3. C語言容許在一個結構體數據類型中以位爲單位來指定其成員所佔的長度。以位爲單位的成員成爲成爲位段。

 

        
        
                 
        
        
  1. struct data{ 
  2.  unsigned a:2; 
  3.  unsigned b:2; 
  4.  unsigned  :0; 
  5.  unsigned  :2;//這兩位不用 
  6.  unsigned c:3; 
  7.  int i; 
  8. }; 
  9. //位段成員必須指定爲unsigned或者int類型 
  10. //c從下一個存儲單元開始存放 
  11. //i從下一個存儲單元開始存放
相關文章
相關標籤/搜索