C語言中級

來源:互聯網
上載者:User

以下轉自一位學長的C語言筆記。。。。

有些是從其他資料裡找的。希望對大家有用。

1.運算式的值:運算式有運算式的值,它是無名的,短暫的。
2.case 常量(不可以是運算)
3.資料區(棧,靜態區,堆)和代碼區
4.sizeof與數組(下邊的說明不考慮機器或者平台等因素).
一.
  int i[10];
  int *p
  p=i;
  上邊sizeof(i)為40.但是sizeof(p)是4.原因:數組名不是指標.
   
二.
  數組的大小:
  sizeof(i)/sizeof(i[0]);
  前者為40,後者為4,於是就是10個.
三.
  如果把數組名作為參數傳給函數,那麼函數的形參一定是指標了.於是在函數內就無法算出來數組的大小了.因為sizeof(這個參數)是4.所以我覺得很多函數需要傳size進去.而不是函數內計算大小.
5.const

const int a;
int const a;
const int *a;
int * const a;
int const * a const;
前兩個的作用是一樣:a是一個常整型數。第三個意味著a是一個指向常整型數的指標(也就是,整型數是不可修改的,但指標可以)。第四個意思a是一個指向整型數的常指標(也就是說,指標指向的整型數是可以修改的,但指標是不可修改的)。最後一個意味著a是一個指向常整型數的常指標(也就是說,指標和所指向的整型數都是不可修改的)。

6.typedef的陷阱:

    typedef  char * pstr;
    /*若我們這樣使用:*/
    int mystrcmp(const pstr, const pstr);
    /*我們希望表達的是:*/
    int mystrcmp( const char*, const char* );
    /*(即 2個指向常量的char指標)*/
    /*可它被解釋為:
    int mystrcmp( char* const, char* const )  ;
    /*(2個指向char的常指標)*/

分析:
const修飾的是pstr,而pstr被定義為char *,而不是char。

應修改為:
        typedef const char* cpstr;
        int myctrcmp( cpstr, cpstr);

7.複雜指標解析
  比如int (*(*func)[5][6])[7][8];
  func是指向三維數組的指標,這類數組的大元素是具有5X6個int元素的二維數組,而指向三維數組的指標又是另一個三維指標數組的元素。

8.為什麼會有匿名結構體呢?
  為了不想讓其他人再聲明該類型的變數.
9.struct的大小
  struct{
    char ch;
    int i;
    float f;
    char ch2;
  }a;
  struct{
    char ch;
    char ch2;
    float f;
    int i;
  }b;

   sizeof(a)==16
   sizeof(b)==12
   為什麼成員一樣,但是順序不同,占的空間不一樣呢?
   a的儲存:ch,_,_,_(補了三個位元組),i,float f,ch2,_,_,_
   b的儲存:ch,ch2,_,_f,i
   得出結論,用成員中占最大位元組的類型為單位,然後填充變數.要是填得下就填,填不下就新找個該單位填.如b的儲存ch,ch2,放到四位元組的記憶體,還空兩個位置.
   再一個結論:聲明struct 的時候要注意成員的先後順序.
10.malloc和calloc
   一.malloc(大小),calloc(個數,每個的大小)用哪個更好?
      用calloc好.
      原因:因為大小雖然可以個數*每個的大小得出來.但是要使這個值很大很大怎麼辦?所以分開寫(calloc)比計算這個大小(malloc)要好.這個原因是個人認為.但是應該用calloc的結論非個人認為.
   二.malloc(0)
      雖然申請0大小的記憶體,但是結果是malloc返回的結果並不等於NULL,就是說它是有返回記憶體的.有多大?忘了...

11.FILE指標
一.
    當使用檔案指標的時候,指標指的是一個結構體,該結構體除了包含各種各樣的和該檔案相關的資訊,還指著一個buffer,而該buffer和檔案又有一個有時讀入有時寫入的流.
    就是說,fopen,不單單返回了一個檔案指標,而是構建了整個讀取檔案的環境.
二.檔案的文本方式與二進位方式.
   假設123,文本方式用每個字的ASCII值表示'49','50','51'
   二進位方式則一個位元組就可以表示了1111011.
   
   使用場合:一個是方便人類,一個方便電腦

   另外,附一個ASCII編碼錶的連結http://www.blabla.cn/ref/ascii.html

12.預先處理
一.
不要忽視宏定義中的空格:
#define f  (x) (x) +1 //實際上是把f 定義成了(x) (x)+1

對於不帶參的宏,若宏值多於一項,一定要使用括弧
#define MAX (M+N)
要給每個參數加上括弧,否則可能影響計算的優先順序
#define abs(x)  (x>=0)?x:-x
z =abs(a+b); /*相當於 z= (a+b>=0)?a+b:-a+b
//修改後:
#define abs(x) ((x)>=0?(x): -(x))
盡量用typedef而不是宏定義去定義類型。
   
二.
用typedef和宏都可以定義新類型.那麼哪個更好.
答:typedef更好.
原因:int* a,b;   a和b的類型,a是指標,b是整形.同樣的,用宏定義出來的新類型,使用的時候也會出現這樣不知道是新類型指標還是新類型的情況.

三.
由於標頭檔包含可以嵌套,那麼C檔案就有可能多次包含同一個標頭檔,就可能出現重複定義的問題
通過條件編譯開關來避免重複包含
例如
#ifndef  __headerfileXXX__
    #define  __headerfileXXX__
   …
    檔案內容
   …
#endif
四.
#include “xxxx.h”
到本級目錄去找和到系統預設目錄去找。
#include <xxxx.h>
到系統預設目錄。

13.常用庫函數(總結略,舉assert為例)
診斷函數(assert.h)
測試一個條件test ,當結果為假時使程式終止,為真時沒反應 。

不要將assert函數用於程式的執行邏輯中,它僅用於調試。
即:程式的 if( 條件 ) 語句不可用 assert( 條件 ) 來替代。

如果在程式開始加入代碼:
#define  NDEBUG       
則該程式中的assert函數全部失效,不必逐一刪除。(有待驗證.因為我實驗了怎麼不管用)

14.關鍵字static的作用是什嗎?
在C語言中,關鍵字static有三個明顯的作用:
  在函數體,一個被聲明為靜態變數在這一函數被調用過程中維持其值不變。
  在模組內(但在函數體外),一個被聲明為靜態變數可以被模組內所用函數訪問,但不能被模組外其它函數訪問。它是一個本地的全域變數。
  在模組內,一個被聲明為靜態函數只可被這一模組內的其它函數調用。那就是,這個函數被限制在聲明它的模組的本地範圍內使用。

15.竟然允許這樣使用指標:
#include "stdio.h"
void main()
{
        int a = 1234;
                     // 0x0012ff7c是&a的值。
        int *p =( (int*)0x0012ff7c );
        printf("&a = %x/n",&a);
        printf("a = %d/n*p = %d/n",a,*p);
}

16.最後.留個題目.
   不申請新的空間,對數組進行逆序. 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.