二级指针的简单运用
在C语言中,数组名就是一个指针常量,保存数组的首地址。因为数组名是一个常量指针常量,不能修改其指向的值,因此可以定义一个指针变量指向数组。这样使用数组名加下标可访问数组中的元素,使用指针名加下标也可访问数组中的元素。这些在本章前面已经介绍过了。
现在如果再定义一个二级指针变量,让其指向一级指针,就可使用二级指针变量操作数组。例如,使用以下语句定义二级指针变量:
- int a[10];
- int *p=a;
- int **pp=&p;
这样,二级指针变量pp、一级指针变量p和数组a之间的关系,如图9-47所示。
(点击查看大图)图9-47 用二级指针操作一维数组 |
1.用二级指针操作一维数组
可使用以下代码输出数组a中各元素的值:
【程序9-24】
- #include <stdio.h> //头文件
- #include <stdlib.h>
- int main()
- {
- int i,a[10]={1,2,3,4,5,6,7,8,9,10};//声明并初始化
- int *p,**pp;
- printf("使用数组方式输出数组各元素的值:\n");
- for(i=0;i<10;i++) //使用数组方式输出
- {
- printf("%4d ",a[i]);
- }
- printf("\n使用一级指针变量输出数组各元素的值:\n");
- p=a;
- for(i=0;i<10;i++) //使用一级指针变量输出
- {
- printf("%4d ",*p++);
- }
- printf("\n使用二级指针变量输出数组各元素的值:\n");
- p=a;
- pp=&p;
- for(i=0;i<10;i++) //用二级指针变量输出
- {
- printf("%4d ",*(*pp+i));
- }
- printf("\n使用二级指针变量**p方式输出数组各元素的值:\n");
- p=a;
- for(i=0;i<10;i++,p++)//使用二级指针变量**p方式输出
- {
- printf("%4d ",**pp);
- }
- printf("\n");
- system("pause");
- 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】
- #include <stdio.h>//头文件
- #include <stdlib.h>
- int main()
- {
- int i,j,a[3][4]={{1,2,3,4},{5,6,7,8},
{9,10,11,12}}; //声明并初始化 - int *p,**pp;
- printf("用二级指针方式输出二维数组:\n");
- pp=&p;
- for(i=0;i<3;i++)//用二级指针方式输出
- {
- p=a[i];
- for(j=0;j<4;j++)
- printf("%4d",*(*pp+j));
- printf("\n");
- }
- printf("用二级指针**pp输出二维数组:\n");
- for(i=0;i<3;i++)//用二级指针**pp输出
- {
- p=a[i];
- for(j=0;j<4;j++,p++)
- printf("%4d",**pp);
- printf("\n");
- }
- printf("\n"); //输出换行
- system("pause");
- 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】
- #include <stdio.h> //头文件
- #include <stdlib.h>
- #include <string.h>
- void strsort(char **p,int n); //函数声明
- int main()
- {
- int i;
- char *s[]={ //初始化
- "C",
- "Basic",
- "Foxpro",
- "Visual Studio"
- };
- strsort(s,sizeof(s)/4); //排序
- printf("\n排序后的数据:\n");
- for(i=0;i<sizeof(s)/4;i++) //输出
- {
- printf("%s\n",s[i]);
- }
- system("pause");
- return 0;
- }
- void strsort(char**p,int n) //自定义函数
- {
- int i,j;
- char *pstr;
- for(i=0;i<n-1;i++)
- {
- for (j=i+1;j<n;j++)
- {
- if (strcmp(*(p+i),*(p+j))>0)//比较
- {
- pstr=*(p+j);
- *(p+j)=*(p+i);
- *(p+i)=pstr;
- }
- }
- }
- }
编译执行这段程序,得到如下结果,如图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) 编辑 收藏 举报