指向指针的指针的理解

转自:https://blog.csdn.net/oqqHuTu12345678/article/details/60962223



结合http://blog.csdn.net/oqqhutu12345678/article/details/60963087来看。

结合http://blog.csdn.net/oqqhutu12345678/article/details/68489807来看。


(1)在子函数中修改主函数传过来的指针的指向

  • 比如主函数申明一个指针变量,且不为其分配指向空间(只是指向NULL),然后取该指针变量的地址传参给子函数;
  • 在子函数里根据需要申请一片空间;
  • 对传参解引用后得到原来的指针变量,且把该指针变量指向刚才申请的空间(修改了原来指针的指向,这是本质);
  • 从而实现不确定返回值个数的编程方法(这是应用);

例子1(本质):

  1. #include<stdio.h>  
  2. int find(char s, char src, char **rt)//从s中查询出src字符所在的位置并在rt中返回。  
  3. {  
  4.     int i = 0;  
  5.     while ((s + i))  
  6.     {  
  7.         if ((s + i) == src)//只会出现一次满足条件,此时将此地址给*rt,即p  
  8.         {  
  9.              rt = s + i;//这里修改了p的指向  
  10.         }  
  11.         i++;  
  12.     }  
  13.     return 0;  
  14.  }  
  15.   
  16.   
  17. int main(void)  
  18. {  
  19.    char a[10] = “zhuyujia”;  
  20.    char p=NULL;  
  21.    find(a, ’y’, &p);//改变p的指向,在子函数中实现  
  22.    printf(”%s”, p);  
  23.    getchar(); getchar();  
  24.    return 0;  
  25. }  
  26.   
  27. / 
  28. //补充: 
  29. 打印指针的时候,会把指针所指向的内容以及至字符串末位的内容都打印出来 
  30. #include<stdio.h> 
  31. int main(void) 
  32. { 
  33.     char a[10] = “abcdefgff”; 
  34.     char* p = &a[6]; 
  35.     printf(“%s”, p);//会打印gff 
  36.     getchar(); getchar(); 
  37.     return 0; 
  38. } 
  39. */  
#include<stdio.h> 
int find(char *s, char src, char **rt)//从s中查询出src字符所在的位置并在rt中返回。
{
int i = 0;
while (*(s + i))
{
if (*(s + i) == src)//只会出现一次满足条件,此时将此地址给*rt,即p
{
* rt = s + i;//这里修改了p的指向
}
i++;
}
return 0;
}

int main(void)
{
char a[10] = “zhuyujia”;
char *p=NULL;
find(a, ‘y’, &p);//改变p的指向,在子函数中实现
printf(“%s”, p);
getchar(); getchar();
return 0;
}

/*
//补充:
打印指针的时候,会把指针所指向的内容以及至字符串末位的内容都打印出来

include<stdio.h>

int main(void)
{
char a[10] = "abcdefgff";
char* p = &a[6];
printf("%s", p);//会打印gff
getchar(); getchar();
return 0;
}
*/


例子2:

  1. #include <stdlib.h>  
  2. #include <time.h>  
  3. #include<stdio.h>  
  4. /*当然有必须使用二级指针才能解决的情况,如,某个函数的功能是 
  5. 返回某个问题的计算结果,但是结果数据是不确定个数的值,所以 
  6. 在调用此函数时不知道事先应分配多少空间来保存返回的数据,此时 
  7. 的处理办法就是传递一个没有分配空间的指针的指针(地址)进去, 
  8. 让函数自己根据计算的结果分配足够的空间来保存结果,并返回, 
  9. 调用者使用了结果后,由调用者负责内存的释放,即,大家可能听说 
  10. 过的”谁使用(调用)谁释放”之类的话,如下面的代码:*/  
  11.   
  12. //返回不定结果个数的计算函数  
  13. //参数int **pResult  保存返回数据的指针的指针  
  14. //参数int &count     保存返回的结果个数  
  15. void Compute2(int **pResult, int &count)  
  16. {  
  17.     //使用随机数来模拟计算结果数的个数  
  18.     srand(time(NULL));  
  19.     count = rand() % 10;//控制个数在10个以内  
  20.   
  21.     *pResult = new int[count];//*pResult相当于主函数传来的pResult指针,  
  22.                               //这里就修改了主函数中的pResult指向,因为还是指针,因此可以指向新开辟的空间  
  23.     for (int i = 0; i < count; i++)  
  24.     {  
  25.         (*pResult)[i] = rand();//给结果随即赋值  
  26.     }  
  27. }  
  28.   
  29. //返回不定结果个数的计算函数(此函数不能返回数据)  
  30. //参数int *pResult   为保存返回数据的指针  
  31. //参数int &count     为保存返回的结果个数  
  32. void Compute1(int *pResult, int &count)  
  33. {  
  34.     //使用随机数来模拟计算结果数的个数  
  35.     srand(time(NULL));  
  36.     count = rand() % 10;//控制个数在10个以内  
  37.   
  38.     pResult = new int[count];  
  39.     for (int i = 0; i < count; i++)  
  40.     {  
  41.         pResult[i] = rand();//给结果随即赋值  
  42.     }  
  43. }  
  44.   
  45. int main(void)  
  46. {  
  47.     int *pResult = NULL;//待获取结果的指针,这里没有分配空间大小,因为不知道返回结果的个数  
  48.                         //具体返回的个数在在子函数中确定,此时指针pResult指向也改变了  
  49.                         //这就间接的说明“在子函数中修改主函数传来的指针”的意图  
  50.                         //具体的应用就在于返回个数不确定的场景,这是后面编程的一个体会点  
  51.     int count = 0;//返回结果的个数  
  52.   
  53.                   /*  
  54.                   Compute1(pResult,count);//pResult为指针,第二个参数使用引用传递,  
  55.                   //使用这个函数时,在函数内部分配的内存的指针并没有返回到主函数中  
  56.                   for ( int i = 0 ; i < count ; i++ )  
  57.                   printf(”第 %d 个结果为 : %d\n”,pResult[i]);//执行了Compute1()函数后,pResult的值还是为NULL  
  58.                   delete [] pResult;  
  59.                   pResult = NULL;  
  60.                   */  
  61.   
  62.     Compute2(&pResult, count); //&pResult为指针的地址(即指针的指针),第二个参数使用引用传递  
  63.     for (int i = 0; i < count; i++)  
  64.         printf(”第 %d 个结果为 : %d\n”, i, pResult[i]);  
  65.   
  66.     delete[] pResult;  
  67.     pResult = NULL;  
  68.   
  69.     getchar();  
  70.     return 0;  
  71. }  
#include <stdlib.h>




include <time.h>

include<stdio.h>

/*当然有必须使用二级指针才能解决的情况,如,某个函数的功能是
返回某个问题的计算结果,但是结果数据是不确定个数的值,所以
在调用此函数时不知道事先应分配多少空间来保存返回的数据,此时
的处理办法就是传递一个没有分配空间的指针的指针(地址)进去,
让函数自己根据计算的结果分配足够的空间来保存结果,并返回,
调用者使用了结果后,由调用者负责内存的释放,即,大家可能听说
过的"谁使用(调用)谁释放"之类的话,如下面的代码:*/

//返回不定结果个数的计算函数
//参数int **pResult 保存返回数据的指针的指针
//参数int &count 保存返回的结果个数
void Compute2(int **pResult, int &count)
{
//使用随机数来模拟计算结果数的个数
srand(time(NULL));
count = rand() % 10;//控制个数在10个以内

*pResult = new int[count];//*pResult相当于主函数传来的pResult指针,
                          //这里就修改了主函数中的pResult指向,因为还是指针,因此可以指向新开辟的空间
for (int i = 0; i &lt; count; i++)
{
    (*pResult)[i] = rand();//给结果随即赋值
}

}

//返回不定结果个数的计算函数(此函数不能返回数据)
//参数int *pResult 为保存返回数据的指针
//参数int &count 为保存返回的结果个数
void Compute1(int *pResult, int &count)
{
//使用随机数来模拟计算结果数的个数
srand(time(NULL));
count = rand() % 10;//控制个数在10个以内

pResult = new int[count];
for (int i = 0; i &lt; count; i++)
{
    pResult[i] = rand();//给结果随即赋值
}

}

int main(void)
{
int *pResult = NULL;//待获取结果的指针,这里没有分配空间大小,因为不知道返回结果的个数
//具体返回的个数在在子函数中确定,此时指针pResult指向也改变了
//这就间接的说明“在子函数中修改主函数传来的指针”的意图
//具体的应用就在于返回个数不确定的场景,这是后面编程的一个体会点
int count = 0;//返回结果的个数

              /*
              Compute1(pResult,count);//pResult为指针,第二个参数使用引用传递,
              //使用这个函数时,在函数内部分配的内存的指针并没有返回到主函数中
              for ( int i = 0 ; i &lt; count ; i++ )
              printf("第 %d 个结果为 : %d\n",pResult[i]);//执行了Compute1()函数后,pResult的值还是为NULL
              delete [] pResult;
              pResult = NULL;
              */

Compute2(&amp;pResult, count); //&amp;pResult为指针的地址(即指针的指针),第二个参数使用引用传递
for (int i = 0; i &lt; count; i++)
    printf("第 %d 个结果为 : %d\n", i, pResult[i]);

delete[] pResult;
pResult = NULL;

getchar();
return 0;

}

(2)用指针的指针取二维数组的元素

  1. /* 
  2. #include<stdio.h 
  3.  
  4. //错误的做法 
  5. int change(char **p) 
  6. { 
  7.     int i, j; 
  8.     for (i = 0; i < 5; i++) 
  9.     { 
  10.         for (j = 0; *(*(p + i) + j) != ’\0’; j++) 
  11.         { 
  12.             printf(“%c”, *(*(p + i) + j)); 
  13.         } 
  14.         printf(“\n”); 
  15.     } 
  16.     return 0; 
  17. } 
  18.  
  19. //若希望赋值,则不能使用指针的指针,要使用数组进行运算。 
  20. int change(char p[][10]) 
  21. { 
  22.    int i, j; 
  23.    for (i = 0; i < 5; i++) 
  24.    { 
  25.      for (j = 0; p[i][j] != ’\0’; j++) 
  26.      { 
  27.         p[i][j] = ‘c’; 
  28.         printf(“%c”, p[i][j]); 
  29.      } 
  30.      printf(“\n”); 
  31.    } 
  32.    return 0; 
  33. } 
  34.  
  35. int main(void) 
  36. { 
  37.     char a[5][10] = { “hello”, “zhuyu”, “jiajia”, “linux”,”Ubuntu” }; 
  38.     change(a); 
  39.     return 0; 
  40. } 
  41.  
  42. */  
  43.   
  44.   
  45. #include<stdio.h>   
  46. int change(char **p)  
  47. {  
  48.     int i, j;  
  49.     for (i = 0; i < 5; i++)  
  50.     {  
  51.         for (j = 0; *(*(p + i) + j) != ‘\0’; j++)//利用指针的指针取二维数组的元素  
  52.         {  
  53.             *(*(p + i) + j) = ’c’;  
  54.             printf(”%c”, *(*(p + i) + j));  
  55.         }  
  56.         printf(”\n”);  
  57.     }  
  58.     return 0;  
  59. }  
  60.   
  61. int main(void)  
  62. {  
  63.     char a[5][10] = { “hello”“zhuyu”“jiajia”“linux”,“Ubuntu” };  
  64.     char *b[5] = { a[0],a[1],a[2],a[3],a[4] };//这样做读取和写入操作都是可以的。  
  65.     change(b);  
  66.     return 0;  
  67. }  
/*




include<stdio.h

//错误的做法
int change(char **p)
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; ((p + i) + j) != '\0'; j++)
{
printf("%c", ((p + i) + j));
}
printf("\n");
}
return 0;
}

//若希望赋值,则不能使用指针的指针,要使用数组进行运算。
int change(char p[][10])
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; p[i][j] != '\0'; j++)
{
p[i][j] = 'c';
printf("%c", p[i][j]);
}
printf("\n");
}
return 0;
}

int main(void)
{
char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };
change(a);
return 0;
}

*/

include<stdio.h>

int change(char **p)
{
int i, j;
for (i = 0; i < 5; i++)
{
for (j = 0; ((p + i) + j) != '\0'; j++)//利用指针的指针取二维数组的元素
{
((p + i) + j) = 'c';
printf("%c", ((p + i) + j));
}
printf("\n");
}
return 0;
}

int main(void)
{
char a[5][10] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };
char *b[5] = { a[0],a[1],a[2],a[3],a[4] };//这样做读取和写入操作都是可以的。
change(b);
return 0;
}

(3)用指针的指针指向指针数组

  1. #include<stdio.h>   
  2. int change(char **p)  
  3. {  
  4.     int i, j;  
  5.     for (i = 0; i < 5; i++)  
  6.     {  
  7.         for (j = 0; *(*(p + i) + j) != ‘\0’; j++)//利用指针的指针取二维数组的元素  
  8.         {  
  9.             *(*(p + i) + j) = ’c’;  
  10.             printf(”%c”, *(*(p + i) + j));  
  11.         }  
  12.         printf(”\n”);  
  13.     }  
  14.     return 0;  
  15. }  
  16.   
  17. int main(void)  
  18. {  
  19.     char *a[5] = { “hello”“zhuyu”“jiajia”“linux”,“Ubuntu” };//如果想使用 需使用指针数组即*a[5] 声明一个有五个字符串指针的数组。  
  20.                                                                   //但是由于每个元素都是指针字符串,所以只能够读取,而不能够写入。  
  21.     change(a);  
  22.     return 0;  
  23. }  
#include<stdio.h> 
int change(char **p)
{
    int i, j;
    for (i = 0; i < 5; i++)
    {
        for (j = 0; *(*(p + i) + j) != '\0'; j++)//利用指针的指针取二维数组的元素
        {
            *(*(p + i) + j) = 'c';
            printf("%c", *(*(p + i) + j));
        }
        printf("\n");
    }
    return 0;
}

int main(void)
{
    char *a[5] = { "hello", "zhuyu", "jiajia", "linux","Ubuntu" };//如果想使用 需使用指针数组即*a[5] 声明一个有五个字符串指针的数组。
                                                                  //但是由于每个元素都是指针字符串,所以只能够读取,而不能够写入。
    change(a);
    return 0;
}


            </div>


猜你喜欢

转载自blog.csdn.net/hunjiancuo5340/article/details/80680120