zoukankan      html  css  js  c++  java
  • 二级指针的简单运用

      在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("使用数组方式输出数组各元素的值: ");  
    10.     for(i=0;i<10;i++)   //使用数组方式输出  
    11.     {  
    12.         printf("%4d  ",a[i]);  
    13.     }  
    14.  
    15.     printf(" 使用一级指针变量输出数组各元素的值: ");  
    16.     p=a;  
    17.     for(i=0;i<10;i++)   //使用一级指针变量输出  
    18.     {  
    19.         printf("%4d  ",*p++);  
    20.     }  
    21.  
    22.     printf(" 使用二级指针变量输出数组各元素的值: ");  
    23.     p=a;  
    24.     pp=&p;  
    25.     for(i=0;i<10;i++)   //用二级指针变量输出  
    26.     {  
    27.         printf("%4d  ",*(*pp+i));  
    28.     }  
    29.  
    30.     printf(" 使用二级指针变量**p方式输出数组各元素的值: ");  
    31.     p=a;  
    32.     for(i=0;i<10;i++,p++)//使用二级指针变量**p方式输出  
    33.     {  
    34.        printf("%4d  ",**pp);  
    35.     }  
    36.  
    37.     printf(" ");  
    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("用二级指针方式输出二维数组: ");  
    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(" ");  
    17.     }  
    18.  
    19.     printf("用二级指针**pp输出二维数组: ");  
    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(" ");  
    26.     }  
    27.  
    28.     printf(" ");   //输出换行  
    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(" 排序后的数据: ");  
    19.     for(i=0;i<sizeof(s)/4;i++)      //输出  
    20.     {  
    21.         printf("%s ",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()比较两个字符串的大小,再根据需要交换指针。

  • 相关阅读:
    P3469 [POI2008]BLO-Blockade
    洛谷P2342 叠积木
    洛谷 P1197 [JSOI2008]星球大战
    洛谷P1967 货车运输
    洛谷P2812校园网络【Network of Schools加强版】
    洛谷P3003 苹果交货Apple Delivery
    luogu Eat the Trees
    插头DP模板
    [NOIP2017] 宝藏
    LOJ6268拆分数
  • 原文地址:https://www.cnblogs.com/wgang171412/p/4984273.html
Copyright © 2011-2022 走看看