# 大一程設精華 適用c ## 架構 跟你看書一樣從上往下,用{ }做為分區 ```c= #include <stdio.h> //函式導入 double pi = 3.1415926; void a(){ //自定義 printf("haha\n"); } int main(){ //主程式 while(1){ a(); } } ``` ## 型態 在程式中,型態不一定能互通,所以型態絕不能弄錯 ![image](https://hackmd.io/_uploads/r1rtFlsEa.png) * <font color="blue">int(整數)</font> 上限是$2^{31}-1 \to -2^{31}$,有時題目會說需要到long long int(64bit),數字放不下會overflow * <font color="blue">float(小數/浮點數)</font> using IEEE 754,假設答案壞掉可以換double(倍精度小數) * <font color="blue">char(字元)</font> 整數型態以ASCII碼或是其他編碼的實現 * <font color="blue">string(字串)</font> string可以視為一個裝了char的陣列 * <font color="red">資料轉型(補充)</font> 因為底層的資料是一樣的東西(2進制資料)可以直接用 **(目標型態)轉換前的值** 進行轉換 ### 全域VS區域 程式的分區由{ }構成,裡層可以讀外層,但外層不能使用裡層的東西,所以在main()外的東西慣稱為全域變數,至少一層{ }包圍的稱為區域變數 ### 保留字 會變色或是變粗體的大部分都是,在做變數定義的時候不能使用保留字,因為在系統中已經有定義了,不然使用的時候會error ## IO 輸入跟輸出,記得型態要放對,輸入要加&,後面會解釋為什麼 ```c= int n; long long m; scanf("%d", &n); scanf("%lld", &n); char a; char str[10]; scanf("%c", &a); scanf("%s", &str); float b; double c; scanf("%f", &b); scanf("%lf", &c); printf("hahaha\n"); ``` ### 字元操作 - \n -> 換行 - \t -> tab(空4格) - \b -> 倒退 - \r -> 回到行首(同home) ## 判斷 依據放入的判斷式或是物件進行判斷,成立(true)則執行,不成立(false)則跳過 - if...else... ```c= int a=10, b=20; if(a==b){ printf("yes"); }else if(a!=b){ printf("no"); }else{ printf("I dont know"); } ``` - switch ```c= int a; scanf("%d", &a); switch(a){ case 1: printf("1"); break; case 2: printf("2"); break; default: printf("none"); break; } ``` ### 邏輯運算 - && 且(and) - || 或(or) - & (bitwise and) - | (bitwise or) - ^ 互斥或(xor) - $\gt$ 大於 - $\lt$ 小於 - = 等於 - ! 反 (not) - ~ (bitwise not) ### 算術運算 $+ - * /$ % ## 迴圈 當條件成立時**重複執行**,直到不符合指定條件,或是手動break,基本上清一色的題目都會需要迴圈來執行 ```c= int a=10; for(int i=0;i<a;i++){ printf("haha\n"); } ``` ```c= int a=10; while(a--){ printf("haha\n"); } ``` ```c= int a=0; while(a++){ printf("haha\n"); if(a==100) break; } ``` ### EOF end of file,顧名思義是當檔案結束用的指令,當檔案正常輸入完會給一個指令讓程式結束,快捷鍵是ctrl+Z,在寫judge一定要注意(多筆測資的時候) ```c= int n; while(scanf("%d", &n)!=EOF){ printf("%d\n", n); } printf("end"); ``` ## 陣列 定義一串連續的記憶體來存放資料,使用索引來呼叫元素(element),初始定義的時候不一定要賦予值 ![image](https://hackmd.io/_uploads/ryyyYMHNT.png =500x) ```c= int n = 10; int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}; while (n--) { printf("%d ", a[n]); } ``` ```c= int n=10; int a[10]; while(n--){ scanf("%d", &a[n]); } n=10; while (n--) { printf("%d ", a[n]); } ``` ### 多維陣列 因為陣列是call by reference,所以[ ]的數量不會被限制 ```c= int a[10][10]; for(int i=0;i<10;i++) for(int j=0;j<10;j++) a[i][j] = (i+1)*(j+1); for(int i=0;i<10;i++){ for(int j=0;j<10;j++){ printf("%5d", a[i][j]); } printf("\n"); } ``` ## 字串 在程式語言中,字元(char)在定義時要用'',而由字元組成的字串則要用"",針對由char組成的陣列做處理,但原始的scanf讀到空格會停下,所以當需要輸入含空格的資料就要改用gets(),輸出可使用puts(); ```c= char str[]="hello world"; for(int i=0;i<strlen(str);i++) printf("%c", str[i]); printf("\n%s", str); ``` ```c= char str[20]; scanf("%s", &str); printf("%s", str); ``` ```c= char str[20]; gets(str); printf("%s", str); ``` ## 自訂函式 由型態衍生而來,定義函式的目的是要簡化程式,利用型態控制回傳值的型態,輸入的東西可以自由設定(區域變數),若不需要回傳可以使用void ```c= #include <stdio.h> void a(int n) { printf("%d haha\n", n); } int main() { int n = 10; while (n--) { a(n); } } ``` ### 遞迴 遞迴是利用自訂函式來做重複性的動作,目的在於提升易讀性以及邏輯性,但不建議拿來做重複性太高的事,因為空間會爆掉(變數會重複定義) ```c= #include <stdio.h> int cal(int a) { if (a == 1) return 1; else return a + cal(a - 1); } int main() { int a ; scanf("%d", &a); printf("%d", cal(a)); } ``` ## 指標 直接使用記憶體位置進行運算,指標通常會拿來傳輸值的位置,陣列的定義其實就是在記憶體中割出一塊區域,陣列的元素其實就各代表了區域中的位址 &代表reference (參照),他會取出變數的位址,而$*$則是dereference(解參照),他會取出位址下的值,printf要用&也是因為他是把值讀進來之後直接放到指定變數的位址下面 ```c= #include <stdio.h> void swap(int a, int b) { //call the value int tmp = a; a=b; b=tmp; } int main() { int a=10,b=20; swap(a,b); printf("%d %d", a, b); } ``` ```c= #include <stdio.h> void swap(int &a, int &b) { //call the reference int tmp = a; a = b; b = tmp; } int main() { int a = 10, b = 20; swap(a, b); printf("%d %d", a, b); } ``` ## 動態定義 當陣列太大時(通常上限是10000),就需要把陣列改成動態定義,不然高機率會記憶體區段錯誤,並用原始的定義進行(指標) ```c= #include <stdlib.h> int *a = (int*)malloc(sizeof(int)*10000); ``` ## 結構 當單一變數型態不能滿足你的需求時,便可以用struct把他們包在一起,再配合typedef便可以簡化變數的定義和複雜度 ```c= // Online C compiler to run C program online #include <stdio.h> struct pair{ int x; char y; }; int main() { // Write C code here int a=10; char b='a'; struct pair p; p.x=a; p.y=b; printf("%d %c", p.x, p.y); } ``` ```c= // Online C compiler to run C program online #include <stdio.h> typedef struct Pair{ int x; int y; }pair; int main() { // Write C code here int a=10, b=20; pair p; p.x=a; p.y=b; printf("%d %d", p.x, p.y); } ``` ## 讀檔 對txt檔進行讀寫,讀取和原本的IO很像,只是對象不一樣,fprint是把資料寫進檔案,fget是把資料讀出檔案,開檔的模式要注意不要用錯 ![](https://hackmd.io/_uploads/Bk_XQlWHp.png) ```c= #include <stdio.h> //建檔+寫入 int main(){ //開始使用前,設定file文件指針並以w+(讀寫)模式開檔 //不存在則新增檔案 FILE *fptr = fopen("TheTXT.txt","w+"); if(!fptr) { perror("檔案開啟失敗"); // 將訊息輸出至 stderr return -1; } //寫入檔案 fprintf(fptr,"haha"); //程式結束前閉檔 fclose(fptr); return 0; } ``` ```c= #include <stdio.h> int main(){ //開始使用前,設定file文件指針並以r+(讀)模式開檔 FILE *fptr = fopen("TheTXT.txt","r+"); if(!fptr) { perror("檔案開啟失敗"); // 將訊息輸出至 stderr return -1; } char c; while ((c = fgetc(fptr)) != EOF) { putchar(c); } //程式結束前閉檔 fclose(fptr); return 0; } ``` ## 綜合練習 使用zerojudge做練習,強烈建議先使用學號或學校Email當帳號,大二用的到,下面的題目已有包含前幾屆的考古題,~~很閒的也可以去[dandanjudge](http://203.64.191.163/)看看閒人都出些什麼題目~~ - IO [a001. 哈囉](https://zerojudge.tw/ShowProblem?problemid=a001) - 判斷 [b682. 2. 同學早安](https://zerojudge.tw/ShowProblem?problemid=b682) [b758. 牛仔(ㄗˇ)很忙](https://zerojudge.tw/ShowProblem?problemid=b758) [c461. apcs 邏輯運算子 (Logic Operators)](https://zerojudge.tw/ShowProblem?problemid=c461) [d064. ㄑㄧˊ 數?](https://zerojudge.tw/ShowProblem?problemid=d064) [d073. 分組報告](https://zerojudge.tw/ShowProblem?problemid=d073) - 迴圈 [a040. 阿姆斯壯數](https://zerojudge.tw/ShowProblem?problemid=a040) [a024. 最大公因數(GCD)](https://zerojudge.tw/ShowProblem?problemid=a024) [a216. 數數愛明明](https://zerojudge.tw/ShowProblem?problemid=a216) [a065. 提款卡密碼](https://zerojudge.tw/ShowProblem?problemid=a065) [a059. 完全平方和](https://zerojudge.tw/ShowProblem?problemid=a059) - 字串 [b532. 字串處理](https://zerojudge.tw/ShowProblem?problemid=b532) [a022. 迴文](https://zerojudge.tw/ShowProblem?problemid=a022) - 陣列 [f345. 新手練習題—陣列](https://zerojudge.tw/ShowProblem?problemid=f345) [a015. 矩陣的翻轉](https://zerojudge.tw/ShowProblem?problemid=a015) [a915. 二维点排序](https://zerojudge.tw/ShowProblem?problemid=a915) - 遞迴 [e156. 良心題: 求和](https://zerojudge.tw/ShowProblem?problemid=e156) [e357. 遞迴函數練習](https://zerojudge.tw/ShowProblem?problemid=e357) [f928. 連環炸彈.................Boom!](https://zerojudge.tw/ShowProblem?problemid=f928) - 綜合練習 [e795. p2.質數日](https://zerojudge.tw/ShowProblem?problemid=e795) [b266. 矩陣翻轉](https://zerojudge.tw/ShowProblem?problemid=b266) [c120. 00623 - 500!](https://zerojudge.tw/ShowProblem?problemid=c120) [d190. 11462 - Age Sort](https://zerojudge.tw/ShowProblem?problemid=d190) [c431. Sort ! Sort ! Sort !](https://zerojudge.tw/ShowProblem?problemid=c431) 還想多練習可以使用標籤去搜尋題目,或是看動態列大家都在解些什麼題目 ## REF [程設例會PPT](/TaFubHEcTv6hRf3ySIFTig) [online compiler](https://www.programiz.com/c-programming/online-compiler/) [文字檔案 I/O](https://openhome.cc/Gossip/CGossip/FileIO.html)