二级指针个人笔记

来源:互联网 发布:it是哪个国家 编辑:程序博客网 时间:2024/05/17 18:29
#include <stdio.h>
int a = 10;
int b = 100;
int *q;


void func1(int *q)
{
printf("--------------\n");
printf("进入func函数中!\n");
printf("*q=%d, q=%p\n", *q, q);
q= &b;
printf("*q=%d, q=%p\n", *q, q);
printf("func函数执行完成!\n");
printf("--------------\n");
}
void func2(int **q)
{
printf("--------------\n");
printf("进入func函数中!\n");
printf("&q=%p,q=%d\n", *q, q);


*q = &b;


printf("&q=%p,q=%d\n", *q, q);
printf("func函数执行完成!\n");
printf("--------------\n");
}


int main()
{
printf("&a=%p, &b=%p, &q=%p\n", &a, &b,&q); //得到a,b,q三者的地址
q = &a;  //让指针q指向a的地址
printf("*q=%d, q=%d, &q=%p\n", *q, q, &q); 
func1(q); //输入了指针q指向的地址,期望替换成b的地址
//func2(&q);
printf("*q=%d, q=%d, &q=%p\n", *q, q, &q);
return 0;

}



在func1中,输入了q指向的地址,期望在其中将其由指向a转为指向b。在此函数中进行输出,发现也确实发生了更改,然而在函数外面却没有实现预期的功能。可见,在函数体中,运行的还是q的拷贝罢了。


在func2中,输入的是指针q的地址。然后在这个地址里面,*q的指向由&a(见main函数)变为func2函数里的指向&b。从而实现了更改。


再联系一下那个经典的指针swap函数可以发现套上了指针,才可以真正的修改里面的东西。



2017.12.4  一些关于二级指针和链表的结论

转自 http://blog.csdn.net/u012234115/article/details/39717215

得出结论:

1,初始化链表头部指针需要用二级指针或者一级指针的引用。

2,销毁链表需要用到二级指针或者一级指针的引用。

3,插入、删除、遍历、清空结点用一级指针即可。


分析:
1,只要是修改头指针则必须传递头指针的地址,否则传递头指针值即可(即头指针本身)。这与普通变量类似,当需要修改普通变量的值,需传递其地址,否则传递普通变量的值即可(即这个变量的拷贝)。使用二级指针,很方便就修改了传入的结点一级指针的值。 如果用一级指针,则只能通过指针修改指针所指内容,却无法修改指针的值,也就是指针所指的内存块。所以创建链表和销毁链表需要二级指针或者一级指针引用。

2,不需要修改头指针的地方用一级指针就可以了,比如插入,删除,遍历,清空结点。假如头指针是L,则对L->next 及之后的结点指针只需要传递一级指针。

3,比如一个结点p,在函数里要修改p的指向就要用二级指针,如果只是修改p的next指向则用一级指针就可以了


函数中传递指针,在函数中改变指针的值,就是在改变实参中的数据信息。但是这里改变指针的值实际是指改变指针指向地址的值,因为传递指针就是把指针指向变量的地址传递过来,而不是像值传递一样只是传进来一个实参副本。所以当我们改变指针的值时,实参也改变了。

    


2017.12.5 更新

带头结点的初始化在堆开辟了一段内存,需要修改head指针变量指向的地址(即head的值),所以要修改head的值,必须传保
存head变量的地址(即二维指针)。而直接调用CreatList(head);相当于传head变量的值,函数修改的是head的副本,无法真正改变head的值。


原创粉丝点击