1. 程式人生 > >C語言 if、for、goto、位運算、位段、函式(2018.11.18)

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;】,不然別人會覺得你忘記寫。

whilefordo 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)