二级指针的简单运用

  在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()比较两个字符串的大小,再根据需要交换指针。

posted on 2015-11-21 17:55  acodewarrior  阅读(4768)  评论(0编辑  收藏  举报

导航