# 這是C課程的共筆
請慢慢享用 d\(\`・∀・)b
## 輸出輸入
scanf("輸入資料型態",儲存用的變數)
資料型態可在下文的 ***輸出格式->百分比符號%*** 找到
儲存的變數前面要加 **&**
printf("輸出的文字",變數)
範例程式如下 :
```c=
//輸入
int input_number; //設定變數
scanf("%d",&input_number) //輸入input_number的值
//輸出
printf("My IG is leo.is.an.egg")
//輸出 My IG is leo.is.an.egg
printf("The number is %d",input_number)
//輸出 The number is [x] ([x]為輸入的值)
```
---
## 設定變數
在任何程式語言中,我們都要設定變數
以下 C 語言設定變數的方式
```c=
//資型型態 變數名稱
int number;
//建立變數值後,我們可以設定其數值
number = 1 //設定 number 為 1
number += 1 //number 加 1
number -= 1 //number 減 1
scanf("%d",&number) //輸入number的值
//也可以這樣直接在設立變數時設定數值
int answer = 100;
```
:::warning
變數常見型態
| 資料型態| 關鍵字 |資料最大值|
| -------- | -------- | -------- |
|很小的整數|short|+-2^16^|
|整數|int|+-2^32^|
|更大的整數|long|+-2^63^|
|超大的整數|long long|+-2^127^|
|浮點數|float|+-10^38^|
|更大的浮點數|double|+-10^308^|
|字元|char|一個字符|
:::
(注意:char字元只能有一個英文字母或符號,你可以用char[50]來輸入字串)
此外,變數也全域變數和區域變數兩種,全域變數可使用在任何地方,區域變數通常只能使用在一個函式內
```c=
#include <stdio.h>
int ans = 1; //全域變數
void print(){
printf("%d",ans); //1
printf("%d",ans1);
//* 函式出錯,因為 ans1 為區域變數,無法運用在此函式中 *//
}
int main(void) {
printf("%d",ans); //1
int ans1 = 2; //區域變數
print()
}
```
---
## 陣列
若一次要輸入多個元素,可以使用陣列
在此筆記中,只會出現正規的陣列使用方法以方便理解
### 一維陣列
變數型態 陣列名稱[ 陣列長度 ] = { 陣列內容 } ;
```c=
#include <stdio.h>
int main(){
int list[]; //建立一個二維陣列,不宣告起始長度值
/* 此陣列可像 c++ vector 一樣自動添加儲存空間*/
list[0] = 1; list[1] = 2; list[2] = 3; //設定陣列的值
int list1[3] = {1,2,3}; //建立一個陣列,宣告起始長度為3,起始元素為{1,2,3}
printf("%d - %d - %d",list[0],list1[1],list[2]) //列印陣列中的值
// 1 - 2 - 3
/*陣列也可拿來建立字串*/
char word[] = "pizza";
printf("%s",word); //列印字串
// pizza
}
```
### 多維陣列
```c=
#include <stdio.h>
int main(){
int list1[][]; //建立一個二維陣列
int list2[][][]; //建立一個三維陣列
list1[0][0] = 1; list1[0][1] = 2;
list1[1][0] = 3; list1[1][1] = 4;
//設定陣列中的值
//陣列內的值如下
// +---+---+
// | 1 | 2 |
// +---+---+
// | 3 | 4 |
// +---+---+
int list3[2][2]={{1,2},{3,4}}; //建立一個二維陣列,並設定裡面的數值
char list4[2][]={"pizza","hamburger"}; //建立一個一維字串陣列,並設定裡面的字串
printf("%d - %d",list1[0][0],list3[0][0]); // 1 - 1
printf("%s and %s",list4[0],list4[1]); // pizza and hamburger
}
```
## 輸出與輸入格式
### 反斜線 \ (字元字面常量)
字元字面常量是以單引號來包括一個字元,例如 'A'、'1' 都表示一個字元字面常量,而有一些字元與C中所使用的相同,例如 “、'、\ 等,要在程式中 表現這些字元則要使用轉義序列(escape sequence),即 \"、\'、\\,其他還有一些不可見字元,也要以轉義序列來表示
:::spoiler 這是常見的轉譯序列格式 :
* \n:換行、新行(newline)
* \t:水平定位點(horizontal tab)
* \v:垂直定位點(vertical tab)
* \b:退回一格(backspace)
* \r:返回(carriage return)
* \f:換頁(formfeed)
* \a:嗶聲(alert bell)
* \\:倒斜線(backslash)
* \?:問號
* \':單引號
* \": 雙引號
* \nnn:nnn 為一到三個 8 進位數字,表示字元編碼,例如 \115
* \xnn.:nn 為多個 16 進位數字,表示字元編碼,通常用兩個數字,例如 \xb4\xfa,
* \unnnn:Unicode 碼點 U+nnnn 表示(C99)
* \Unnnnnnnn:Unicode 碼點 U+nnnnnnnn 表示(C99)
:::
(初學者基本只會用到 \n XD )
.
### 百分比符號 % (格式指定字)
如果在使用 printf 時要指定整數、浮點數、字元等進行顯示,要配合格式指定字(format specifier)
:::spoiler 以下列出幾個可用的格式指定碼:
%c:以字元方式輸出
%d:10 進位整數輸出
%o:以 8 進位整數方式輸出
%u:無號整數輸出
%x、%X:將整數以 16 進位方式輸出
%f:浮點數輸出
%e、%E:使用科學記號顯示浮點數
%g、%G:浮點數輸出,取 %f 或 %e(%f 或 %E),看哪個表示精簡
%%:顯示 %
%s:字串輸出
%lu:long unsigned 型態的整數
%p:指標型態
:::
---
## 運算字和邏輯門
對於變數,我們可以使用邏輯門去判斷大小、資料是否相等 等等資料
:::warning
C語言中沒有布林值,所以一般 true = 1 , false = 0
true也可以是>0的數字,fasle也可以是<=0的數字
C++有布林值,True跟False
:::
### 大於小於等於
|大於|小於|等於|
|-|-|-|
|>|<|=|
|大於等於|小於等於|不等於|
|>=|<=|!=|
:::spoiler 以下是範例程式碼 :
```c=
#include <stdio.h>
int main() {
int x=1,y=2;
printf("%d",x>y); //0
printf("%d",x>=y); //0
printf("%d",x<y); //1
printf("%d",x<=y); //1
printf("%d",x==y); //0
printf("%d",x!=y); //1
}
```
:::
### 邏輯門
| 名稱 | 使用方式 | 特性 |
| ---- | -------- | ---- |
| 且門 | && | 當兩者都是true時輸出true, 兩者其中之一不是true時, 輸出false |
| 或門 | \| \| | 當兩者其中之一是true時輸出true, 兩者都不是true時, 輸出false|
| 反或門| ^ |當兩者都是true/false時輸出true, 其餘輸出false|
| 非門 | !| 輸入是 true 時輸出 false, 輸入是 false 時輸出 true |
:::spoiler 以下是範歷程式碼:
```c=
#include <stdio.h>
int main(void) {
x=1,y=0 //1=true 0=false
printf("%d",x&&x); //1
printf("%d",x&&y); //0
printf("%d",y&&y); //0
printf("%d",x||x); //1
printf("%d",x||y); //1
printf("%d",y||y); //0
printf("%d",!x); //0
printf("%d",!y); //1
}
```
:::
---
## 條件判斷式
### if else
當判斷式內的內容為 True,執行函式內的內容,否則跳到下一個else處
```c=
#include <stdio.h>
int main(void) {
int x=0;
if(x==0){printf("A");} //因為 x==0 輸出 A
else if(x==1){printf("B");} //不會輸出
else{print("C")} //不會輸出
int x=1;
if(x==0){printf("A");} //因為 x!=0 不會輸出,並跳到下一個else
else if(x==1){printf("B");} //因為 x==1 輸出 B
else{print("C")} //不會輸出
x=2;
if(x==0){printf("A");} //因為 x!=0 不會輸出,並跳到下一個else
else if(x==1){printf("B");} //因為 x!=1 不會輸出,並跳到下一個else
else{print("C")} //由於上面的if都不成立,執行else內的函式
}
```
### switch
還沒教到,我之後再補 by 睿瑜 \^-^
---
## 迴圈
:::info
迴圈有兩種 for 跟 while
for 通常用於有限迴圈, while 通常用於無盡迴圈
兩者皆可通用
:::
### for迴圈
當判斷式內容成立,執行for迴圈
for迴圈常用於 **執行有限/指定做n次** 的迴圈
```c=
for (初始變數; 判斷式; 遞增式) {
陳述句一;
陳述句二;
}
```
也可以這樣寫
```c=
for (初始變數; 判斷式; 遞增式) 陳述句一;
陳述句二;
//在迴圈內只會執行陳述句一,跑完迴圈後才會執行陳述句二
```
### while迴圈
跟 for 迴圈一樣,當判斷式的內容成立,執行while迴圈內的內容
但是沒有初始變數跟遞增式,只有判斷式
常用於寫 **無盡/不知道要執行多少次** 的迴圈
```c=
while(條件式){
陳述句一;
陳述句二;
}
```
也可以寫成 do...while變種
程式會優先執行一次迴圈在進入判斷式
```c=
do{
陳述句一;
陳述句二;
}while(條件式);
```
請記得加入讓迴圈中斷的邏輯
不然他會變成無盡迴圈,程式會跑不完
必須使用無盡迴圈的程式 : Ardiuno,遊戲程式
例如下方程式
```c=
#include <stdio.h>
int main(){
int i=0;
while(i<5){
i++;
}
}
```
每次執行while迴圈時 i 的值都會 +1
當 i >= 5 時會中斷程式,總共會執行 5 次迴圈
### 迴圈中斷 break/contiune
可以使用break讓迴圈強制中斷
例如下方程式
```c=
#include <stdio.h>
int main(){
int i=0;
while(i<5){
i++;
if(i>3){break;}
}
printf("i=%d",i); // i=4
}
```
因為在 i=4 的時候觸發了第 7 行的 break 函式
所以迴圈強制中斷,列印出 i=4
此外,可以使用continue讓迴圈直接重跑
例如下方程式
```c=
#include <stdio.h>
int main(){
int i=0;
while(i<5){
i++;
if(i % 2 == 0){continue;}
printf("%d ",i);
}
}
```
觸發到 continue 之後 , printf("&d",i) 就不會執行
所以輸出為 1 3
## 副程式
有兩種定義函式的方法
【巨集】類似 python 的 lambda 函數,是簡單定義副程式的方法
【函式】可以自訂義一大串功能,在跑迴圈或演算法時很好用
### 巨集
使用方法如下 :
```c=
#define 副程式名(輸入變數) 執行程式
```
define會直接將 ( ) 的內容丟入函式中
```c=
#include <stdio.h>
#define function(x) x * x
int main(){
printf("%d",function( 10 )) //100
printf("%d",function( 8 + 2 )) //26
//* 因為函式會將其視為 ( 8 + 2 * 8 + 2 ) = 26 *//
printf("%d",function( ( 8 + 2 ) ) //100
//* ( ( 8 + 2 ) * ( 8 + 2 ) ) = 100 *//
}
```
### 副程式
使用方法如下
```c=
//不回傳數值
void 副程式名(輸入變數){
執行程式內容;
}
//需要回傳數值
int 副程式名(輸入變數){
}
```
##