如果把函数比喻成一台机器,那么参数就是原材料,返回值就是最终产品;从一定程度上讲,函数的作用就是根据不同的参数产生不同的返回值。

这一节我们先来讲解C语言函数的参数,下一节再讲解C语言函数的返回值。

C语言函数的参数会出现在两个地方,分别是函数定义处和函数调用处,这两个地方的参数是有区别的。

形参(形式参数)

在函数定义中出现的参数可以看做是一个占位符,它没有数据,只能等到函数被调用时接收传递进来的数据,所以称为形式参数,简称形参

  这里按自己的理解为什么说形参看作一个占位符,后文还说到在调用之前并没有给他分配内存,看上去这两段是有些矛盾的,其实机器在时间上的运行顺序这么说没毛病;

  本人理解是在程序编译过程中,程序计数器不断加以程序顺序执行,执行到调用函数位置时,会将之前的数据压栈就像中断一样,调用前要传递实参值对应的内存位置并没有开辟,所以可以说形参再调用前不占内存;

  但是这里没有开辟不是说实参会传到随机的位置,这是不会发生的,程序在编译好之后,每执行一条指令,数据都会有个确切的内存位置对应(这是在编译器编译的时候就已经确定好的),所以这么说来,形参确实是一个占位符(占有一个内存地址的位置);

  只是调用前别的参数也可以占用这个位置,但编译器编译的时候肯定不会让一个全局变量的内存地址和分配给形参的内存地址是同一个地址,原因大家应该通过上面的解释也明白编译器在编译时不会让两个没有关联的变量,同时服务于一个地址这样会造成数据的混乱。

  就像两个服务员负责同一桌客人时,当客人需要一瓶饮料时,两个服务员分别在不同时刻听到,可能就会造成给客人拿两瓶情况。

实参(实际参数)

函数被调用时给出的参数包含了实实在在的数据,会被函数内部的代码使用,所以称为实际参数,简称实参

形参和实参的功能是传递数据,发生函数调用时,实参的值会传递给形参。

形参和实参的区别和联系

1) 形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

2) 实参可以是常量、变量、表达式、函数等,无论实参是何种类型的数据,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参,所以应该提前用赋值、输入等办法使实参获得确定值。

3) 实参和形参在数量上、类型上、顺序上必须严格一致,否则会发生“类型不匹配”的错误。当然,如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型。

4) 函数调用中发生的数据传递是单向的,只能把实参的值传递给形参,而不能把形参的值反向地传递给实参;换句话说,一旦完成数据的传递,实参和形参就再也没有瓜葛了,所以,在函数调用过程中,形参的值发生改变并不会影响实参。

请看下面的例子:

 1 #include <stdio.h>
2 //计算从m加到n的值
3 int sum(int m, int n)
4 {
5 int i;
6 for (i = m+1; i <= n; ++i)
7 {
8 m += i;
9 }
10 return m;
11 }
12 int main()
13 {
14 int a, b, total;
15 printf("Input two numbers: ");
16 scanf("%d %d", &a, &b);
17 total = sum(a, b);
18 printf("a=%d, b=%d\n", a, b);
19 printf("total=%d\n", total);
20 return 0;
21 }

运行结果:
Input two numbers: 1 100
a=1, b=100
total=5050

在这段代码中,函数定义处的 m、n 是形参,函数调用处的 a、b 是实参。通过 scanf() 可以读取用户输入的数据,并赋值给 a、b,在调用 sum() 函数时,这份数据会传递给形参 m、n。

从运行情况看,输入 a 值为 1,即实参 a 的值为 1,把这个值传递给函数 sum() 后,形参 m 的初始值也为 1,在函数执行过程中,形参 m 的值变为 5050。函数运行结束后,输出实参 a 的值仍为 1,可见实参的值不会随形参的变化而变化。

以上调用 sum() 时是将变量作为函数实参,除此以外,你也可以将常量、表达式、函数返回值作为实参,如下所示:

  1. total = sum(10, 98); //将常量作为实参
  2. total = sum(a+10, b-3); //将表达式作为实参
  3. total = sum( pow(2,2), abs(-100) ); //将函数返回值作为实参

5) 形参和实参虽然可以同名,但它们之间是相互独立的,互不影响,因为实参在函数外部有效,而形参在函数内部有效。

更改上面的代码,让实参和形参同名:

 1 #include <stdio.h>
2 //计算从m加到n的值
3 int sum(int m, int n)
4 {
5 int i;
6 for (i = m + 1; i <= n; ++i)
7 {
8 m += i;
9 }
10 return m;
11 }
12 int main()
13 {
14 int m, n, total;
15 printf("Input two numbers: ");
16 scanf("%d %d", &m, &n);
17 total = sum(m, n);
18 printf("m=%d, n=%d\n", m, n);
19 printf("total=%d\n", total);
20 return 0;
21 }

运行结果:
Input two numbers: 1 100
m=1, n=100
total=5050

调用 sum() 函数后,函数内部的形参 m 的值已经发生了变化,而函数外部的实参 m 的值依然保持不变,可见它们是相互独立的两个变量,除了传递参数的一瞬间,其它时候是没有瓜葛的。

C语言形参和实参的区别(非常详细)的更多相关文章

  1. C语言形参跟实参详解

    形参与实参今天我们来说下c语言形参与实参的区别,形参跟实参理解的话也很简单,但是好多同学关于这个知识点都是一知半解,没有真正的去透彻,一问都知道,但在真正引用的时候还会出现很多问题,而百度的时候又会说 ...

  2. 嵌入式-C语言基础:理解形参和实参的区别

    #include<stdio.h> //实参:函数原型中声明函数后面带的参数 int test(int x)//函数原型 { //函数体 printf("test里面的x地址=% ...

  3. java的形参与实参的区别以及java的方法

    package com.lv.study; public class Demo05 { public static void main(String[] args) { //我想要用什么分隔符进行分隔 ...

  4. js函数形参和实参的区别

    在<Javascript权威指南>中这样定义: 参数有形参(parameter)和实参(argument)的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数. 说明白 ...

  5. 形参与实参的区别---java基础

    1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元.因此,形参只在函数内部有效.函数调用结束返回主调用函数后则不能再使用该形参变量.2.实参可以是常量.变量.表达式.函数 ...

  6. Java中的形参和实参的区别以及传值调用和传引用调用

    名词解析: 1.形参:用来接收调用该方法时传递的参数.只有在被调用的时候才分配内存空间,一旦调用结束,就释放内存空间.因此仅仅在方法内有效. 2.实参:传递给被调用方法的值,预先创建并赋予确定值. 3 ...

  7. JavaScript中函数的形参和实参的实现原理剖析

    我们都知道JS里面参数的传递是可以不一样的,比如我们有一个函数: <script type="text/javascript"> function one(a,b,c) ...

  8. js 形参和实参---2017-04-11

    一.定义 1.实参(argument):     全称为"实际参数"是在调用时传递给函数的参数. 实参可以是常量.变量.表达式.函数等, 无论实参是何种类型的量,在进行函数调用时, ...

  9. 深入理解java的形参和实参

    转载声明:本文转载自公众号「码匠笔记」. 前几天在头条上看到一道经典面试题,引发了一些思考.也是写这篇文章的导火索. 背景 请看题: public    classMain{    publicsta ...

随机推荐

  1. 1.分类维护-通过Java8 Stream API 获取商品三级分类数据

    实体类 @Data @TableName("pms_category") public class CategoryEntity implements Serializable { ...

  2. 实用TCP协议(1):TCP 协议简介

    传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议.TCP 协议假设下层协议可以提供简单的不可靠数据报, 并在此基础 ...

  3. k8s全方位监控-prometheus-alertmanager部署-配置第一条告警邮件

    1.alertmanager告警插件部署 [root@VM_0_48_centos prometheus]# cat alertmanager-pvc.yaml apiVersion: v1 kind ...

  4. laravel html转pdf

    这两天项目中需要将HTML页面转换为PDF文件方便打印,我在网上搜了很多资料.先后尝试了laravel-dompdf和laravel-snappy两种扩展包,个人感觉laravel-snappy比较好 ...

  5. xshell + xftp 安装及1603错误解决

    xshell + xftpan下载安装 百度网盘下载链接:https://pan.baidu.com/s/14orvEWDjFkrLvr_9JaG4Gw 提取码:om9z 下载地址 https://w ...

  6. 自己的markdown笔记

    markdown一些语法 记录自己会用的一些markdown语法,不定期更新,用的软件是hroopad,hroopad下载地址点击跳转.这个书写软件对新手还有中文用户比较友好,左边是markdown语 ...

  7. JavaSE 千寻简学习笔记

    JavaSE 千寻简学习笔记 简介 TIOBE:编程语言排行榜 官网:https://hellogithub.com/report/tiobe/ 如何高效的学习Java 多写(代码)多写(笔记)多写( ...

  8. c++ set与unordered set的区别

    c++ std中set与unordered_set区别和map与unordered_map区别类似,其底层的数据结构说明如下: 1.set基于红黑树实现,红黑树具有自动排序的功能,因此map内部所有的 ...

  9. 常用命令行指令 Windows & Linux

    一.Linux linux常用命令详解:https://www.cnblogs.com/yuncong/p/10247583.html 挂载U盘到linux一个文件夹中 二.Windows 1.查看电 ...

  10. 装饰器property的简单运用

    property函数:在类中使用,将类中的方法伪装成一个属性 使用方法:在函数,方法,类的上面一行直接@装饰器的名字 装饰器的分类: 装饰器函数 装饰器方法:property 装饰类 class St ...