上一篇写了结构产生的原因以及一些常识的结论,一般来说,常用的知识点就是这些,基本够用,但有时也容易产生一些小错误,这篇简单写下, 主要面向初学者。
传指针的小问题在C语言中,函数传参都是传值。有同学表示反对:书上是这么说的,可以传值,也可以传引用(地址)。其实是,两者都是传值。
比如
void test_pointer(int *p){ printf("%d
",*p);}int main(int argc, char* argv[]){ int a=10; test_pointer(&a); //传地址 return 0;}
调用test_pointer函数时,将a的地址传过去,我们知道地址是一个固定长度的4字节整数值(以VC6.0环境为例),test_pointer的函数栈中也会准备4字节来存放这个值,因此是传值。如下图所示:
如图所示,相当于将a的地址值0x0019fecc传过去,那么函数栈中也就有了一份地址数据。因此,结论是:传地址也只是传值。
有地址只能读不能修改这句话主要针对动态分配来说的,有一个指针p1传过去,赋值给参数p2,相当于有两个地址,且p1=p2。如果在函数内部进行malloc分配,并赋值给p2,但p1并未改变,只是因为两者都只是4字节大小的普通值。代码如下:
void test_pointer(char *p2){ //p2变化了 p2=(char*)malloc(100);}int main(int argc, char* argv[]){ char *p1; test_pointer(p1); return 0;}
那么怎么办呢?只能将函数参数改为指向指针的指针。代码如下:
void test_pointer(char* *p2){ //*p2就是p1的值 *p2=(char*)malloc(100);}int main(int argc, char* argv[]){ char *p1; test_pointer(&p1); printf("%p
",p1); return 0;}
【分析】对于熟练的程序员来说不是一个问题,但对于初学者来说,是一个比较隐讳的错误。指向指针的指针比较麻烦一些,在C++中通过引用解决这个问题,代码如下:
void test_pointer(char* &p2){ //引用之后p2就是p1 p2=(char*)malloc(100); p2[0]='a';}int main(int argc, char* argv[]){ char* p1; test_pointer(p1); printf("%c
",p1[0]); // 'a' return 0;}
但是觉得代码还是不够清晰,使用typedef将类型包装一下,得到下面的样式:
typedef char* POINTER;void test_pointer(POINTER &p2){ //引用之后p2就是p1 p2=(POINTER)malloc(100); p2[0]='a';}int main(int argc, char* argv[]){ POINTER p1; test_pointer(p1); printf("%p
",p1); printf("%c
",p1[0]); return 0;}
经过这几步就将程序包装清楚了,下面到主题:结构体
二叉树的创建在《数据结构 算法分析与实现》书中讲到二叉树创建时,就运用了上面了这个模型,概括下就是:有一个指针值p当前是空的,传入函数之后,想通过动态分配让这个p得到值,那么我们设计形参时,要么传指向指针的指针,要么用C++模式传引用。下面是C++传引用的形式:
/* @C++传引用版本 @功能:创建二叉树*///二叉树结构定义typedef struct BiTNode{ char data; BiTNode *lchild,*rchild;}BiTNode,*BiTree;//创建二叉树//使用引用时,形参的T就等于实参的T,无缝衔接void CreateBiTree(BiTree &T){ char ch; scanf("%c",&ch); if(ch== ' ') T=NULL; el{ T=(BiTree)malloc(sizeof(BiTNode)); if(!T) exit(-1); T->data=ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); }}int main(int argc, char* argv[]){ //定义二叉树头指针 BiTree T; CreateBiTree(T); //输入:ab c ↘ //b后两个空格,c后两个空格,然后回车 return 0;}
最后,我们再看下C语言版本的
//结构定义typedef struct BiTNode{ char data; BiTNode *lchild,*rchild;}BiTNode,*BiTree;void CreateBiTree(BiTree *T){ char ch; scanf("%c",&ch); if(ch== ' ') *T=NULL; el{ *T=(BiTree)malloc(sizeof(BiTNode)); if(!T) exit(-1); (*T)->data=ch; CreateBiTree(&((*T)->lchild)); CreateBiTree(&((*T)->rchild)); }}int main(int argc, char* argv[]){ //定义二叉树头指针 BiTree T; CreateBiTree(&T); //输入:ab c ↘ //b后两个空格,c后两个空格,然后回车 return 0;}
【分析】可以看出使用C++引用更清晰一些
结语通过几个小例子说明了指针的使用方式,并写了一个关于结构体的问题。问题不是很难,但是需要谨小慎微。
如果文章的意思都能理解,那么在结构体的使用上基本不会有太大的问题!
本文发布于:2023-02-28 21:04:00,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/1677722748102424.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:vc6.0英文版(vc6.0英文版安装教程).doc
本文 PDF 下载地址:vc6.0英文版(vc6.0英文版安装教程).pdf
留言与评论(共有 0 条评论) |