# 大一程設精華
適用c
## 架構
跟你看書一樣從上往下,用{ }做為分區
```c=
#include <stdio.h> //函式導入
double pi = 3.1415926;
void a(){ //自定義
printf("haha\n");
}
int main(){ //主程式
while(1){
a();
}
}
```
## 型態
在程式中,型態不一定能互通,所以型態絕不能弄錯

* <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),初始定義的時候不一定要賦予值

```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是把資料讀出檔案,開檔的模式要注意不要用錯

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