C语言中函数和指针的參数传递
近期写二叉树的数据结构实验。想用一个没有返回值的函数来创建一个树,发现这个树就是建立不起来,那么我就用这个样例讨论一下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语言中函数和指针的參数传递的更多相关文章
- C语言中函数参数传递的本质是值传递
数组名做函数参数进行传递时,实际上是是一份该指针的拷贝. 给形参赋予其他值,并不影响实参的值. 类似于: int *p = a; //a为数组名 p = b; //b为数组名 ...
- C语言——指向函数的指针
转载自:http://www.cnblogs.com/liangyan19910818/archive/2011/08/19/2145270.html C语言——指向函数的指针 函数类型 (* 函数指 ...
- C语言中函数参数传递
C语言中函数参数传递的三种方式 (1)值传递,就是把你的变量的值传递给函数的形式参数,实际就是用变量的值来新生成一个形式参数,因而在函数里对形参的改变不会影响到函数外的变量的值.(2)地址传递,就是把 ...
- C语言中函数返回字符串的4中方法
C语言中函数返回字符串的4中方法 函数的构成部分:返回类型.函数名称.参数.函数主体 参数:函数调用时传入的参数称为实参,函数定义时出现的参数为形参 形参的作用在于接收实参传入的值,形参和函数内部的其 ...
- C语言中函数的调用方式
第一眼看到这样一个题目的我,心想除了如下的直接调用还能怎么调用呢? 1 void fun(void) 2 { 3 ...... 4 //你的代码 5 ..... 6 } 7 int main(void ...
- windev中的内存机制及其与C语言中的内存指针相似性(一)
windev中的内存机制,是初入windev世界必须要越过的一道高山,以下我的理解和经验未必都对,如有错误或遗漏,以后再纠正或补充!另外,以下内容,咱先谈应用,再说对机制的认识和理解. 一.新建表单, ...
- c语言中函数的简单介绍
c语言中函数的介绍: 函数,简单的说就是代码的打包.存放在一个地方,当需要的时候调用. 函数分类: 1.无参无返回值函数 void func() 2.无参有返回值函数 int func() 3.有参 ...
- c语言中函数参数入栈的顺序是什么?为什么
看到面试题C语言中函数参数的入栈顺序如何? 自己不知道,边上网找资料.下面是详细解释 #include <stdio.h> void foo(int x, int y, int z){ ...
- 指针数组,数组指针,函数指针,main函数实质,二重指针,函数指针作为參数,泛型函数
1.指针数组 数组里面的每一个元素都是指针. 指针数组的案比例如以下: 易犯错误: 2.数组指针 归根结底还是指针,仅仅是取*的时候可以取出一整个数组出来. 数组指针:(一个指针指向了数组.一般 ...
随机推荐
- Express使用MongoDB常用操作
const MongoClient = require('mongodb').MongoClient const url = "mongodb://localhost:27017" ...
- canvas 画椭圆
圆的标准方程(x-x0)²+(y-y0)²=r²中,有三个参数x0.y0.r,即圆心坐标为(x0, y0), 半径为 r圆的参数方程 x = x0 + r * cosθ, y = y0 + r * s ...
- luogu P1012 拼数
题目描述 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4时,4个整数7,13,4 ...
- 【莫比乌斯反演+容斥】BZOJ2301-[HAOI2011]Problem b(成为权限狗的第一题纪念!)
[题目大意] 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. [思路] “怎么又是你系列……”思路 ...
- python基础之if,while,for
流程控制之if判断 根据女性年龄不同的不同叫法,如: age = 24 if age < 18: print('小妹妹好') elif age <28: print('小姐姐好') els ...
- Error attempting to get column 'xxx' from result set. Cause: java.sql.SQLException: 无法转换为内部表示
因为<resultMap>中映射的实体类属性类型与数据库字段类型不一致造成的.
- struts2和spring整合错误 org.springframework.beans.factory.BeanCreationException,已解决
先贴上错误 2018-8-16 23:41:10 org.springframework.context.support.ClassPathXmlApplicationContext prepareR ...
- [转载]memcached 命令操作详解
转载:http://www.cnblogs.com/azheng007/p/3159345.html 一.存储命令 存储命令的格式: <command name> <key> ...
- jquery load 方法回显数据
使用jQuery对象.load()方法 load() 方法的作用是可以通过 AJAX 请求从服务器加载数据,并把返回的数据直接放置到指定的元素中. 该方法使用起来非常简单,大大简化了ajax开发 语法 ...
- ylbtech-LanguageSamples-NamedAndOptional(命名和可选参数)
ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-NamedAndOptional(命名和可选参数) 1.A,示例(Sample) 返回顶 ...