C語言 if、for、goto、位運算、位段、函式(2018.11.18)
if語句
if(表示式)
{
語句1;
}
else
{
語句2;
}
在使用if語句判斷條件的時候要注意符號的結合性
eg:
if(5 <= x <= 20)
if(5 <= x && x <= 20)
語句1與語句2判斷的條件不一樣。
語句1: (5 <= x) <=20,先判斷x是否大於5,返回0或者1,再與20比較。所以這判斷條件恆成立。達不到要判斷x是否在5到20的範圍內。
語句2:判斷x是否在5到20內。
與零值做比較
浮點變數
只能比較精度
指標變數
與NULL比較
swicth語句
switch(表示式) { case 常量表達式 1: 語句 1; case 常量表達式 2: 語句 2; … case 常量表達式 n: 語句 n; default : 語句 n+1; }
要注意,一般來說,使用switch時, case 常量表達式 1: 語句 1; break;,要加break。但是break不是switch自帶的。可以在一定情況下不加。
eg:
當 條件為5、6、7時,執行相同。
switch(表示式) { case 5: case 6: case 7: printf(“1”); break; case 8: printf(“2”) ; break; default : }
但是7、8執行的東西不一樣,所以要加break,不然的話當執行完7後,會繼續執行下面的語句。輸出就發生錯誤。
default可以放在任何地方。但是放在任何地方時,要記得加break。不然會繼續執行下面的語句。
default不需要用到時最好也寫一下【default: break;】,不然別人會覺得你忘記寫。
while,for,do while
while(判斷條件) { 語句; } //直到不滿足條件後,結束迴圈 do { 迴圈體; } while(條件); //先執行迴圈體一次後,再按段條件。所以do-while結構至少執行一次迴圈體; //直到不滿足條件後,結束迴圈 for(表示式1;表示式2;表示式3) { 迴圈體; }
for與while都是當型迴圈,他們可以互相轉換。
do while轉換為while只需要在while前面多寫一次迴圈體。
但是while 無法轉換為 do while
注意
寫do while時的最好是:
do{
迴圈體;
}while(條件);
goto
goto state;
char s1, s2; // 被goto 跳過
int sum = 0; // 被goto 跳過
state:
不能隨意使用,因為他可以隨意跳出,會破壞程式的結構。
goto多數用來:在多重迴圈的最裡層,跳出到最外層。
goto沒有自帶判斷語句,所以一般配搭if使用。
int i = 0;
int a[i];
是不可以的。因為系統雖然給i分配了記憶體空間,但是在編譯的時候i沒有值,只有在執行的時候有值。但是在編譯的時候a[]陣列就要i的變數,這時候i的變數是垃圾值,陣列的長度就變成垃圾長度了。
按位與&
x & y
x=1,y=1,x&y =1
其他=0;
同一為一
【一般用來使原碼為0】
按位或
x | y
x=0,y =0, x | y=0
同0為0
【一般用來使原碼為1】
按位異或
x ^ y
相同為0,不相同為1
按位取反
~x
按位左移
x << 位數
低位補0,高位溢位
按位右移
x >> y
移出的低位捨棄,分兩種補位方法。
對無符號數和有符號正數,補0
有符號負數
1、邏輯右移:補0
2、算術右移:補1
位段
所謂位段型別,是一種特殊的結構型別,其所有成員均以二進位制位為單位定義長度,並稱成員為位段。
struct status
{ unsigned sign: 1; /*符號標誌*/
unsigned zero: 1; /*零標誌*/
unsigned carry: 1; /*進位標誌*/
unsigned : 0; /*長度為0的無名位段*/
unsigned parity: 1; /*奇偶/溢位標誌*/
unsigned half_carry: 1; /*半進位標誌*/
unsigned negative: 1; /*減標誌*/
} flags;
因為位段型別是一種結構型別,所以位段型別和位段變數的定義,以及對位段(即位段型別中的成員)的引用,均與結構型別和結構變數一樣。
對位段賦值時,要注意取置範圍。一般地說,長度為n的位段,其取值範圍是:0~(2n-1)。
使用長度為0的無名位段,可使其後續位段從下1個位元組開始儲存。
對CPU的狀態暫存器而言,使用位段型別,比使用結構型別節省。
帶引數的main函式和命令列引數
main(int argc, char *argv[ ])
可變引數列表
#include<stdarg.h>中定義了
typedef struct{
char *ao;
int offset;
}va_list;
所以在使用的時候不用再定義了。
控制函式:
void va_start(va_list ap,last);
type va_arg(va_list ap,type);
void va_end(va_list ap);
void va_copy(va_list dest,va_list src);
呼叫引數表以前,定義一個va_list型別變數
變數作為函式引數是單向傳遞的
指標作為函式引數是雙向傳遞的
遞迴函式
在函式呼叫時,直接或間接地自己呼叫自己的函式稱為遞迴函式。
第一階段稱為“遞推”階段,第二階段稱為“迴歸”階段
遞迴的條件:
1、須有完成函式任務的語句;
2、一個確定是否能避免遞迴呼叫的測試;
3、一個遞迴呼叫語句;
4、先測試,後遞迴呼叫。
遞迴時,每次遞迴都要給呼叫函式分配記憶體空間,所以遞歸併不既節省空間和時間,與呼叫其他函式相同。
只是節省了程式設計時間,使程式設計簡化。
返回指標值的函式
型別 *函式名(形參列表)
int *a(int x, int y)