指针问题梳理
来源:互联网 发布:2017年网络热点话题 编辑:程序博客网 时间:2024/06/16 01:53
指针好像一直都是一个头疼的问题,从一级指针到二级指针的运用,总是经常出错。今天遇到的一个二级指针的问题,花了很多时间,想了一个比较合理的解释。
今天在数据结构的实验中,用一个二级指针作为参数来写了一个二叉树的建立。大概的函数代码如下:
存储结构如下:
/*树的存储结构*/typedef struct Tree { char data; struct Tree *Lift; struct Tree *Right;}Tree,*Btree;
/*二级指针建立二叉树*/void crea(Btree *root){ printf("%p\n",root); char ch; ch = getchar(); if(ch=='#') { (*root) = NULL; } else { *root=(Tree *)malloc(sizeof(Tree)); (*root)->data = ch; // printf("ch=%ckk\n",ch); if((*root)==NULL) { exit(0); } crea((&(*root)->Right)); crea((&(*root)->Lift)); }}
然后为了测试这个创建二叉树的函数对不对,我在主函数里,简单地定义了一个二级指针,给传了进去,然后问题来了。
int main(){ Btree *p; crea(p);}
然后程序,跑到malloc的时候就断错误了。
*root=(Tree *)malloc(sizeof(Tree)); printf("%c\n",ch);//该输出是输出不了的,以段错误结束
然后改了下主函数传递参数的方式,就能够正常的malloc了。
int main(){ Btree p; //一级指针 crea(&p); //传入一级指针本身的地址}
同样相当于二级指针,但是为什么第一种就会出现断错误。主要原因是malloc一块明确的空间后要给一个明确的地址。
最简单的列子(首先搞懂自定义函数形参怎么传递的)
#include<stdio.h>#include<stdlib.h>int fun(int a){ a++; return a;}int main(){ int b = 0; int a = 10; fun(a); b = fun(b); printf("b=%d\n",b); printf("a=%d\n",a); return 0;}
在C语言中,函数的参数传递是值传递,素以fun(a),只是把a的值传递给了自定义函数中的a,然后a在自定义函数中自加,但是主函数里面的a是不变的,只是多了return,return会把a自加的结果赋值给主函数中的b。结果如下:
但是这个传递给这个自定义函数的是一个主函数里a变量的地址,那么在自定义函数中就会对这个a进行改变。
#include<stdio.h>#include<stdlib.h>int fun(int *a){ (*a)++; return *a;}int main(){ int b = 0; int a = 10; fun(&a); b = fun(&b); printf("b=%d\n",b); printf("a=%d\n",a); return 0;}
第二个代码中,在形参定义的是一个指向int类型的指针,而从主函数中传入的是a变量的地址,那么形参将获得主函数中a的地址,然后直接在a的地址上操作其内容。而第一个代码中,形参只是获得了a的数值,并没有获得其本身的地址,所以没有对主函数中的变量a进行改变的权利。第二个代码中,传递的值是a的地址值,直接从地址值对a进行了改变。
然后理解中的指针(有它自己的地址值,和存储的区域)
所以我理解的二级指针(**p)大概就是:
所以一级指针便是(*p):
最后回到原来的错误代码
int main(){ Btree *p; crea(p);}
其中p是一个二级指针,因为Btree是*Btree。此时传入的是二级指针,是一个指针变量,并没有明确地指向某个空间。在自定义函数creat接收它之后,root指向了p,然后malloc开辟了一个明确的空间,接下来root将指向这个随机空间的首地址,但是在此之前,root指向了p,而p又没有指向一个明确的空间,所以此时的malloc会出错。
int main(){ Btree p; crea(&p);}
第二个代码中,p是一个一级指针变量,但是传入的时候&p,此时假如p指针本身的地址是100,那么就是将100传给了变量root,root是一个二级指针,是存储指针的指针变量,此时将100存入了root存储内容中,malloc一块空间后,再降root存储的这个地址的指针再指向malloc开辟的空间。此时malloc赋给了一个明确的指针。所以不会出错。
再举一个简单的类比例子
#include<stdio.h>#include<stdlib.h>int main(){ int *p; *p = 9; printf("p=%d\n",*p);}
会出现断错误,因为*p可以存内容为9的地址,但是不能直接降9赋给它,因为此时P没有明确地指向一个空间。可以用malloc给它指向一个明确的空间后,才能降9存入到其中。如下:
#include<stdio.h>#include<stdlib.h>int main(){ int *p; p = (int *)malloc(4); *p = 9; printf("p=%d\n",*p);}
或者这样:
#include<stdio.h>#include<stdlib.h>int main(){ int a = 9;//申请一个地址,初始化为9. int *p; //p = (int *)malloc(4); p = &a; printf("p=%d\n",*p);}
所以今天的代码还可以做这样的改正。
int main(){ Btree *p; Tree *q=NULL; //申请了一个地址,代号为p,初始化为NULL p = &q; //p明确存储了q的地址,因此**p传入之后有了明确指向 crea(p); //所以成功传入并没有发生错误}
感觉自己对指针的领悟还有待提升,如果这次这个解释存在错误的话,希望大家可以帮我指出。
- 指针问题梳理
- 函数指针语法梳理
- C++智能指针梳理
- C++智能指针梳理
- 数组指针语法梳理
- 函数指针语法梳理
- 指针知识梳理8- 指针的指针
- 指针知识梳理3-指针作为参数
- 指针知识梳理6-const与指针
- 指针知识梳理7- 函数指针
- 指针知识梳理9-指针数组
- 指针数组和数组指针梳理
- RecycleView使用问题梳理
- C语言梳理指针的混淆点
- 字符串常量,指针,数组,[],*各关系梳理
- python2.X编码问题梳理
- MYSQL问题梳理(备忘)
- 自签证书问题梳理
- Monkey的APK集合测试的设置方法
- bzoj1493
- 一个简单的压缩成tar.gz文件的shell脚本
- [编程题] 藏宝图
- 6.4
- 指针问题梳理
- git问题:You have not concluded your merge (MERGE_HEAD exists)
- java反射与代理
- Mac安装OpenCV(用于虚拟环境)
- Ubuntu14.04下编译pycaffe并绘制网络结构图
- 中国计算机学会推荐国际学术期刊
- 11月9日心得
- jQuery选择器
- BZOJ 4390: [Usaco2015 dec]Max Flow