c语言的一级指针和二级指针做为函数参数,链表,malloc中的分配等等总结

原文网址:https://blog.csdn.net/u011123091/article/details/82055257小程序

c语言的一级指针和二级指针做为函数参数,链表,malloc中的分配等等总结主要内容:ide

一、一级指针和二级指针函数

二、函数指针传递的例子.net

三、何时须要传递二级指针?3d

四、二级指针在链表中的使用指针

一、一级指针和二级指针
一级指针:即咱们通常说的指针,就是内存地址;code

二级指针:指向指针的指针,就是地址的地址;blog

如:内存

int a=1;

int *p=&a;  // p为a变量的地址,经过*p能够获得a的值

int **q=&p;   // q为p指针的地址,经过**q能够获得a的值

二、函数指针传递的例子
程序1:get

#include<stdio.h>

void  fun(int  *p){

    int  b=100;

    p=&b;

}

int main(){

    int  a=10;

    int  *q;

    q=&a;

    printf("%d\n",*q);

    fun(q);

    printf("%d\n",*q);

    return  0;

}

运行结果:

10

10

程序2:

#include<stdio.h>

void  fun(int  **p){

    int  b=100;

    *p=&b;

}

int main(){

    int  a=10;

    int  *q;

    q=&a;

    printf("%d\n",*q);

    fun(&q);

    printf("%d\n",*q);

    return  0;

}

运行结果:

10

100

程序3:

#include<stdio.h>

#include<stdlib.h>

void  myMalloc(char  *s){

     s=(char*)malloc(100);

}

int main()

{

     char  *p=NULL;

     myMalloc(p);

     if(p==NULL)

        printf("P is not changed!\n");

     else{

        printf("P has been changed!\n");

        free(p);

     }

     return 0;

}

运行结果:

P is not changed!

程序4:

#include<stdio.h>

#include<stdlib.h>

void  myMalloc(char  **s){

     *s=(char*)malloc(100);

}

int main()

{

     char  *p=NULL;

     myMalloc(&p);

     if(p==NULL)

        printf("P is not changed!\n");

     else{

        printf("P has been changed!\n");

        free(p);

     }

     return 0;

}

运行结果:

P has been changed!

三、何时须要传递二级指针?

经过上述例子,咱们能够看到,在某些状况下,函数参数传递一级指针时,在函数体内对指针作变更,也不会对原始指针产生变化,而传递二级指针时,则能够,这是为何呢?

在传递一级指针时,只有对指针所指向的内存变量作操做才是有效的;

在传递二级指针时,只有对指针的指向作改变才是有效的;

下面作简单的分析:

在函数传递参数时,编译器总会为每一个函数参数制做一个副本,即拷贝;

例如:

void fun(int *p),指针参数p的副本为_p,编译器使_p=p,_p和p指向相同的内存空间,若是在函数内修改了_p所指向的内容,就会致使p的内容也作相应的改变;

但若是在函数内_p申请了新的内存空间或者指向其余内存空间,则_p指向了新的内存空间,而p依旧指向原来的内存空间,所以函数返回后p仍是原来的p。

这样的话,不但没有实现功能,反而每次都申请新的内存空间,而又得不到释放,由于没有将该内存空间的地址传递出来,容易形成内存泄露。

void fun(int **p),若是函数参数是指针的地址,则能够经过该参数p将新分配或新指向的内存地址传递出来,这样就实现了有效的指针操做。

若是以为二级指针比较难理解,也能够经过函数返回值的形式来传递动态内存(切记不能返回栈内存),如:

#include<stdio.h>

#include<stdlib.h>

char* myMalloc(){

     char *s=(char*)malloc(100);

     return s;

}

int main()

{
     char  *p=NULL;

     p=myMalloc();

     if(p==NULL)

        printf("P is not changed!\n");

     else{

        printf("P has been changed\n");

        free(p);

     }
     return 0;
}

知道了上述这些,就不难理解上面四个小程序的执行结果了。

四、二级指针在链表中的使用
在链表或者树的操做中,也须要用到二级指针,

好比建立链表的头指针:

在初始化链表函数中,传入头指针,并在函数中为该指针分配空间,此时就应该使用二级指针,如void initLinklist(Node **head);

而在添加删除结点的过程当中,咱们并无改变函数参数指针的指向,而是经过传入的指针如Node *head,找到要删除结点的位置,并未对该指针作改变,所以退出函数后,该指针无影响。

相关文章
相关标签/搜索