440 likes | 514 Views
今日目標. 複習進度 小考及作業 題目練習. 個人化你的 Dev-C++. 一個美好的編輯器. 舒服最重要~微調 Dev-C++. 一般設定. 顯示設定. 語法配色. 右鍵貼上測資 – 快速編輯模式. 簡易漂亮縮排法. 同一區塊的程式敘述對齊 若 B 區塊包含於 A 區塊,則 B 區塊往後縮排一單位 EX for( i =0;i< n;i ++){ a[ i ]= i ; if(a[ i ]== i ){ a[ i ]=0; } }. 了解程式區段、區域變數與全域變數. 當區域變數與全域變數 糾結在一起. 程式區塊.
E N D
今日目標 • 複習進度 • 小考及作業 • 題目練習
個人化你的Dev-C++ 一個美好的編輯器
簡易漂亮縮排法 • 同一區塊的程式敘述對齊 • 若B區塊包含於A區塊,則B區塊往後縮排一單位 • EXfor(i=0;i<n;i++){ a[i]=i; if(a[i]==i){a[i]=0;}}
了解程式區段、區域變數與全域變數 當區域變數與全域變數糾結在一起
程式區塊 • C以{ statement;}來表示一塊塊的程式區塊,在許多語法中會也與其串接 • Exif(true) do sth. // 只做這件事 if(true){ do sth1.// 做了這些事 do sth2.}
區域變數的作用範圍 • C是區塊式結構的程式語言,每個由大括弧所組成的區塊都是一個獨立的結構。 • 在每一個區塊,C會建立一個獨立的命名空間,使用者可以在這個命名空間內對變數任意取名字(但不能與保留字衝突,也不能取相同的名字),但到區塊外就無法存取了。 • 區塊內的變數又稱為區域變數,所能作用的範圍只有該區塊內。
區域變數的作用範圍 • {intx,y; x=1; y=2;}int x;x=?;y=2; Question 1:第一個x與第二個x一樣嗎 Question 2:第二個y存在嗎?
區域變數的好處 • 1. 只存活於自己作用的區段,不會在不需要的區段出現,也不會有誤用的情況。 • 2. 區段結束後記憶體會自動釋放。 • 3.除錯容易
全域變數 • 在函數之外宣告的變數被稱為全域變數。 • 全域變數自宣告後,一直存在,直到程式結束為止。 • 在整個程式中,一個全域變數的名稱只能被宣告一次。 • 全域變數的作用範圍從宣告處開始,直到檔案的結束。
全域變數的作用範圍 • void Function(){ x=2;}int x;int main(){ x=1; return 0;} Question:這樣的程式會通過編譯嗎?
全域變數的好處 • 1.減少函數輸入的引數 • 2.能使用較大的記憶體
變數常犯的錯誤 • 當區域變數與全域變數有相同的名稱時,編譯器並不會出現編譯錯誤,但常常會因此而出問題。 • int n;int main(){int n;scanf(“%d”,n);}
各類迴圈 1+1+1+….+1=N*1
while • while(判斷式){程式敘述; ...} 是 迴圈內程式敘述 檢察判斷式是否為真 否 執行迴圈之後的敘述
do…while • do {程式敘述; ...}while(判斷式); 迴圈內程式敘述 是 迴圈內程式敘述 檢察判斷式是否為真 否 執行迴圈之後的敘述
for • for(起始式;判斷式;運算式){程式敘述; …} 起始式 迴圈內程式敘述 是 檢查判斷式是否為真 運算式 否 執行迴圈之後的敘述
break; 與 continue; • 在迴圈敘述中,break;會直接跳出迴圈,執行迴圈之後的程式敘述。 • 而continue;則是會直接跳到該次迴圈的最尾端(PS.若為for迴圈仍會執行運算式)
陣列 • 型態 陣列名稱[元素個數]; • 宣告時元素個數要為常數,盡量不要以變數當作元素個數。 • 陣列占用的是連續的記憶體。 • EX:int array[1000];
多維陣列 • 型態 陣列名稱[元素個數1] [元素個數2]…[元素個數n]; • 多維陣列占用的依然是連續的記憶體 • EX:int A[100][100];
指標 • 指向變數的型態 *指標名稱; • 一種指向記憶體位置的變數
取位置的& • 要對一般變數找到其在記憶體上的位置,只需在變數的前加上&即可。 • &不能加在指標的前面,&指標,代表指標在記憶體上的位置。 • EX:int a=2;int *ptr;ptr=&a;
取值的* • 要對一個指標找到其在記憶體上變數的值,只需在指標的前加上*即可。 • *不能加在一般變數的前面,否則會編譯錯誤。 • EX:int a;int *ptr;ptr=&a;*ptr=2;
指標的型態 • 指標只是指向記憶體的一個變數,型態對其來說並不重要 • 會影響到的只有取值以及運算的時候。
指標NULL不可以取值 • NULL不指向任何地方,故不會有值,所以對NULL取值的話會記憶體存取錯誤。
陣列與指標 • 陣列所用的是一段連續的記憶體,而陣列的另外一個含意就是指向記憶體的指標。 • 例如有一個陣列A[m],則A指向變數A[0]的位置,A+i指向A[i]的位置,又如有一個陣列A[m][n],則A指向A[0][0]的位置,A+i*n+j指向A[i][j]的位置。 • 但不可以將陣列像一般指標一樣指向其他的記憶體。
函數 • 回傳值型態 函數名稱(型態1 引數1,型態2 引數2,…){ … return 回傳值;} • 為依據每次的引數進行相同操作,並回傳結果的一個程式區塊。 • 若回傳值型態為void時不須回傳任何東西。
遞迴函數 • 遞迴函數是呼叫自己的函數 • 通常會將問題切割成許多小問題在交由函數繼續遞回下去解決 • EXint FAB(int x){ if(x==1) return 1; else if(x==2) return 2; return FAB(x-1)+FAB(x-2);}
遞迴常見的問題 • 1. 函數沒有回傳值 • 2. 遞迴沒有結束條件 • 3. 遞迴的引數出錯 • 4. 遞迴使用了不同函式的變數 • 5. 變數名稱與全域函數相同 • 6. 邊界回傳值不正確(以上感謝silentvow學長整理)
qsort() • qsort(第一個元素的指標,元素的個數,每個元素所占用的byte數,比較函式);
qsort() • intcmp(const void* a元素的指標,const void* b元素的指標){int *A=(int*)a;int *B=(int*)b;若a的順位在b前面回傳負值;若a的順位在b後面回傳正值;若a的順位跟b一樣回傳0;}
字串 • C的字串以字元(char型態)陣列表示並以字元’\0’表示字串結束 • 需要注意開char陣列時要多留一個位置給’\0’
gets與puts • char *gets( char *str ); • 讀入字元直到換行或EOF(讀完一整行) • 會回傳讀入字串的位置 • 若讀到EOF會回傳NULL • int puts( char *str ); • 印出一字串並換行 • 若印出成功回傳一非負整數 • 若印出失敗回傳EOF
strcmp與strncmp • intstrcmp( const char *str1, const char *str2 ); • 比較兩字串 • 若兩字串相同則回傳0 • 若str1的字典順序較小回傳一負整數 • 若str1的字串順序較大回傳一正整數 • intstrncmp( const char *str1, const char *str2, size_t count ); • 與strcmp相同,不過只比較前count個字元
strcpy與strncpy • char *strcpy( char *dest, const char *src ); • char *strncpy( char *to, const char *from, size_t count ); • strcpy是將一個字串複製到另外一個字串 • 而strncpy是將一個字串的前count個字元複製到另一個字串,但需要注意的是,複製過去後並不會補上’\0’
strtol • long strtol( const char *start, char **end, int base ); • strtol可以用來分割字串裡面的多個數字 • start為字串的指標 • end為第一個數字之後的部分 • 當end變成NULL時,代表已經取完了
strlen • size_tstrlen( char *str ); • strlen會回傳字串的長度 • 需要特別注意放入的指標不可以是NULL • EXchar str[]=“hello”;len=strlen(str);
memset • void* memset( void* buffer, intch, size_t count ); • memset將會將記憶體的某一個區段都填上某一個值,可用來幫助初始化 • 注意:只能用來初始化0或-1(想想計概的表示法) • EXmemset(array,0,sizeof(array));
題目練習 • UVaOnline Judgehttp://uva.onlinejudge.org/ • Q272,Q458,Q494 • Q10062,Q10222 • 翻譯http://www.csie.ntu.edu.tw/~b97115/luckycat/