二級指針變量與數組


在C語言中,數組名就是一個指針常量,保存數組的首地址。因為數組名是一個常量指針常量,不能修改其指向的值,因此可以定義一個指針變量指向數組。這樣使用數組名加下標可訪問數組中的元素,使用指針名加下標也可訪問數組中的元素。這些在本章前面已經介紹過了。

現在如果再定義一個二級指針變量,讓其指向一級指針,就可使用二級指針變量操作數組。例如,使用以下語句定義二級指針變量:

  1. int a[10];  
  2. int *p=a;  
  3. int **pp=&p; 

這樣,二級指針變量pp、一級指針變量p和數組a之間的關系,如圖9-47所示。

 
(點擊查看大圖)圖9-47  用二級指針操作一維數組

1.用二級指針操作一維數組

可使用以下代碼輸出數組a中各元素的值:

【程序9-24】

  1. #include <stdio.h>  //頭文件  
  2. #include <stdlib.h
  3.  
  4. int main()  
  5. {  
  6.     int i,a[10]={1,2,3,4,5,6,7,8,9,10};//聲明並初始化  
  7.     int *p,**pp;  
  8.  
  9.     printf("使用數組方式輸出數組各元素的值:\n");  
  10.     for(i=0;i<10;i++)   //使用數組方式輸出  
  11.     {  
  12.         printf("%4d  ",a[i]);  
  13.     }  
  14.  
  15.     printf("\n使用一級指針變量輸出數組各元素的值:\n");  
  16.     p=a;  
  17.     for(i=0;i<10;i++)   //使用一級指針變量輸出  
  18.     {  
  19.         printf("%4d  ",*p++);  
  20.     }  
  21.  
  22.     printf("\n使用二級指針變量輸出數組各元素的值:\n");  
  23.     p=a;  
  24.     pp=&p;  
  25.     for(i=0;i<10;i++)   //用二級指針變量輸出  
  26.     {  
  27.         printf("%4d  ",*(*pp+i));  
  28.     }  
  29.  
  30.     printf("\n使用二級指針變量**p方式輸出數組各元素的值:\n");  
  31.     p=a;  
  32.     for(i=0;i<10;i++,p++)//使用二級指針變量**p方式輸出  
  33.     {  
  34.        printf("%4d  ",**pp);  
  35.     }  
  36.  
  37.     printf("\n");  
  38.  
  39.     system("pause");  
  40.     return 0;  

在以上程序中,分別采用了如下幾種方法輸出數組各元素的值。

使用數組下標方式輸出各元素的值。

使用一級指針變量輸出指向元素的值,然后執行p++使指針指向下一個元素,循環處理將所有數組元素都輸出。

使用二級指針變量的方式輸出數組元素值,在第23行中,首先使用*pp得到一級指針變量p中保存的值,再將其加上一個整數i,再使用運算符*得到具體的值。

使用**pp方式輸出具體元素的值,這時,因為二級指針變量pp指向一級指針變量p,所以只需要改變一級指針變量p所指向的位置,**pp就可以得到不同元素的值。

編譯執行這段程序,得到如下結果,如圖9-48所示。

 
圖9-48  執行結果


從以上程序可以看出,對於一維數組,使用一級指針變量可方便地操作數組元素,而使用二級指針變量只會讓情況更復雜。

2.用二級指針操作二維數組

用二級指針操作二維數組的示意圖,如圖9-49所示。同樣在二級指針變量pp中保存一級指針的地址,修改一級指針p的指向,使用**pp就可訪問到不同的數組元素,如圖9-49所示。因為一級指針變量定義為int型,所以對指針變量p進行自增時,將移動到下一個int變量(即一個數組元素),如圖9-49右圖所示。

 
(點擊查看大圖)圖9-49  用二級指針操作二維數組示意圖

下面編寫程序,用二級指針變量輸出二維數組的數據。

【程序9-25】

  1. #include <stdio.h>//頭文件  
  2. #include <stdlib.h
  3.  
  4. int main()  
  5. {  
  6.     int i,j,a[3][4]={{1,2,3,4},{5,6,7,8},
    {9,10,11,12}}; //聲明並初始化  
  7.     int *p,**pp;  
  8.  
  9.     printf("用二級指針方式輸出二維數組:\n");  
  10.     pp=&p;  
  11.     for(i=0;i<3;i++)//用二級指針方式輸出  
  12.     {  
  13.         p=a[i];  
  14.         for(j=0;j<4;j++)  
  15.             printf("%4d",*(*pp+j));  
  16.         printf("\n");  
  17.     }  
  18.  
  19.     printf("用二級指針**pp輸出二維數組:\n");  
  20.     for(i=0;i<3;i++)//用二級指針**pp輸出  
  21.     {  
  22.         p=a[i];  
  23.         for(j=0;j<4;j++,p++)  
  24.             printf("%4d",**pp);  
  25.         printf("\n");  
  26.     }  
  27.  
  28.     printf("\n");   //輸出換行  
  29.  
  30.     system("pause");  
  31.     return 0;  

在該程序中,首先使二級指針變量pp指向一級指針變量p,因為p的內存地址不會再變化,所以可將該語句放在程序前面,在后面的循環中不需要修改其值。然后,使用*(*pp+j)的方式輸出數組中的值,這種方式在本章前面曾多次使用,首先通過*pp得到一級指針變量p保存的值(從語句p=a[i]可知道,變量p中保存着二維數組某行的首地址),再將其加上一個整數j,得到該行第j個元素的地址,最后使用運算符*得到該地址的值。

在第二種方法中,使用**pp方式輸出二維數組元素的值,該表達式可看做為*(*pp),*pp得到變量p中的值,從語句p=a[i]可知道,變量p中保存着二維數組某行的首地址,該首地址也是該行第1個元素的地址,因此使用*(*pp)將輸出某行第1個元素的值。接着執行循環中的p++,使一級指針變量的值增加1,因該變量保存的值是一個指針,所以對其進行自增運算將指向下一個元素,即該行的第2個元素,再使用**pp即可輸出第2個元素的值。通過內循環語句,即可將二維數組一行中的每個元素輸出。再通過外循環,即可輸出整個二維數組中的元素值。

編譯執行這段程序,得到如下結果,如圖9-50所示。

 
圖9-50  執行結果

3.用二級指針操作指針數組

在本章的程序9-22中,使用指針數組操作多個字符串。還可以通過二級指針變量的方式進行這種操作,其示意圖如圖9-51所示。首先定義一個字符串指針數組s,用來指向多個字符串常量,再定義一個二級指針變量p,使其指向數組s,因數組s中的每個元素都是數組,因此指針變量p必須定義為指向指針的指針(即二級指針)。

 
(點擊查看大圖)圖9-51  二級指針與數組

修改程序9-22中的strsort()函數,使其形參使用二級指針的方式。

【程序9-26】

  1. #include <stdio.h>  //頭文件  
  2. #include <stdlib.h
  3. #include <string.h
  4.  
  5. void strsort(char **p,int n);       //函數聲明  
  6.  
  7. int main()  
  8. {  
  9.     int i;  
  10.     char *s[]={     //初始化  
  11.                "C",  
  12.                "Basic",  
  13.                "Foxpro",  
  14.                "Visual Studio"  
  15.                };  
  16.  
  17.     strsort(s,sizeof(s)/4);     //排序  
  18.     printf("\n排序后的數據:\n");  
  19.     for(i=0;i<sizeof(s)/4;i++)      //輸出  
  20.     {  
  21.         printf("%s\n",s[i]);  
  22.     }  
  23.  
  24.     system("pause");  
  25.     return 0;  
  26. }  
  27.  
  28. void strsort(char**p,int n)     //自定義函數  
  29. {  
  30.      int i,j;  
  31.      char *pstr;  
  32.      for(i=0;i<n-1;i++)  
  33.      {  
  34.        for (j=i+1;j<n;j++)  
  35.        {  
  36.            if (strcmp(*(p+i),*(p+j))>0)//比較  
  37.            {  
  38.                pstr=*(p+j);  
  39.                *(p+j)=*(p+i);  
  40.                *(p+i)=pstr;  
  41.            }  
  42.        }  
  43.      }  

編譯執行這段程序,得到如下結果,如圖9-52所示。

 

 
圖9-52  執行結果

 

在該程序中,重新編寫自定義函數strsort()。在函數頭的形參中,使用二級指針變量p接收一個指針變量的地址作為參數(指針數組的每一個元素是一個指針,指針數組名就是一個指向指針變量的指針),變量n為需要處理的字符串數量。

在自定義函數strsort()中,定義了一個字符指針變量pstr,作為臨時指針變量,用來保存需要交換的指針地址。

對照前面的示意圖,*(p+i)表示p[i],即與數組s[i]相同,得到其指向的字符串常量。程序中調用庫函數strcmp()比較兩個字符串的大小,再根據需要交換指針。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM