# Pointer basic --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # 前置作業 確認電腦中有安裝`git`和`gdb` 如果有缺請用`sudo apt-get install` 安裝 並執行以下指令: ``` git clone https://github.com/HMKRL/lion-pointer.git cd lion-pointer/ ``` --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # gdb ## (GNU Debugger) ---- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> 安裝  啟動   ### 使用時編譯參數需加上 `-g`  ---- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> ## 基本指令 |指令 |用途 |簡寫用法| |:--:|:--:|:--:| |`file <執行檔名稱>` |讀入執行檔| |`run`|程式開始執行|`r`| |`list`/`list 行數`|顯示程式碼|`l`| |`break`|設定中斷點|`b`| |`continue`|程式繼續|`c`| |`print 變數名稱`|印出變數內容|`p`| |`quit`|離開|`q`| |`whatis`|顯示type| ---- <!-- .slide: data-transition="slide" data-transition-speed="fast"-->   ---- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # GDB Practice 請使用gdb 對bug.c進行除錯 --- <!-- .slide: data-transition="slide" data-transition-speed="fast"-->  ---- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # Call by value 在C語言中,函式呼叫時會把變數複製一份傳入 因此傳入的只有變數的"__數值__"! --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # 變數儲存  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> `int var = 39;`  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"-->  --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> # 變數型態-指標 指標並不是什麼神祕的東西 它和`int`或`char`一樣都是一種變數型態 ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## 宣告方式 ### `type * 變數名稱`  此處的星號代表『指標型態』 前面的type則是『指標指向的type』 ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## Practice  p b c d 分別是什麼type? ---- ## 使用whatis  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> # 指標用運算子 ## `* (value of)` ## `& (address of)` ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## 指標變數賦值 #### `int *ptr = &var` #### `ptr = &var` #### `ptrA = ptrB` <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ---- # practice #### 宣告一個`int`變數 `a = 3` #### 和一個指標變數 `ptr` 指向 `a` #### 用 gdb 觀察`ptr`的值 --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> ## `int var = 39`  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## `int *ptr = &var`  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## `*ptr = 8763`  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## `int *ptr2 = ptr`  ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> # `*ptr2 = ?` ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> ## practice 修改swap.c到正常運作 正常輸出:  --- <!-- .slide: data-transition="slide" data-transition-speed="fast"--> ## 為何要知道指標指向的type? ---- <!-- .slide: data-transition="zoom" data-transition-speed="fast"--> `int pi = 31415926`  `float f = 2.813587e-09`  `short s = 12609`  ---- ## `&pi = ?` ## `&f = ?` ## `&s = ?` ---- ## 全部都是 `0xc8763`!!  ---- #### 如果不知道指標所指向的記憶體存了什麼type #### 就沒辦法正確解讀記憶體內容  --- ## 知道type後除了可以解讀 ## 還有什麼作用? ---- ## 指標加減運算 #### 編譯pointer_add.c,用GDB印出 #### (1)`intptr`, `intptr + 1` #### (2)`charptr`, `charptr + 1` ----   ---- ## 對指標來說,加法/減法的意義是移動本身type的大小! ----  ----  ---- ## Practice 宣告一個`char`陣列  使用gdb觀察 `ch`、`ch[0]`到`ch[3]`的記憶體位址 ---- ## 有何發現? ----  ---- ## 在C語言中 陣列就是連續的記憶體位置!  ---- ## Practice 修改pointer_array.c 不使用[]印出陣列內容 ---- ## 由此可知 ## `arr[3]` 和 `*(arr + 3)` ## 是一樣的! --- ## 所以陣列就是指標...嗎? ---- ### 很明顯不一樣...  ---- # 可是到底哪裡不一樣? ---- ## 陣列會包含尺寸資訊   ---- ### 陣列和指標在以下情況可以通用: * 不用於宣告時 ```clike int a[10]; int *ptr = a ``` * 用`[]`取內容時 ```clike `a[3] 和 *(a + 3)同義 ``` * 傳入function時 ```clike void function_name(char *arr) ``` ```clike void function_name(char arr[]) ``` #### 相同 ---- ## Quiz #### 如何在function中知道array有幾個元素 ---- ## Ans #### 沒辦法 ; _ ; ---- ### 剛剛提過,傳入function時array和指標相等 編譯器只會把array的開頭指標傳進function 如果要知道array大小,只能自己傳進去~ 這個情況稱作 __退化__ __(Pointer decay__ ``` void function_name(char *arr, int size) ``` ---- ## Practice: 寫一個印出array所有元素的function,陣列大小需用傳入的 ```clike= void print(/*the parameter you need*/) { int i; for(i = 0;i < array_size;i++) { /* code for print array*/ } } ``` --- ## NULL Pointer `int *ptr = NULL` NULL用來代表『這個指標沒有指向特定變數』 所以也不能做*ptr 用途:之後做linked-list時判斷用 ---- ## 指標強制轉型 前面提過, 知道指標型態才能正確解讀記憶體內容 ---- ### 我們也可以利用強制轉型(casting)操作指標 ### 做一些原本不能做的事 #### (例如對float做>>) ---- 以`int`形式讀取一個`float`變數   ---- ## Practice 印出浮點數的bit pattern(使用pointer casting)  --- ## 指標應用? ----  ---- `char`的陣列其實就是字串! 但最後會有一個字元`'\0'`代表結束 ---- |0|1|2|3|4| |:-:|:-:|:-:|:-:|:-:| |`C`|`S`|`I`|`E`|`\0`| ---- ## Practice 寫一個function `string_length` 計算argv[0]的長度 ---- const pointer ```clike= #include <stdio.h> int main(int argc, char *argv[]) { int a = 3, b = 2; int *ptr1=&a; //ptr 和 *ptr都可以改 const int *ptr2 = &a; //ptr2可以改, *ptr2不能改 int * const ptr3 = &a; //ptr3不能改, *ptr3可以改 const int * const ptr4 = &a; //都不能改 return 0; } ``` ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up