---
# System prepended metadata

title: C程式語言設計_1.0

---

# 零---補充
## 一、基本運算子




1. 邏輯

運算符號： \+ \- \* \/ %(取餘數





| 運算子 | 意義   |
| ------ | ------ |
| &&     | AND,且 |
| \|\|       |  OR,或      |
|   !     |    NOT,否    |

## 二、其他常用的運算子

1. 增遞/減遞運算




| 運算子 |    意義    |
|:------:|:----------:|
|   ++   | 變數值加 1 |
|  - -   | 變數值減 1 |

* i++：先執行整個敘述後, 再將 i 的值加 1
* ++i：先將 i 的值加 1, 再執行整個敘述
2.




| 運算子(?:) | 意義 |
| -------- | -------- |
| 條件判斷 ? 運算式 1 : 運算式 2||
```
if(判斷條件)
運算式 1;
else
運算式 2;
```

| 實例1                  | 實例2 |
| ---------------------- | ----- |
| a = (x > 100) ? b : c; |  abs = (a > 0) ? a : -a; |
```
if (a > 0)
 abs = a;
else
 abs = -a; 
```





---

# 壹、格式化的輸入與輸出
```
#include <stdio.h>#將檔案<stdio.h>將進來
int main(){
    printf("Hello world!");
    return 0;
}
```
[https://web.fg.tp.edu.tw/~earth/vision/study/cprogram06/C_handout.pdf](https://)
##   一、標準輸出指令
`printf("格式字串", N1, N2,...);`

`scanf("格式字串",&N1,&N2,...);`

### Printf
```
int main(){
	int a = 1 ;
	printf("Hello \n%d", a);
	return 0; 
} 
```
### Scanf

```
int main(){
	int a,b;
	scanf("%d%d",&a,&b);
	printf("%d,%d",a,b);
}
```
* 注意!如果要讀取字元陣列時，`str`它被當作指向字串的指標使用，所以在 scanf 函式中，我們直接使用陣列名稱 str 來讀取字串。因為 str 已經是一個指向陣列的指標，使用 & 運算子會導致類型不匹配
> 字串為字元的陣列
##    二、跳脫字元(Escape Sequence)
  
  



| \n 換行               | \\" 雙引號           | \\' 單引號 |         |
| --------------------- | -------------------- | ---------- | ------- |
| \f 換頁               | \t 跳格              | \b 倒退    |         |
| \x ASCII 碼 (16 進位) | \d ASCII 碼 (8 進位) | \\\ 反斜線 | \\/ 斜線 |

**例子 執行結果**
```
printf("\tThis line begins with tab.\n");
printf("It\'s a \"C Tutorial\".\n");
printf("This is backslash: \\.\n");
printf("\\101 is \101.\n");
printf("\\x41 is \x41.\n");
```
>  This line begins with tab.
> It's a "C Tutorial".
> This is backslash: \.
> \101 is A.
> \x41 is A.
## 三、修飾子










| -：向左靠齊 | +：印出正負號 | %c：字元 |
| -------- | -------- | -------- |
|    %s：字串     %d：十進位整數 |    %f：浮點數 (小數點型式)      |   %l：長整數，加在 d、u…之前       |
| %u：無號十進位整數     | %e：浮點數 (指數 e 型式)      | Nope     |




---

# 貳、流程控制


## 一、if 指令
### 巨集
> define name 函式
```
#define MAX(a, b) (a>b ? a:b)
int main(){
	int x, y;
	printf("輸入N1:");
	scanf("%d",&x);
	printf("輸入N2:");
	scanf("%d",&y);
	printf("兩數最大值為:%d\n",MAX(x, y));
}
```
```
if (條件判斷式)
{
    指令1;
    ...2;
    ...3;
    .....
}
```

```
```
### 單一條件不用加{}
```
if (條件判斷)
    指令1 ;
```

### ALL
```
int main(){
	int a;
	printf("輸入成績:");
	scanf("%d",&a);
	if (a>=60 && a<=100)
		printf("及格\n");
	
	else if (a>100)
		printf("error!\n");
	
	else
		printf("不及格\n");
}
```
## 二、switch指令
### case、default


---

 ![](https://hackmd.io/_uploads/HJSMQ-39h.png)

 

---


範例題：
> 依據下列表格中的等級表，使用switch完成分數的判斷，且在使用者輸入成績後顯示出等級

| 等第 |  分數 |
|:--------:|:--------:|
|    A     |  90~100  |
|    B     |  80~90   |
|    C     |  70~79   |
|    D     |  60~69   |
|    E     |   0~59   |

```
switch (運算式)
{
     case 選擇值 1:
         敘述主體 1;
         break;
     case 選擇值 2:
         敘述主體 2;
         break;
     …
     case 選擇值 n:
         敘述主體 n;
         break;
     default:
         敘述主體;
} 
```
Answer:
```
int main(){
	int a;
	
	printf("輸入成績:");
	scanf("%d",&a);
	
	switch ( a/10 ){
		case 10:
            printf("A");
            break;
		case 9:
			printf("A");
			break;
		case 8:
			printf("B");
			break;
		case 7:
			printf("C");
			break;
		case 6:
			printf("D");
			break;
		case 0 ... 5:  /* gcc擴充套件允許對比特定範圍 (0~5)*\
			printf("E");
			break;
	}
}
```
### for 迴圈
```
for(變數起始1;條件;變數增減){

    程式1;

    for(變數起始2;條件;變數增減){
    
        程式2;
    }

}
```
### while
```
while(條件判斷){

    程式區;

}
```
### do-while (後測試型迴圈)
> do裡的程式碼會被先執行一次
```
do{

    :
    程式區;

}
    while(條件判斷);
```
### break、continue
* break跳脫迴圈不再執行下列程式
* continue持續執行迴圈並跳過下列程式
# 參、陣列、字串、矩陣、結構與檔案
## 一、陣列
### 一維
* 元素個數可未設定(自動)
* 超過個數長度時將自動設定為0
```
int arr[] = {
    [0] = 3,
    [1] = 4,
    [2] = 5,
    [3] = 6,
    [4] = 7,
};
```
```
資料型態 陣列名稱 [長度];
```
或者
```
資料型態 陣列名稱 [大小]={初始值1,..2,..3,...};
```
### 二維
* 若初始值個數少於設定長度其餘將設定為0
* c/c++以列為主軸


|   x   |  行[0]  |  行[1]  |  行[2]  |
|:-----:|:----:|:----:|:----:|
| 列[0] |  [0][0]    |  [0][1]   | [0][2]     |
| 列[1] | [1][0] | [1][1] | [1][2] |

```
資料型態 陣列名稱 [列個數] [行個數];
```
```
資料型態 陣列名稱 [列個數] [行個數] ={{var1,var2,var3},{var4,var5,var6}};
```


## 二、結構
### struct
```
struct 結構名稱
{
    資料型態 成員1;
    資料型態 成員2;
    ......

}s1,s2;
```
* 定義結構變數

`struct name s1,s2;`

* 點運算子(用於存取)

`結構變數.成員名稱;`

* 成績&名子

```
int main(){
	struct rank
	{
		char name[10];
		int score;

	} s1,s2 ;
	
	strcpy(s1.name,"KATE");
	s1.score = 900;
	s2 = s1;
	printf("%s%d",s2.name,s2.score);
	return 0;
}
```
### 巢狀struct
```
struct 結構名稱1
{
    資料型態 成員1;
    資料型態 成員2;
    ......

};
struct 結構名稱2
{
    
    ......
    struct 結構名稱1 變數名稱;

};
```
### 結構陣列
* 宣告


`struct 結構名稱 陣列名稱 [長度];`

* 存取

`陣列名稱 [索引值].陣列成員名稱`
```
struct 結構名稱
{
    
    ......
    資料型態 陣列名稱 [個數];

};
```
`struct 結構名稱 陣列名稱 [個數];`
* 存取

`陣列名稱 [索引值].陣列成員名稱[索引值]`

* 下圖為建立5個元素的結構陣列

```
struct student
{
    char name[10];
    int score;

};
struct student class1[5];
```


---

# 演算法_
> 具有時效性，不會形成無窮迴圈
* ## 分治演算法
>  將一個大問題拆解成許多的子問題
>  再由各子問題的**解**合併出答案
* ## 遞迴演算法
### 1. 費伯納數列
* 直接遞迴
> 在遞迴函數中直接呼叫本身
 
```
 int Fun(...)
{
    ...
        if(...)
            Fun(...)
    ...
}
```
* 間接遞迴
> 在遞迴函數中呼叫其他遞迴，再從其他遞迴呼叫回遞迴函數。

```
int Fun(...)        
{
    .
    if(...)
        Fun2(...)
        ...
}
int Fun2(...)
{
    .
    if (...)
        Fun(...)
        ...
}
```
For example:
```
n! =nX(n-1) * (n-2) .....*1
```
code
```
int factorial(int i)
{
    
   int sum;
   if (i==0) /*終結*\
   {
    return(1); 
   }
   else
    {
        sum = i*factorial(i-1); /*sum =n*(n-1)*\
    }
    return sum;
}
```
For example2:
> 第零項為0 第一項為1，每個項目皆由前兩項相加所得的數_費伯納序列(Fibonacci)。

code
```
int fib(int n)
{
    
    if (n==0) return 0;
    if (n==1) return 1;
    else
        return fib(n-1)+fib(n-2);/*呼叫兩次*/
}
```
### 2.河內塔問題
#### 結論：
> 步驟1: 將n-1盤子，從木樁1移到2
> 步驟2: 移動第n個最大的盤子，從木樁1移到3
> 步驟3: 將n-1盤子，從木樁2移到3
#### 限制:
> 1. 直徑較小套環永遠置於直徑較大的上方
> 2. 套還可隨意從木樁移到其他木樁
> 3. 每一次僅能移動一個套環，且為最上面開始移動

![](https://hackmd.io/_uploads/rkeJDhe1a.png)

#### code:


```c
#include<stdio.h>
void hanoi(int n, int p1, int p2, int p3)
{
    if (n==1) /*出口*/
        printf("第%d個套環從 %d 移到 %d\n",n,p1,p3);
    else
    {
        hanoi(n-1,p1,p3,p2);
        printf("第%d個套環從 %d 移到 %d\n",n,p1,p3);
        hanoi(n-1,p2,p1,p3);
    }
}

int main()
{
    int n = 3; // 套環的數量
    hanoi(n, 1, 2, 3); // 從柱子1移動到柱子3，使用柱子2作為中介
    return 0;
}

```
### 3.選擇排序
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int data[N];
int main(void) {
	srand(time(NULL));
	int i,j,k,p,tmp;
	for(i=0; i<N ; i++){
		data[i] =rand()%100;
	}
	for(i=0; i<N ; i++){
		printf("%d ",data[i]);
	}
	k=0;
	for(j=0;j<N-1;j++)
	{
		for(i=j+1 ; i<N ; i++){
			if(data[i]<data[k])
				k=i;
		}
		tmp=data[j];
		data[j]=data[k];
		data[k]=tmp;
	}
	
		
	
	printf("\n");
	for(i=0; i<N ; i++){
		printf("%d ",data[i]);
	}
}
```
### 4.插入排序
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 10
int data[N];
int main(void) {
	srand(time(NULL));
	int i,j,k,p,tmp;
	for(i=0; i<N ; i++){
		data[i] =rand()%100;
	}
	for(i=0; i<N ; i++){
		printf("%3d ",data[i]);
	}
	printf("\n");
	
	
	for(j=1;j<N;j++)
	{
		tmp=data[j];
		for(i=j;i>0;i--){
			if(data[i-1]>data[i]){
				data[i] =data[i-1];
				data[i-1]=tmp;
			}
			else
				break;
		}
		for(i=0; i<N ; i++){
			printf("%3d ",data[i]);
		}
		printf("\n");
	} 
	
		
	
	
	
}

```
### 5.各類排序
```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h> 
int N;

int data[1000000];
int test[1000000];

void bubble_sort(int,int);		//氣泡排序 
void selection_sort(int,int);	//選擇排序 
void merge_sort(int,int);
void show_test();		//顯示 test 陣列結果 


int main(void){
	printf("請輸入要產生的數量(1000000以內)： ");
	scanf("%d",&N);
	if(N>=2000000){ printf("數量太大");	return 0;	}
	
	clock_t start_t;	
	srand(time(NULL));
	int i,j,k,p,tmp;	
	for(i=0; i< N; i++)	data[i]=(rand()%30000)*(rand()%30000);	//產生資料 

	for(i=0; i< N; i++)	test[i]=data[i];	//恢復資料 
	start_t = clock();	//開始計時 
	merge_sort(0,N-1);	//排序ing... 
	printf("合併排序： %.3f\n", (double)(clock() - start_t) / CLOCKS_PER_SEC);
	
	for(i=0; i< N; i++)	test[i]=data[i];	//恢復資料 
	start_t = clock();	//開始計時 
	bubble_sort(0,N-1);	//排序ing... 
	printf("氣泡排序： %.3f\n", (double)(clock() - start_t) / CLOCKS_PER_SEC);
	
	for(i=0; i< N; i++)	test[i]=data[i];	//恢復資料 
	start_t = clock();	//開始計時 
	selection_sort(0,N-1);	//排序ing... 
	printf("選擇排序： %.3f\n", (double)(clock() - start_t) / CLOCKS_PER_SEC);
	
	
}
void show_test(){
	int a;
	for(a=0;a<N;a++)
		printf("%d ",test[a]);	
	printf("\n");
}

void bubble_sort(int a,int b){
	int i,j,k,tmp;
	for(i=b;i>0;i--){
		for(j=1;j<=i;j++){
			if(test[j-1]>test[j]){				
				tmp=test[j-1],test[j-1]=test[j],test[j]=tmp;				
			}
		}
	}
}

void selection_sort(int a,int b){
	int i,j,k,tmp;
	for(i=a;i<=b;i++){		
		k=i;
		for(j=i+1;j<=b;j++){
			if(test[j]<test[k]){				
				k=j;				
			}
		}
		
		tmp=test[i],test[i]=test[k],test[k]=tmp;
	}
}
int result[1000000];

void merge_sort(int L, int R)
{
	if(L==R) return;

	
	int M=(L+R)/2;
	
	merge_sort(L,M);
	merge_sort(M+1,R);
	
	
	int i=L,j=M+1,p=L;

	while(i<=M && j<=R)
	{
		if(j>R || (i<=M && test[i]<test[j]))
		{
			result[p]=test[i];
			i++;
		}
		else
		{
			result[p]=test[j];
			j++;
		}
		p++;
	}
	for(i=L;i<=R;i++)
	{
		test[i]=result[i];
	}
}
```