深入理解C语言中两级指针(char **pptr)的参数的用法

来源:互联网 发布:税务系统网络信息安全 编辑:程序博客网 时间:2024/06/05 00:09

最近在看亚嵌的《Linux C编程一站式学习》,对其中的两层指针的参数用法有些疑惑,下面和大家分享一下学习心得!


首先来看一段代码:

/* main.c */#include <stdio.h>#include <stdlib.h>static const char *msgg[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};void get_w_day(const char **pp){     pp[0] = msgg[2]; // *pp     = msgg[0];     pp[1] = msgg[3]; // *(pp+1) = msgg[1];}int main(void){          char  ptr[2] = {};    const char  *pptr = ptr;    //这里初始化也可以为NULL,不会导致编译出错和运行时的段错误,但在实际程序中最好详细初始化    const char **ppptr = &pptr; //在ppptr参数传入get_w_day()函数之前,必须对其进行初始化,否则会导致运行时的段错误 //仔细想一下原因,如果ppptr是NULL,那么get_w_day()函数修改的*ppptr就会修改一个不确定的位置                                //进一步从底层查找原因,如果ppptr是NULL,那么传入get_w_day()时刻的实际值就是0x0,也就是我们要操作*((char*)0x00) = ??                                //这样必然导致一个段错误    get_w_day(ppptr);        char fuck      = **ppptr + 1;     //这里的fuck应该等于几? 答案是'U' ==> 'T'+1      char fuckk     = *(*ppptr + 1);   //如果是 fuck = *(*ppptr + 1) 呢? 答案是 'u' ==> 指向"Tuesday"头指针加1    char fuckkk    = **(ppptr + 1);   //如果是  **(ppptr + 1)呢?答案是'V'    char fuckkkk   = **((ppptr+1) + 1 //是'W' ==> 'V'+1    char fuckkkkk  = **((ppptr+2) + 1 //是一个不确定的值,有可能引起段错误    printf("%s\t%s\n", *ppptr, *(ppptr+1));      return 0;}


指针就是指向内存地址的变量,二级指针也是指针,即指向指针的指针,同样可以表示传入参数、传出参数或者Value-result参数,只不过该参数所指的内存空间应该解释成一个指针变量。

这里有一个法则,传入一个N级的指针,就可以修改N-1级的指针,原因是C语言的参数传递是按值传递的,直接修改形参是无法改变实参的,但可以通过传入的指针参数修改其指向的的内容,N级指针指向的内容就是一个N-1级的指针,边界情况就是参数是一个非指针类型的变量,可以理解为0级指针,这样就修改不了其内容。

对于上述代码,可以在gei_w_day()函数中,修改一级指针的内容,即可以修改×ppptr的值,而*ppptr 对应 pptr,这里把他看成一个字符串数组名,从而可以理解为可以在gei_w_day()函数中改变字符串数组中的0项、1项...的值。

        在来看看形参中const的作用,如下代码所示,

char ** p1;        // int元素不可修改char * const * p2; // int *一级指针不可修改char ** const p3;  // int **二级指针不可修改

思考题:

//思考题:如果将下述代码做改动,那么 printf("%s\t%s\n", *ppptr, *(ppptr+2)); 能否打印出void get_w_day(const char **pp){     pp[0] = msgg[2];      pp[1] = msgg[3];     pp[2] = msgg[4]; //新增...}




1 0
原创粉丝点击