Introduction to the C Programming Language 指標 (Pointer)
指 標 (Pointer) 指標變數所存放的內容為記憶體位置,而指標變數在記憶體中佔幾個記憶體位元組,則視所使用的語言系統而定,以Turbo C而言是2個位元組. 宣告指標變數時,需在變數名稱前加個 * 號以玆識別. * 號除了在指標變數宣告時使用外,最主要是用來存取pointer所指到的變數值. 例: *pa=0; [ 將0存入pa所指的變數內 ] y=*pa; [ 取pa所指的變數值(0),再設給y ] pa=&x; [ 以&符號取得x的位址,存入pa(把pa指向x) ] y=*pa; [ 把pa所指的變數存入y ] 若指標沒指到任何一個位置,其初值要設為NULL,NULL在stdlib.h,stdio.h,stddef.h,mem.h,alloc.h的標頭檔皆有定義.
指 標 (Pointer) 範例一: 指標的運算 #include<stdio.h> void main() { int *ptr,i,val; i=20; ptr=&i; val=*ptr; printf("val=%d\n",val); } ptr 所指的位址等於 i 的位址
指 標 (Pointer) 範例二: 指標的應用 #include<stdio.h> main() { int a=3,b=4; int *fp; printf("The original values are: a=%d , b=%d \n" , a , b ); printf("The Address are : &a=0x%p , &b=0x%p \n", &a , &b ); fp=&a; *fp=100; printf( "passing *fp=100 , a value change=%d \n" , a ); fp=&b; printf("passing fp=&b , fp value change=%d\n", *fp ); } 宣告 : fp 是指向整數變數的pointer 以 & 取得 a 變數的位址, 將位址設給 fp ( fp 指向a) 把100存入 fp 所指的變數內 以 & 取得 b 變數的位址, 將位址設給 fp ( fp 轉指向b) 利用 * 號 間接取值
傳入pointer值(變數位址即為pointer的值) 以指標來傳引數 範例三:設計一個傳值函式noswap(),及一個傳址函式swap(), 將從主程式傳來的兩個正數引數值互相對調 #include<stdio.h> main() { int x=2,y=3; void noswap(int a , int b ); void swap( int *a , int *b ); printf("The original values are: x=%d , y=%d \n" , x , y ); noswap(x,y); printf("The x y are changed : x=%d , y=%d \n", x , y ); swap(&x,&y); } 傳入pointer值(變數位址即為pointer的值)
以指標來傳引數 接上頁(範例三) void noswap ( int a , int b ) { int t; t=a; a=b; b=t; } void swap ( int *a , int *b) t=*a; *a=*b; *b=t;
指位器的指位器 指標(pointer)也可以指向指標,可稱為“指位器的指位器“ 指位器的指位器的宣告方式: int **pa; 亦可寫成 int*(*pa) [ pa是一個pointer,它指向一個整數的pointer ]
以指標來傳引數 範例四: 指標以位址傳遞(call by address) #include<stdio.h> main() { int a=1,b=2,*p,*q; void sub( int ** , int ** ); p=&a; q=&b; sub(&p,&q); printf("a=%d b=%d \n" , *p , *q ); } void sub ( int **x , int **y ) *x=*y; }
指標與陣列的關係 在C語言裡,指標與陣列的關係密不可分,兩者的差別是:陣列是固定長度的連續實體,而指標則是用來記錄位址的單一變數. 建立指標與陣列的關係 char a[10]; /*宣告陣列*/ pa=&a[0]; /*第一個指標指向陣列的開頭(第0個元素)*/ 以此為基點用索引的方式來取得陣列的每個元素 *(pa) 取到的是陣列的第0個元素 a[0] *(pa+1) 取到的是陣列的第1個元素 a[1] *(pa+i)取到的是陣列的第i個元素 a[i]
指標與陣列的關係 範例五: 用指標取出陣列元素的位址 #include<stdio.h> main() { int i; char *pa; char a[4]={'A','B','C','D'}; pa=a; for(i=0;i<4;i++) printf("a[%d] value:%c ; *(pa+%d) value:%c\n",i,a[i],i,*(pa+i)); printf("&[%d] address:%x ; *(pa+%d) address:%x\n",i,&a[i],i,pa+i); } Pointer指向陣列的開頭
指標與陣列的關係 範例六: 利用指標將陣列元素相加 #include<stdio.h> void main() { int array[5]; int *ptr,i,sum; printf("Please enter 5 integer:\n"); for(i=0;i<5;i++) scanf("%d",&array[i]); sum=0; for(ptr=array;ptr<&array[5];ptr++) sum+=*ptr; printf("The sum of this array is %d\n",sum); }
指標與陣列的關係 範例七: 將數字由小到大排序(選擇排序法). #include<stdio.h> main() { void swap(int *a,int *b); void printArray(int n,int a[]); int a[] = {32,43,12,7,52,95,66,28}; int i,j,min,t; printf("The original Array:"); printArray(8,a); for(i=0;i<8;i++) for(j=min=i;j<8;j++) if(a[j]<a[min]) min=j; swap(&a[min],&a[i]); } printf("The sorted Array:");
指標與陣列的關係 接上頁(範例七) void swap(int *a,int *b) { int t; t=*a; *a=*b; *b=t; } void printArray(int n,int b[]) int i; for(i=0;i<n;i++) printf("%5d",b[i]); printf("\n");
指位器陣列 陣列的元素也可以是pointer,這種陣列叫做“指位器陣列” 指位器陣列對於不定長度的資料處理非常有用,因陣列是固 定的存放空間,資料搬動很不方便,可採指位器陣列來解決 問題 指位器陣列的宣告方式: char *p[m]; [ p是一個陣列,其元素是字元的pointer ]
指位器陣列 範例八: 指位器陣列的使用--字串排序 #include<stdio.h> #include<string.h> #define SIZE 100 void main() { char s[SIZE][SIZE]; char *line[SIZE]; char *p; int i,j,k; for (i=0;i<SIZE;i++) printf("%d:",i++) get(s[i]); if(strcmp(s[i],"q")==0) break; line[i]=s[i]; }
指位器陣列 接上頁(範例八) for (j=0;j<i-1;j++) for (k=j+1;k<i;k++) if (strcmp(line[j],line[k] )>0) { p=line[k]; line[k]=line[j]; line[j]=p; } printf("\nSorting...\n"); for(j=0;j<i;j++) printf("%d:%s\n",j+1,lint[j]);