近期写二叉树的数据结构实验。想用一个没有返回值的函数来创建一个树,发现这个树就是建立不起来,那么我就用这个样例讨论一下c语言中指针作为形參的函数中传递中隐藏的东西。

大家知道C++中有引用的概念,两个数据引用同一个数据,那么更改随意的一个都相当于更改了本体,那么还有一个数据所相应的值也会改变。但是C中是没有这个概念的。所以就产生了一些东西。和我们本来想的有区别。

一、明白C语言中函数的入口:

C语言中函数的形參负责接收外部数据。那么数据到底怎么进入函数的呢。事实上我们在函数体内操作的形參仅仅是传递进来參数的一个副本,也就是说这两个參数尽管名字一样,相应的值一样,可是他们两个相应的内存地址是不一样的,也就是说这就是两个“看上去一模一样”的全然不同的变量。

所以一定要知道。C语言中函数是值传递的。也就是说,C语言仅仅能把值传给函数,而不能把你想要传递的变量全然的放进函数内部。

二、指针传递给函数:

指针作为一个特殊的东西。他的强大之处就在于指针能够直接改动内存地址上的数据。尽管指针特别强大,可是他也难逃函数的限制,你传递给函数一个指针。由于是值传递。那么你在函数体内的使用的形參指针也仅仅是一个副本,仅仅是一个指向的值和你传进来的那个指针一样的一个另外的一个变量。也就是说他和普通常量是没有差别的。

三、我想要达到引用的效果怎么实现

C语言中由于是值传递的。那么我们就传递值,仅仅要讲想要传递进函数的东西的地址传进函数。而且函数用一个指针接收。那么就相当于把这个变量地址原封不动的传递给了函数,形參的指针指向的是外面传进来的地址。有了地址不就好办了吗。

四、以下是我写的一个二叉树建立的一个无返回值的版本号:

由于二叉树是用递归建立的,就像建立链表一样,一个节点一个节点建立,假设不获得上一个节点的地址。你怎么把链表连接起来呢,链表就散开了。

所以仅仅能通过传递地址来达到找到已经建好的链表的前驱,才干把各个节点穿起来。

#include <stdio.h>
#include <stdlib.h> typedef struct tree {
char t;
struct tree *lchild;
struct tree *rchild;
}Tree; void initTree(Tree **T) {
char ch;
ch = getchar();
if (ch == '#') {
*T = NULL;
}
else {
*T = (Tree *)malloc(sizeof(Tree));
(*T)->t = ch;
initTree(&(*T)->lchild);
initTree(&(*T)->rchild);
}
} void qianT(Tree *T) {
if (T) {
printf("%c ",T->t);
qianT(T->lchild);
qianT(T->rchild);
}
} int main (void) {
Tree *T;
initTree(&T);
qianT(T);
return 0;
}

注意看树的建立那个函数。我每次都是穿进去一个节点的地址,然后通过地址来找到已经建立好的树,才干将树建立起来。

那么有的人会问了?为什么不是以下这个写法呢?

void initTree(Tree *T) {
char ch;
ch = getchar();
if (ch == '#') {
T = NULL;
}
else {
T = (Tree *)malloc(sizeof(Tree));
T->t = ch;
initTree(T->lchild);
initTree(T->rchild);
}
}

这样的写法,你每次传进来的都是一个变量。说过,c语言是值传递的。那么每次你申请的节点空间都是给副本申请的。然后递归的是副本的左右孩子,也就是说你的树根本没有建立起来,由于每次申请的内存都没有连接上。

       为什么我的那个写法能够呢,由于我是用一个指向指针的指针来存地址的,我给传进来的地址申请了内存,也就相当于给穿进来的那个节点本身申请了内存,而不是给副本,所以二叉树就顺其自然建立起来了。

       最后记住,c语言是值传递的,不论什么东西传递给函数的都仅仅是值!

C语言中函数和指针的參数传递的更多相关文章

  1. C语言中函数参数传递的本质是值传递

    数组名做函数参数进行传递时,实际上是是一份该指针的拷贝. 给形参赋予其他值,并不影响实参的值. 类似于: int *p = a;    //a为数组名 p = b;          //b为数组名 ...

  2. C语言——指向函数的指针

    转载自:http://www.cnblogs.com/liangyan19910818/archive/2011/08/19/2145270.html C语言——指向函数的指针 函数类型 (* 函数指 ...

  3. C语言中函数参数传递

    C语言中函数参数传递的三种方式 (1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值.(2)地址传递,就是把 ...

  4. C语言中函数返回字符串的4中方法

    C语言中函数返回字符串的4中方法 函数的构成部分:返回类型.函数名称.参数.函数主体 参数:函数调用时传入的参数称为实参,函数定义时出现的参数为形参 形参的作用在于接收实参传入的值,形参和函数内部的其 ...

  5. C语言中函数的调用方式

    第一眼看到这样一个题目的我,心想除了如下的直接调用还能怎么调用呢? 1 void fun(void) 2 { 3 ...... 4 //你的代码 5 ..... 6 } 7 int main(void ...

  6. windev中的内存机制及其与C语言中的内存指针相似性(一)

    windev中的内存机制,是初入windev世界必须要越过的一道高山,以下我的理解和经验未必都对,如有错误或遗漏,以后再纠正或补充!另外,以下内容,咱先谈应用,再说对机制的认识和理解. 一.新建表单, ...

  7. c语言中函数的简单介绍

    c语言中函数的介绍: 函数,简单的说就是代码的打包.存放在一个地方,当需要的时候调用. 函数分类: 1.无参无返回值函数 void func() 2.无参有返回值函数  int func() 3.有参 ...

  8. c语言中函数参数入栈的顺序是什么?为什么

    看到面试题C语言中函数参数的入栈顺序如何? 自己不知道,边上网找资料.下面是详细解释 #include <stdio.h> void foo(int x, int y, int z){   ...

  9. 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数

     1.指针数组 数组里面的每一个元素都是指针. 指针数组的案比例如以下: 易犯错误: 2.数组指针 归根结底还是指针,仅仅是取*的时候可以取出一整个数组出来. 数组指针:(一个指针指向了数组.一般 ...

随机推荐

  1. 29、Flask实战第29天:cms用户名渲染和注销功能实现

    这节来完成用户名渲染和注销的功能,目前用户名在前端页面是写死的,我们需要动态的展示出来 用户名渲染 实现用户名动态展示,其中一种方法就是在视图函数,根据session信息,获取到user id,通过该 ...

  2. (转) HA的几种方案

    数据库HA   一般把数据库层面的HA,和应用层面HA分开考虑 数据库一般采用数据库产品提供的HA方案,比如Oracle的RAC,mysql的集群,mongodb的replica set等 无HA的运 ...

  3. 【Leetcode】264. Ugly Number II ,丑数

    原题 Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime facto ...

  4. 【kubernetes】ubuntu14.04 64位 搭建kubernetes过程

    背景: Kubernetes介绍:http://kubernetes.io/docs/getting-started-guides/ github地址:https://github.com/kuber ...

  5. 挑战python 之一马当先(python的广搜)

    下过象棋的人都知道,马只能走'日'字形(包括旋转90°的日),现在想象一下,给你一个n行m列网格棋盘, 棋盘的左下角有一匹马,请你计算至少需要几步可以将它移动到棋盘的右上角,若无法走到,则输出-1. ...

  6. BZOJ 4443 [Scoi2015]小凸玩矩阵(二分答案+二分图匹配)

    [题目链接]http://www.lydsy.com/JudgeOnline/problem.php?id=4443 [题目大意] 从矩阵中选出N个数,其中任意两个数字不能在同一行或同一列 求选出来的 ...

  7. 【构造】Ural Championship April 30, 2017 Problem K. King’s island

    题意:让你构造一个n个点的简单多边形,使得所有点是整点,并且所有边长是整数,并且没有边平行于坐标轴. 就利用勾股数,如下图这样构造即可,n为偶数时,只需矩形拼成,n为奇数时,封上虚线边即可. #inc ...

  8. java面试笔试总结(一)--亲生经历的面试题

    说明:本文只是自己的一些心得体会,答案也是自己写的,正确与否,还需考证 java笔试题    1java笔试题1 启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7 ...

  9. 2016.4.3NOI上较难的动规题目(仔细分析样例)--王老师讲课整理

    1.NOI 191:钉子和小球 总时间限制: 1000ms 内存限制:  65536kB 描述 有一个三角形木板,竖直立放,上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1).每 ...

  10. Matlab读取音频数据

    项目需要,读出识别的车牌,对着图片看看是否识别正确. 有了0到9和A到Z,32个省份的音频,但是如何用matlab读出来,老版本有wavread直接读出,然后waveplay读入的即可.但是现在的是a ...