# 學習筆記
# 函式
使用函數的目的,**利用模組化來簡化主程式**
---
**num( )函數原型的宣告格式:**
```
函數名稱 函數不須有引數傳入
| |
void num (void);
|
函數沒傳回值
```
**num( )函數的定義格式:**
```
void num(void)
{
printf(".....");
return;
}
```
---
**add( )函數的原型宣告:**
```
傳回值型態是整數
|
int ass(int,int);
| |
函數名稱 有兩個引數傳入add()函數,型態均為int
```
**add( )函數的定義格式:**
```
int add(int num1,int num2)
{
int sum;
sum=num1+num2;
return sum;
}
```
---
# 指標
1 資料的地址就是指標
`int b=2;`
以上面的程式碼為例,在宣告好變數、程式開始執行後,會去記憶體中要一塊儲存空間,然後把 2 這個資料丟進去。
想像記憶體是一個大櫃子,每一格都有相對應的位址,2 的位址就在記憶體中的某個地方
一個格子= 1 byte
----
# 指標變數
**指標**:某變數的位址
**指標變數**:用來存放指標的變數
舉例:
```
int *n;
int b;
int 2;
n=&b;
```
---
**int * n ;**
這個的意思是,跟記憶體要一塊區域稱為n,這塊區域專門放指向int型變數的指標(位址)
**int b ;**
這個的意思是,跟記憶體要一塊區域稱為 b,這塊區域專門放 int 型變數
**b=2 ;**
這個的意思是,把 2 這個值給變數 b
**n=&b ;**
這個的意思是,把變數 b 的地址值給 n
(&的意思是,取得變數在記憶體中被配置的位址)
---
# 使用void型別的指位器
---
指位器只能指向同型別的變數位址,舉例:
```
char *n;
int y=3;
n=&y;
```
這個是錯誤的,因為字元型別的指位器只能指向字元型別的指標
如果要讓指位器指向不同型別的指標,可以宣告 void 型別的指位器,舉例:
```
void *box;
int i= 1;
box=&i;
printf("%d ",* ( int* ) box )
```
將 box 由 (void*) 型別轉型為(int*)型別,再用 * 取值
---
# 陣列和指位器
---
```
int number[3];
int *box=&number[0];
*(box)=0; //number[0]=0;
*(box+1)=10; //number[1]=10;
*(box+2)=20; //number[2]=20;
```
因此,可以發現指位器材和陣列非常相似,所以也可以說「 陣列變數就是指位器 」,舉例:
```
int arr[10]={0};
int *ptr=arr;
//不必使用 &,因為 arr 本身就是指位器,其值就是陣列存放的地址
int arr[10]={0};
*(arr)=0; //arr[0]=0;
*(arr+1)=1;//arr[1]=1;
```
----
# 動態記憶體配置
---
動態記憶體配置是什麼呢?在這之前先來了解
什麼是靜態記憶體配置:
像是定義整數或字元、陣列都是靜態,也就是說開始執行程式時,就已經預備好所要用到的空間,就算臨時想更改空間大小也不行。
而動態記憶體配置就能解決「 臨時 」要更改空間大小的窘境,文言一點,就是「當程式執行到一半,發現它需要一塊記憶體空間來存放資料,才向系統索取一塊沒有被其他程式使用的記憶體空間。」
向系統索取記憶體區塊主要透過 malloc( )函式來做,使用到的標頭檔是 stdlib.h
語法使用:
`( 資料型別 * ) malloc ( sizeof ( 資料型別 ) * 個數);`
資料型別:新配置空間的型別
個數:新配置多少型別的變數空間
舉例:
```
int *box=( int * ) malloc ( sizeof ( int ) * 10 ) ;
動態配置 10 個 int 型別的記憶體空間,配置成功後,使用 box 時,就像使用 box [ 10 ]一樣,可以在其中任意儲存資料
```
動態配置的空間使用完畢後,必須用free( )函式將配置的記憶體釋放
舉例:將box給釋放 :
`free ( box );`
完整動作:
```
int *box ;
.
.
.
box= ( int * ) malloc ( sizeof ( int ) * 10 ) ;
.
.
.
free( box ) ;
```
---
# 字串
---
字串和字元的差別:差在記憶體所佔的空間
字串: "c" => 'c' \0 佔 2 bytes
字元: ’c’ => 'c' 佔 1 byte
---
**\0 是什麼呢?**
它是在 C 語言中,處理各種字串時,就是以 \0 作為結束字元來1判斷字串的1結尾
---
**宣告字串:**
`char 字串名稱 [ 陣列容量 ] = ”字串內容 ”;`
---
**陣列容量:**
* 通常會依初始值設定的字串長度( 字元數 + 1 )來設定陣列容量
* 由“ 標準輸入”輸入字串
* 標準輸入:在電腦上就是鍵盤
可使用 scanf 配合 %s 的格式,或者呼叫 gets ( ) 函式
舉例:
```
char str1 [ 64 ]={0} ;
char str2 [ 64 ]={0} ;
scanf ( " %s" ,str1 ) ;
// 將標準輸入的字串存到 str1 陣列
gets ( str2 ) ;
// 將標準輸入的字串存到 str2 陣列
```
scanf 和 gets 的差別:差在遇到空白字元時處理的方式不同
**scanf ( )** 函式取得輸入時,遇到空白字元時,就視為字串結束,所以空白字元後還有東西,也不會被讀到
**gets ( )** 函式取得輸入時,不會視空白字元為字串結束,而是必須明確出現換行字元( 例如Enter 鍵 )或檔案結束字元,才會視為結束字串
---
# 計算字串的長度:
---
* strlen ( 字串 ) 函式
* 標頭檔 string.h
---
**字串複製:如果想將字串a的內容給字串b,可以用這個方式進行,舉例:**
```
char * strcpy ( 目的陣列 ,來源陣列 ) ;
// strcpy會將來源陣列的內容“ 複製 ”到目的陣列
```
但是,如果“ 來源陣列 ”的字串內容超過“ 目的陣列 ”的容量限制的話,程式會出錯
所以,如果只想複製來源陣列裡其中的部分到目的陣列的話,可以用這個,舉例:
`char * strncpy ( 目的陣列 ,來源陣列 ,複製字元數 ) ;`
---
# 字串比對
---
strcmp ( ) 函式可以用來比對兩個字串的內容
舉例:
`int strcmp ( 字串1 , 字串2 ) ;`
strncmp ( ) 跟 strcmp ( ) 一樣都是比對字串,差別在它是可以指定字串的第幾個字元比較
舉例:
`strncmp ( 字串1, 字串2, 比對字元數 )`
---
# 字串串接
---
strcat ( ) 將兩個字串進行串接
舉例:
`char * strcat(目的陣列 , 來源陣列);`
假設來源陣列 :djsls ,目的陣列 :kdmkmr
會變成: kdmkmrdjsls
strncat() 跟 strcat() 很像,差在它可以指定來源陣列中,最前面的字元數量
舉例:
// `char * strncat(目的陣列 , 來源陣列, 串接字元數);`
```
char box_1[] = "jscd" ;
char box_2[] = "jdcns" ;
strncat (box_1, box_2, 2) ;
```
會變成 :jscdjd
---
# 字串轉換
---
**字串轉整數**
`int atoi(字串)`
記得,它只是將字串裡的數字轉成整數型別的整數喔,像是:"123"
只要一遇到非數字就會停止,如果都是非數字的話,傳回 0
**字串轉浮點數**
`double atof(字串)`
記得,atof()的傳回值為 double 型別,跟 atoi()很像,一樣遇到不是 '.' 或 'e' 或 'E' 的話,就停止。如果都是不是浮點樹相關的字元,傳回 0.0
---