再谈C语言指针变量 (注定与你有多交集)

  • 引子

什么时候使用一级指针?什么时候使用二级指针?一/二级指针对实参形参能造成什么影响?为什么链表创建,清空,删除结构体指针级别的不同造成什么样的影响?…等等宇宙大难题,至今还没搞明白,希望能通过交换变量的的例子来进一步加深对指针、全局/局部变量、以及实参形参传递方向的理解和记忆。

 

  1. 全局变量/局部变量(作用域问题)
  2. 关于实参形参
  3. 关于指针级别(略)
  4. 关于指针函数(?_?可能说的不对,看下方解释)
  5. 函数指针,函数参数为指针类型。
  1. 设有以下函数:

Void f(int a,char *s)

{

   …;

   …;

}

此处char *s 即是将指针作为函数参数来使用的。!

  1. 所谓指针函数,其实不应该这么叫它 因为我们已经有了指针数组,表明它是一个数组。 同理指针函数归根结底他是一个函数,是这个函数的返回值基类型为void *的指针函数,所以看如下定义:

int  *fun(int,char *);//这样声明就说明他是一个函数,函数有返回值

 

  1. 关于函数指针,归根结底,他是一个指针;指针指向谁?指向函数的指针;它的作用是:将一个变量的地址传送到另一个函数中,函数名代表函数的入口地址。见如下定义

int (*fun)(int,char *);//函数指针定义

fun = f;//指针变量赋函数f()的入口地址 同样能够在初始化的时候定义。

        值得注意的是:取函数的地址更不用加取地址符号&。注意实参与形参类型匹配。比较两者差异的细微区别就在于()优先级!这一点同数组指针类似 即int (*p)[10];//二维数组指针。 int *p[10] ó int (*p[10]) //指针数组。而指针函数int *fun();不是指里面的所有形参都是指针,而是指该定义的函数的返回值是int *。

下面是我在学习中遇到的问题,思考:

1.如何利用一级指针改变主调函数main()中的参数?(以交换变量值为例),显然这是不可取的?!

#include <stdio.h>


int *f(int *,int *);

int a=5,b=6;//全局变量整个程序(进程)消亡后回收


int main()

{

    int *s;

    int *p1 = &a , *p2 = &b;

   

    s = f(p1,p2);

   

    printf("a=%d\nb=%d\n*p1=%d\n*p2=%d\n*s=%d\n",a,b,*p1,*p2,*s);

    //结果 为 5 6 5 6 6 天真地发现主调函数调用完后并不改变指向?

    return 0;

}


int *f(int *m ,int *n)

{

    int *p;

   

    p = m;

    m = n;

    n = p;

   

    return m;

}

此处,需要理解程序的死亡,函数调用完结束后空间收回,实参与形参传递问题 局部变量,全局变量作用域的问题

 

于是乎,我使用了二级指针 当时我就想我还是不理解上述所说的问题 ,我就用二级指针 这样我就明白函数调用 结束返回后 时个什么玩意儿 形参指针变量影不影响主调函数内实参指针变量 为什么值带不回去?(其实知者所知:当前在操作地址,只不过一个是直接寻址 另一个是间接寻址 而并未对地址指向的值操作 改变不了什么。)

#include <stdio.h>


int **f(int **,int **);


int main()

{

    int a=5,b=6,**s;

    int *p1 = &a , *p2 = &b;

    printf("pre_a=%d\npre_b=%d\n\n",a,b);

     

    s = f(&p1,&p2);

    printf("a=%d\nb=%d\n*p1=%d\n*p2=%d\n*s=%d\n",a,b,*p1,*p2,**s);

//结果仍然为:5 6 5 6 6 ;发现二级指针在被调函数f()内的确交换了位置 并且把交换后的地址赋给了变量s

    return 0;

}
int **f(int **m,int **n)

{

    //int a;

    //int *p1 = &a;

    int **p2;

   

    p2 = m;

    m = n;

    n = p2;

   

    return m;

}

 

经过几许辗转反侧、看书、问同学、消耗时间 总结: 被调函数调用结束后整个函数就消亡了,而我只带回了一个地址(值) 局部变量**p2被收回(函数消亡) 如果没有一个容器s来装这个地址,那么照样无法进行址交换 ,故我现在操作的是地址 而不是地址所指向的值 仅仅交换指向 被调函数调用结束后,死亡、局部变量空间收回;程序死亡后 全局变量空间被收回。

于是 我回归到最初 其实这些老师上课都有说明! 这里仅用这个比较好的例子来更好为自己总结  ;改变了原来的想法 来看看!

#include <stdio.h>


int *f(int *,int *);


int main()

{

    int a=5,b=6,*s;

    int *p1 = &a , *p2 = &b;

    printf("pre_a=%d\npre_b=%d\n",a,b);

   

    s = f(p1,p2);

    printf("a=%d\nb=%d\n*p1=%d\n*p2=%d\n*s=%d\n",a,b,*p1,*p2,*s);

   

    return 0;

}


int *f(int *m ,int *n)

{

    int a;

    int *p = &a; //这里必须要使用一个变量来给指针变量存放地址 也是防止野指针的手段

   

    *p = *m;

    *m = *n;

    *n = *p;

   

    return m;

}

 

同理 二级指针操作函数来改变值,是要真正意义上的改变值,而非异想天开的想通过改变指针指向来改变指向,“指向变了 值就变了”这一说法。是作为初学者的我没理解程序运行的流程 实参形参的传递性 全局,局部,静态,创建变量而改变内存空间性质 产生的原因。(关于这块,我仍然只是理解皮毛,仍需后续进一步的通过各种程序锻炼 来理解其中的奥秘!)

#include <stdio.h>


int **f(int **,int **);


int main()

{

    int a=5,b=6,**s;

    int *p1 = &a , *p2 = &b;

    printf("pre_a=%d\npre_b=%d\n\n",a,b);

     

    s = f(&p1,&p2);

    printf("a=%d\nb=%d\n*p1=%d\n*p2=%d\n*s=%d\n",a,b,*p1,*p2,**s);

//结果发现,与欲达到的值稳合了!!

    return 0;

}



int **f(int **m,int **n)

{

    int a;

    int *p1 = &a;

    int **p2 = &p1;

   

    **p2 = **m;

    **m = **n;

    **n = **p2;

   

    return m;

}

以上 有很多说到的知识点 没做补充说明;学才疏浅而只能为自己和相似的人做贡献。这里也有自己目前的学习见解 以交换值为例子 可以更好地解释我在做题时遇到的问题。

 

什么时候使用一级指针 ,什么时候使用二级指针 这也是需要去积极探索和理解的! 例如在链表中 插入 和 删除 清空 使用一级指针 二级指针 导致的结果 为什么回是这样的结果 它到底是指结点的那块地址 是我们后续需要加以积极探索的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值