Presentation is loading. Please wait.

Presentation is loading. Please wait.

C 程式設計— 指標.

Similar presentations


Presentation on theme: "C 程式設計— 指標."— Presentation transcript:

1 C 程式設計— 指標

2 課程大綱 C語言簡介 基本資料型態, 變數, 基本輸入輸出 控制敘述- 選擇控制與重覆控制 陣列 函式 指標 字元與字串 結構 檔案處理

3 本次上課大綱 指標與記憶體位址 指標運算 函式的傳指標呼叫 指標和陣列 指標與函式 多重指標 main函式的引數串列與回傳值 動態記憶體配置

4 什麼是指標(pointer) 指標 一種變數 儲存記憶體位置 儲存在該記憶體中的可能是字元, 整數,指標本身變數的位置
程式可以間接取得該指標所指位址的變數值 節省記憶體空間 減少不必要的搬動 使用不當的話, 造成系統或程式嚴重的錯誤

5 存取記憶體內容

6 宣告指標變數 (1) 指標的宣告方式與變數的宣告方式相同, 只不過指標在變數前面多加一個 * 資料型態 *指標變數名稱
資料型態 *指標變數名稱 int *int_ptr; char *ch_ptr; float *float_ptr; double *double_ptr;

7 宣告指標變數 (2) int i=3; int *ptr; ptr=&i; ptr是一個指向整數型態的指標, 內容為該整數的位址
1012 3 1000 1004 1008 ptr是一個指向整數型態的指標, 內容為該整數的位址 i是一個整數, 內容為3, 與*ptr的值一樣 記憶體位址

8 取址運算子與指標運算子(1) &是取址運算子 用來取得該變數在記憶體的位址 &變數名稱 int i=3; int *ptr; ptr=&i;
1012 3 1000 1004 1008 記憶體位址 ptr是一個整數指標 *ptr取得該指標的內容值 &i取得該整數在記憶體中 的位址 i是一個整數

9 取址運算子與指標運算子(2) *是指標運算子 用來取得指標所指向位址的內容值 *指標變數名稱 int i; int *p; p=&i;
記憶體位址 記憶體位址 1012 1012 1000 1000 1004 1004 1008 1008 50 ?? 1012 1012

10 練習時間 每一種資料型態的指標變數在32位元的作業系統環境中都佔用4個bytes,因為指標變數存放的是記憶體位址 比較輸出指標的位址與值.

11 指標運算 (1) 指定運算 加減運算 比較運算 差值運算 錯誤:int *p=10; 正確: int x=10; int *p=&x;
變數 int x = 10; 指標變數 int *x = (int *)10; x 10 *x &x 10 x

12 指標運算 (2) 加減運算 只能加常數值 將指標變數內容『加1』
依據指標指向的資料型態所佔用的記憶體單位大小,來決定移動多少個位址(加1代表加1個單位),以便指向正確的下一筆同樣資料類型的資料。 例子 int *p,*q; p=p+q; /* 不合法 */

13 指標運算 (3) 比較運算 例子 相同型態的指標變數可以做比較運算,藉由比較運算,我們可以得知記憶體位址的先後關係
較早配置記憶體的變數位於較高的記憶體位址 例子

14 指標運算 (4) 差值運算 兩個相同資料型態的指標變數可以做減法運算 代表兩個記憶體位址之間的可存放多少個該資料型態的資料 例子

15 傳址呼叫 (1) 傳值呼叫 call by value 傳址呼叫 call by address

16 Copyright 1992-2004 by Deitel & Associates, Inc
Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

17 The original value of number is 5
The new value of number is 125 Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

18 Analysis of a typical call-by-value. (Part 1 of 2.)
Before main calls cubeByValue : int main() number int cubeByValue( int n ) { { int number = 5 ; 5 return n * n * n; } n number=cubeByValue(number); } undefined After cubeByValue receives the call: int main() int cubeByValue( int n ) number { { int number = 5 ; 5 return n * n * n; } number = cubeByValue( number ); n } 5 After cubeByValue cubes parameter n and before cubeByValue returns to main : int main() int cubeByValue( int n ) number { { 125 int number = 5 ; 5 return n * n * n; } number = cubeByValue( number ); n } 5 Analysis of a typical call-by-value. (Part 1 of 2.)

19 and before assigning the result to
125 int main() { number = 5 ; number = cubeByValue( number ); } cubeByValue( n ) return n * n * n; number n After cubeByValue returns to main and before assigning the result to : undefined completes the assignment to Analysis of a typical call-by-value. (Part 2 of 2.)

20 傳入型態為指標 傳入變數位址 將變數改為指標型態
Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

21 The original value of number is 5
The new value of number is 125 Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

22 receives the call and before is cubed:
main calls cubeByReference : int main() number void cubeByReference( int *nPtr ) { { 5 int number = 5 ; *nPtr = *nPtr * *nPtr * *nPtr; } cubeByReference( &number ); nPtr } undefined After cubeByReference receives the call and before *nPtr is cubed: int main() number void cubeByReference( int *nPtr ) { { 5 int number = 5 ; *nPtr = *nPtr * *nPtr * *nPtr; } cubeByReference( &number ); nPtr call establishes this pointer } After *nPtr is cubed and before program control returns to main : int main() number void cubeByReference( int *nPtr ) { { 125 125 int number = 5 ; *nPtr = *nPtr * *nPtr * *nPtr; } cubeByReference( &number ); called function modifies nPtr } caller’s variable Analysis of a typical call-by-reference with a pointer argument.

23 練習時間 SWAP #include<stdio.h> void swap(int *,int *); int main() {
int i,j; i=1,j=2; swap(&i,&j); printf("%d %d",i,j); } void swap(int *p,int *q) int temp; temp=*p,*p=*q;*q=temp; SWAP

24 傳址呼叫 (2) 傳值呼叫 傳址呼叫

25 指標與陣列 int array[10]; 我們以陣列名為array代表陣列的起始位址, 以array+1表示下一個位址.
當宣告指標時, int *ptr; 則以ptr代表其位址, 以ptr+1代表下一個位址. 陣列其實也是指標的一種應用.

26 Copyright 1992-2004 by Deitel & Associates, Inc
Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

27 Copyright 1992-2004 by Deitel & Associates, Inc
Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

28 Array b printed with: Array subscript notation b[ 0 ] = 10 b[ 1 ] = 20 b[ 2 ] = 30 b[ 3 ] = 40 Pointer/offset notation where the pointer is the array name *( b + 0 ) = 10 *( b + 1 ) = 20 *( b + 2 ) = 30 *( b + 3 ) = 40 Pointer subscript notation bPtr[ 0 ] = 10 bPtr[ 1 ] = 20 bPtr[ 2 ] = 30 bPtr[ 3 ] = 40 Pointer/offset notation *( bPtr + 0 ) = 10 *( bPtr + 1 ) = 20 *( bPtr + 2 ) = 30 *( bPtr + 3 ) = 40 Program Output Copyright by Deitel & Associates, Inc. and Pearson Edition Inc. All right Reserved.

29 練習時間 陣列其實也是指標的一種應用. 如果用array++會怎樣? 使用指標控制陣列. 如果用ptr++會怎樣?

30 指標與二維陣列 例子 多重指標與二維陣列 int array[3][4], *ptr; ptr=(int *)array;
(*(array+1))[1]跟*((array+1)[1])的比較 多重指標與二維陣列

31 指標陣列 陣列裡面所包含的元素都是指標. 指標陣列型態 例子: int *int_ptr[10]; // 整數指標陣列
float *float_ptr[10]; double *double_ptr[10]; char *str[10]; 例子:

32 指標與函數 函數的名稱與陣列的名稱一樣, 都代表著起始位址, 同時也是一個指標的常數, 因此函數指標可做如下的宣告: 例子:
void (*func)(void); 例子: 傳回整數的指標函數: 如果把程式中第9行的 *func(i) 變成 func(i)的話, 會怎樣?

33 指標的指標 (1) int * ptr; /* 指標 */ int ** ptr; /* 指向指標的指標 */
位址 位址 整數值 雙重指標

34 指標的指標 (2)

35 指標的指標 (3) 使用多重指標(指標的指標)將九九乘法表的乘法結果儲存在9*9的二維整數陣列,並將陣列的資料列印出來 陣列表示法
指標表示法 array[i][j] *(*(array+i)+j)

36 問題: 請問下列程式的執行結果 #include <stdio.h> #include <stdlib.h>
int main() { int x[5]={2,4,6,8,10},*p,**pp; p=x; pp=&p; printf("%d\n",*(p)); p++; printf("%d\n",**pp); system("pause"); return 0; }

37 main()的argc與argv 定義方式一 定義方式二: 定義方式三: argc表示命令列中參數字串的個數.
int main(int argc,char *argv[]) 定義方式二: int main(int argc,char argv[][]) /* 使用二維字元陣列(字串陣列) */ 定義方式三: int main(int argc,char **argv) /* 使用指標的指標 */ argc表示命令列中參數字串的個數. argv表示指向命令列中所有參數字串的指標. 例子

38 動態記憶體配置 使用在某些陣列大小無法於事先決定的情況 需要用多少記憶體空間,就向系統要多少記憶體空間
C語言不能宣告一個陣列大小為變數的陣列 需要用多少記憶體空間,就向系統要多少記憶體空間 於執行過程中配置一個適當大小的記憶體空間給指標,接著藉由這個指標來存取分配到的記憶體空間內的資料

39 配置記憶體函式-malloc( ) 標頭檔: 語法:void *malloc(size_t size); 功能:動態配置記憶體 範例
#include <stdlib.h> #include <malloc.h> 語法:void *malloc(size_t size); 功能:動態配置記憶體 範例 char *ptr; ptr = (char *)malloc(sizeof(char)*9);

40 釋放記憶體函式-free( ) 標頭檔: 語法:void free(void *ptr); 功能:釋放記憶體 範例:
#include <stdlib.h> #include <malloc.h> 語法:void free(void *ptr); 功能:釋放記憶體 範例: Free(ptr); 我們透過malloc函式取得的記憶體,可以於不需再使用的狀況下,透過free函式將之歸還給系統

41 今天學到了什麼 什麼是指標 如何使用指標運算 如何使用函式的傳指標呼叫 如何使用指標和陣列 如何使用指標與函式 如何使用多重指標
如何使用main函式的引數串列與回傳值 如何使用動態記憶體配置


Download ppt "C 程式設計— 指標."

Similar presentations


Ads by Google