c語言容易忽略的點

2021-09-30 13:54:12 字數 3574 閱讀 4891

世間事,除了生死,哪一件不是閒事。        ------倉央嘉措

在linux環境下,gcc編譯器由分析器、優化器、編譯器組成。gcc執行分四步:

1)預處理;執行預處理語句,刪除注釋(預先護理部分語句)gcc -e xx.c xx.i 

2)編譯;將c語言轉化為組合語言(檢查c語言的語法正確性) gcc -s xx.i -o xx.s 

3)彙編;將組合語言轉換成目標檔案(二進位制檔案)  gcc -c xx.s -o xx.o      vim -b xx.o (:%!xxd -g 1)  檢視二進位制檔案

4)鏈結;確保多個目標檔案組成的程式正常執行

1、對於主函式的寫法,主要有兩種:

第一種:

int main(int argc,char  **args)

這種寫法是最初c語言主函式的寫法。

第二種:

int main()

這種是簡化了的寫法,兩種寫法都可以,但是有許多學校的教學用的是:

void main()

這種寫法不符合c語言的標準。

2、關於常量變數

實型常量有兩種表示形式:

1.小數形式。由數字和小數點組成,必須有小數點。

例:4.23、0.15、.56、78.、0.0

2.指數形式:以冪的形式表示,以字母e或e後跟乙個以10為底的冪數。

(1)字母e或e之前必須要有數字。

(2)字母e或e後面的指數必須為整數,字母e或e的前後及數字之間不得有空格。

預設是double,如果數字後面加上就表示float 型,字尾「l」或「l」表示long double型。

例:2.3e5   500e-2   .5e3    4.5e0   34.2  .5  12.56l  2.5e3l

sizeof(); 運算子 計量單位位元組

int    4位元組     32位1個符號位,範圍:-2**31---2*31-1

float     4位元組    小數點後6---7位

double     8位元組     小數點15---16位

char     1     

不同作業系統可能會不同,可用運算子sizeof()來計量單位位元組。

值得注意的是long int與short int,這兩種變數型別的大小根據作業系統而定,唯一確定的是long型一定大於等於int型,short型一定小於int型。

在選擇資料型別時,在都可以的情況下,盡量選擇少的,因為將來如果使用者非常多的時候,可能是幾個位元組的上億次疊加。

unsigned作修飾符時,格式輸出為%u,可以達到節省字元的目的,但使用時要確保不會用到負數。

另外,關於c語言有沒有bool型別資料的問題,最初的89年版c語言是沒有的,但是c語言隔一段時間就會更新一次,99年版增加裡bool型別,但是現在大多數的編譯器都還是只支援89年版。

3、關於格式輸出

%.2f  保留小數點後兩位(四捨五入)

10.2f  10表示整個位數(小數點也算,只有大於資料原寬度情況下才有用)

%10d  同樣的,輸出的位數佔十位

另外,還有輸出一些特殊符號:

1)\t   出現的地方相當於出現裡tab鍵;

2)\r  換行;

3)\空格  代表空格;

4)\\  代表\;

5)\n   代表回車回車;

6)\"  代表";

7)\'   代表';

8)??   代表?;

9)%%   代表%

4)關於字元

大家都知道計算機儲存字元是儲存的ascii碼,說白了就是存的數字,不同數字代表不同字元,為了寫程式的方便,最好能記住一些常用字元的ascii碼。(所有的單字元都用符號' ',字串用「 」)

a--z  65 -- 90

a--z   97 -- 122

0--9   48 -- 57

5)關於型別轉換

出現不同位元組大小的變數型別進行運算的時候

將會擴充佔位元組小多大的資料

(自動型別轉化)。

出現不同型別運算,但是兩種型別佔空間大小一致,將表示精度小的資料型別,轉化為表示精度大的資料型別。

除了自動型別轉換,有時需要人為的進行型別轉換,稱為強制型別轉換。

例:(int)float 小數部分直接丟棄,不進行四捨五入

6)關於標準輸入函式scanf()

使用者在用鍵盤輸入資料時,資料並不是直接到達計算機記憶體,而是要經過乙個緩衝區。這就設計到乙個緩衝區殘餘問題。

舉個簡單的例子:

#include

int main()

**的本意是輸入兩個字元並列印,但是執行時會發現,當你輸完第乙個字元,回車後,螢幕上就會輸出你輸入的第乙個字元,然後換行。這是因為當輸入第乙個字元並回車後,字元被寫入,但是回車(\n)留在裡緩衝區,當遇到getchar時,被吸收了進去,如何沒有遇到getchar,這個回車會一直存在於緩衝區,很容易引發程式出錯。輸入完成後回車,這是無法避免的,如何解決這個問題?首先,可以在每乙個scanf()語句後面增加一句getchar();來吸收\n,但是,使用者在輸入的時候並不一定會按要求輸入乙個字元,可能是任意多個,這樣的話緩衝區會殘存許多字元,最常用的做法是在每乙個scanf()後面增加一句while(getchar()!='\n');

7)關於運算子

c=b+a++;    相當於c=b+a;a++

a+++b;相當於(a++)+b;

c=a>b?a:b;(唯一的三目運算子)先判斷a>bs是否成立,成立c取值於a,不成立取值於b。

運算子的運算方向:除了單目運算子和賦值運算子是從右向左,其餘都是從左向右。

,(逗號運算子)取值為右邊的值,但是左右的表示式都會執行,優先順序最低。

8)關於程式書寫

寫程式首考慮1、穩定性;2、可讀性;3、可維護性;4、效能

linux系統編譯程式時,它會報錯誤和警告,其中警告是分等級的,有些它認為不重要的警告使用gcc ***.c 命令不會報,要用gcc ***.c -wall來檢視,有些警告可能會造成輸出結果的不理想。

在寫if語句時,我們經常會寫if(a==0),當**非常長的時候,可能會寫成if(a=0),此時括號裡是賦值語句,為真,所以一定會執行if下的語句,不妨寫成if(0==a),這時當寫成if(0=a),程式就會報錯。

例:for(i=0;i<18;i++)   一般判斷的時候不寫=,因為像float這種型別是不精確的,使用等號容易錯過需要的數。

9)一些函式

程式執行時有時我們需要直接退出---exit(0);自然退出  exit(1);成功退出  exit(-1);失敗退出

index = rand()%5;   //0--4隨機取值

index =  rand()%91 + 10;  //90--100隨機取值

srand((unsigned)time(null));//將時間設定為隨機數種子,整個程式中只要有一次就好

10)最後

if switch不是函式,不屬於任何庫

for 適用於迴圈次數確定的場景

while  適用於迴圈次數不確定的場景

do while 總次數與while相同

contiune  結束當前一次迴圈

break  退出迴圈

c 中容易忽略的效能優化點

private static void main string args time console.readkey 使用 號連線字串時,值型別需要通過裝箱操作轉化為引用型別才可以新增到字串中。但是裝箱操作對效能影響較大,因為在進行這類處理時,將在託管堆中分配乙個新的物件,原有的值複製到新建立的物件中...

C 容易忽略的細節

1 超出資料型別指定長度的賦值 1 無符號資料型別 unsigned char ch1 336 unsigned char ch2 1 上面兩個賦值都超出了unsigned char 型別的範圍,大部分的編譯器對這種情況是這麼處理的 允許賦值,僅僅給出乙個警告,但是是經過modulo之後的值。cou...

C 容易忽略的特性

1 cin 標準輸入流物件,與標準輸入裝置相聯絡 通常指鍵盤 例如 cin 變數名 為提取運算子 輸入運算子 表示從鍵盤讀取資料放入變數中。2 cout 標準輸出流 流物件 與標準輸出裝置相聯絡 通常指顯示器 例如 cout 資料 為插入運算子 輸出運算子 表示將 資料 寫到顯示器上。3 cerr ...