1. 操作符與基本類型
賦值運算子的優先順序低於算數運算子。如:X*=3+2即X*=(3+2)
優先順序&&高於||, &高於^高於|
一元操作符的關聯是從右至左,“++”和“- -”都必須邦定一個變數或者叫“左值”,如“x”。注意“-X”並不是左值。
例如:z+=-x++ + ++y,相當於:z+=-(x++)+(++y)
字元:’0’對應ASCII的48,’A’對應的是65。
無論是無符號還是有符號的整數,-2這樣的都將被解釋為一個由0和1構成的字串。對於無符號的負數變數,運算時將被解釋為一個大的正整數。
賦值運算式的值是“=”右邊的值,類型是“=”左邊的類型。
7位元字是float浮點數的精度極限(intel8086和motorola68000平台)
資料類型不同的兩個數進行運算,結果將保持資料類型高的類型。
2.控制流程與編程風格
continu語句將強行開始下一次迴圈
字元常數’\n’(其中“n”是三個八位元字)代表著一個與八位元字n相對應的字元。比如說,“\101”對應的是001000001即65即在ASCII對應’A’
所謂優良的編程風格,關鍵是讓你編寫出來的程式適合他人閱讀:
1). 把你的思路用一些簡明的語句表現出來
2). 為那些語句選擇一種適當的代碼結構
如果對某個函數的調用發生在對它做出聲明之前,C語言將假設該函數的傳回型別是int
聲明為static的變數,在程式載入到記憶體時被初始化,在程式退出執行時終止
3.指標和數組
“type *p”形式的定義向編譯器表明:當 *p出現在一個運算式裡的時候,它將代表一個type類型的值。P是一個type類型的指標,這個指標的值是某個type類型元素的地址。type稱做指標p的基底類型。“*”表示要取出p指向的那個地址的值!
對一個指標變數使用遞增操作符,將使指標指向它基底類型的下一個元素。實際上是使該指標遞增sizeof(basetype)個位元組。
在C語言裡,x[i]被定義為“*(x+i)”,其中x是一個地址。i是一個整數遞增量。
關於多維陣列:
如,int a[3][3]={
{1,2,3},
{4,5,6},
{7,8,9}
};
則a的類型是指向三元int數組的指標,a的基底類型是三元int數組,而a+1將指向記憶體中的下一個三元int數組。a[0]的類型是指向int整數的指標,a[0]的基底類型是int,而a[0]+1將指向記憶體中的下一個int整數。這裡的a,a[0]求值為同一個地址。事實上a+i與*(a+i)所表示的地址也是一樣的,都是第i行的地址(但意義不同)。
4.結構
//聲明結構,用OO的觀念來看,就是聲明了一個輕量級的‘類’!
struct S1{
char *s;
int I;
struct S1 *s1p;
} ;
//建立一個結構執行個體,類似OO裡面自訂類型的執行個體化。
static struct S1 a[]={
{“abcd”,1,a+1},
{“efgh“,2,a+2},
{“ijkl”,3,a}
} ;
struct S1 *p =a;
則p->s表示指標p所指向的那個結構的s欄位所指向的字串。
a[--(p->s1p->i)].s 表示先對指標p所指向的那個結構的s1p欄位所指向的那個結構的i欄位進行遞減,再使用i欄位的值作為下標,去訪問數組a的相應元素。
5.預先處理
預先處理的幾條原則:
1). 只要一條宏定義語句裡麵包含操作符,就應該用括弧把它括起來
2). 宏定義越緊湊越好;運算式比語句好;單語句比多語句好
3). 在宏定義裡面要注意避免使用有副作用的C語言元素或者運算式
4). 一定要讓對宏進行擴充得到的運算式,語句,塊都是完整的C語言元素
5). 宏要盡量簡單,如果無法得到一個簡單的宏就應該把它定義為函數