為何要使用指標
使用指標的好處是:我們不需要先跟電腦要記憶體空間,可以事後要用到時,再指定一個記憶體空間位置給它使用。
與之相對的陣列,在宣告時,需要事先告訴電腦我需要多少的空間,如此一來,空間大小就固定住了,不如指標可以隨時改變其空間的大小。
與之相對的陣列,在宣告時,需要事先告訴電腦我需要多少的空間,如此一來,空間大小就固定住了,不如指標可以隨時改變其空間的大小。
指標觀念
宣告指標的格式如下:
其中*的功能為讀取指標變數所指向的記憶體空間位置所儲存之數值,稱為取值運算子。
==================================================================
<範例1>
其中的宣告方式:
==================================================================
<範例2>
<範例3>*重要觀念:特別注意第8行程式碼*
<範例4>
<說明>
本例子示範的是指標陣列的用法
若以圖形化表示,大該如下:
該函式calloc會跟電腦要10個char的記憶體空間,並回傳其記憶體空間位置的地址給指標變數,所以使用指標來儲存該記憶體空間的地址。
若以圖形化表示,大該如下:
==================================================================
<範例5>
<說明>
本例子示範的是自訂結構資料型態的變數宣告,程式碼如下:
目的是要與指標陣列在圖形化表示上做個概念性的比較,自訂結構資料型態的變數宣告的圖形化表示如下:
==================================================================
<範例6>
<說明>
本範例是示範以R為資料型態宣告指標陣列的方式,程式碼如下:
資料型態 *自訂變數名稱;
其中*的功能為讀取指標變數所指向的記憶體空間位置所儲存之數值,稱為取值運算子。
==================================================================
<範例1>
#include <stdio.h> int main( ) { int *a; int b = 5; a = &b; printf("a = %d\n", a); //表示a所儲存的記憶體空間位置,以%d輸出代表將其記憶體位址編號以十進位表示 printf("a = %p\n", a); //表示a所儲存的記憶體空間位置,以%p代表輸出記憶體位址編號(以十六進位表示) printf("*a = %d\n", *a); //表示*a所存儲的記憶體空間位置所儲存之數值 printf("b = %d\n", b); return 0; }<說明>
其中的宣告方式:
int *a; a = &b;可以直接合併成:
int *a = &b;將上述的內容直接寫入範例1,可得如下:
#include <stdio.h> int main( ) { int b = 5; int *a = &b; printf("a = %d\n", a); //表示a所儲存的記憶體空間位置,以%d輸出代表將其記憶體位址編號以十進位表示 printf("a = %p\n", a); //表示a所儲存的記憶體空間位置,以%p代表輸出記憶體位址編號(以十六進位表示) printf("*a = %d\n", *a); //表示*a所存儲的記憶體空間位置所儲存之數值 printf("b = %d\n", b); return 0; }
==================================================================
<範例2>
#include <stdio.h> int main( ) { char b = 'A'; char *a = &b; printf("a = %d\n", a); //表示a所儲存的記憶體空間位置,以%d輸出代表將其記憶體位址編號以十進位表示 printf("a = %p\n", a); //表示a所儲存的記憶體空間位置,以%p代表輸出記憶體位址編號(以十六進位表示) printf("*a = %c\n", *a); //表示*a所存儲的記憶體空間位置所儲存之字元 printf("b = %c\n", b); return 0; }==================================================================
<範例3>*重要觀念:特別注意第8行程式碼*
#include <stdio.h> int main( ) { char b[20] = "Test for a string"; char *a = &b; printf("a = %d\n", a); //表示a所儲存的記憶體空間位置,以%d輸出代表將其記憶體位址編號以十進位表示 printf("a = %p\n", a); //表示a所儲存的記憶體空間位置,以%p代表輸出記憶體位址編號(以十六進位表示) printf("a = %s\n", a); //特別注意:如果是宣告一個字串(陣列)時,要輸出該指標變數,使用%s,且不需要在a前方加上* printf("b = %s\n", b); return 0; }==================================================================
<範例4>
#include <stdio.h> #include <stdlib.h> #include <string.h> void a(char *name, int score) //"設計函數"和"指標變數"的技巧 { printf("Name:%s / score:%d\n", name, score); } void F1() //"設計函數"和"指標變數"的技巧 { char *name [2]; int score[2]; int i; name [0] = (char *) calloc(10, sizeof(char)); //問系統一個char的size為何,並跟系統要10個char的size之記憶體空間,最後再告訴系統以字元的方式來存取資料 (note:從右邊開始解釋程式碼) strcpy (name[0], "Jason"); score[0] = 90; name [1] = (char *) calloc(10, sizeof(char)); strcpy (name[1], "Jimmy"); score[1] = 95; for (i=0; i< 2; i++) { a(name[i], score[i]); } } int main() { F1(); return 0; }
<說明>
本例子示範的是指標陣列的用法
char *name [2];
若以圖形化表示,大該如下:
然而,指標陣列並沒有一個實際的記憶體空間可以給我們的資料來存放,所以這個時候我們可以使用calloc來跟電腦要記憶體空間給指標變數使用,程式碼如下:
name [0] = (char *) calloc(10, sizeof(char)); name [1] = (char *) calloc(10, sizeof(char));
該函式calloc會跟電腦要10個char的記憶體空間,並回傳其記憶體空間位置的地址給指標變數,所以使用指標來儲存該記憶體空間的地址。
若以圖形化表示,大該如下:
使用calloc所配置的記憶體空間,在使用後,如果不需要了,可以使用free( )來歸還電腦記憶體空間,這就是所謂的指標動態記憶體空間配置的觀念,這樣做的好處是可以減少不必要的記憶體空間浪費、節省記憶體資源。
修改後的code:<note>第27行程式碼
#include <stdio.h> #include <stdlib.h> #include <string.h> void a(char *name, int score) //"設計函數"和"指標變數"的技巧 { printf("Name:%s / score:%d\n", name, score); } void F1() //"設計函數"和"指標變數"的技巧 { char *name [2]; int score[2]; int i; name [0] = (char *) calloc(10, sizeof(char)); //問系統一個char的size為何,並跟系統要10個char的size之記憶體空間,最後再告訴系統以字元的方式來存取資料 (note:從右邊開始解釋程式碼) strcpy (name[0], "Jason"); score[0] = 90; name [1] = (char *) calloc(10, sizeof(char)); strcpy (name[1], "Jimmy"); score[1] = 95; for (i=0; i< 2; i++) { a(name[i], score[i]); } free(name); } int main() { F1(); return 0; }
==================================================================
<範例5>
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct record { //"自訂結構資料型態"和"自訂資料型態的別名"的技巧 char name[10]; int score; } R; void a(char *name, int score) //"設計函數"的技巧 { printf("Name:%s / score:%d\n", name, score); } void F2(){ //"設計函數"和"指標變數"的技巧 R data[2]; //類似我們宣告字元、整數、浮點數依樣,需要先告訴電腦我們的資料型態是char、int或float,只是在這邊我們使用的是剛剛自訂的資料型態R int i; strcpy (data[0].name, "Jason"); data[0].score = 90; strcpy (data[1].name, "Jimmy"); data[1].score = 95; for (i=0; i<2; i++){ a(data[i].name, data[i].score); } } int main() { F2(); return 0; }
<說明>
本例子示範的是自訂結構資料型態的變數宣告,程式碼如下:
typedef struct record { //"自訂結構資料型態"和"自訂資料型態的別名"的技巧 char name[10]; int score; } R; void F2(){ R data[2]; }
目的是要與指標陣列在圖形化表示上做個概念性的比較,自訂結構資料型態的變數宣告的圖形化表示如下:
==================================================================
<範例6>
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct record { //"自訂結構資料型態"和"自訂資料型態的別名"的技巧 char name[10]; int score; } R; void a(char *name, int score) //"設計函數"的技巧 { printf("Name:%s / score:%d\n", name, score); } void F3(){ //"設計函數"和"指標變數"的技巧 R *data[2]; int i; data[0] = (R *) malloc (sizeof(R)); strcpy (data[0]->name, "Jason"); data[0]->score = 90; data[1] = (R *) malloc (sizeof(R)); strcpy (data[1]->name, "Jimmy"); data[1]->score = 95; for (i=0; i<2; i++){ a(data[i]->name, data[i]->score); } } int main() { F3(); return 0; }
<說明>
本範例是示範以R為資料型態宣告指標陣列的方式,程式碼如下:
typedef struct record { //先定義清楚所自訂的資料型態內包含些什麼內容(例如:本程式自定的資料型態叫作struct record,別名是R,內容包含一個大小為10的name陣列與一個整數變數score char name[10]; int score; } R; R *data[2]; //以R為資料型態(就像之前我們所使用的int、float、double、char等),宣告指標陣列
作者已經移除這則留言。
回覆刪除作者已經移除這則留言。
回覆刪除