c语言中函数参数处理顺序

下面我们来看2个案例,分析下c语言中函数参数处理顺序。

第一个:

#include "stdio.h"void fn(int a,int b,int c){printf("%d,%d,%d", a, b, c);}void main(){int a = 3;fn(a++, a++, a++);}

输出结果:

5,4,3

原因分析:

C函数参数作为一个整体执行的顺序是从右向左,所以会先处理最右端的参数,然后依次向左处理。所以结果为最右端的a++先被处理结果为3,然后++,接着4和5,这样就有了上面的结果。

第二个:

 #includeint main(void){int i = 0;printf("%d,%d,%d,%d,%d\n", ++i, ++i, i++, ++i, i++);}

输出结果:

5,5,2,5,0

原因分析:

和上面的一样,执行的顺序是从右向左,所以会先处理最右端的参数,然后依次向左处理。不同是出现了++i,对于i++和++i是先加与后加的区别,但是在参数处理上则对应。如果是i++那么表示符合从右向左处理的前提下,当即处理该参数。如果是++i,那么表示只是执行++i运算并不将结果作为参数结果,将参数位置压入堆栈,只有当所有参数从右向左处理完毕之后,从堆栈弹出所有因为延后操作语句而没有填入最终结果的参数位置,将最终执行的结果i,作为相应的参数值,填入进去。

现在大家回忆下,逗号运算符,逗号运算的结合性是从左至右,完毕之后整个表达式的值是最后一个表达式的值。

例子:

int a[2],x=2,y=5;

a[0]=(x+3,y++,x++);

那么最终结果是:

a[0]=2 x=3 y=6;

从上面分析可以看出,函数参数和逗号运算符的执行顺序正好相反!

注意:

但是这两个的执行顺序是不确定的。如果函数参数是普通的表达式那么他们的执行顺序是不确定的。这就是为什么我们要避免写 printf("%d%d",++i,i++);这样的垃圾代码了。
并且C++标准是没有规定的,参数压栈顺序取决于编译器的,看你用什么编译器,貌似VC同GCC的压栈顺序就是相反的,最好在外面算好了再作为参数传递

C语言函数参数默认原则

#include <iostream>int print(int a = 1, int b = 2); int main() {print();print(-1);return 0;
}//int print(int a = 1, int b = 2) {// 编译错
int print(int a, int b) {std::cout << a << "," << b << std::endl;
}

结果:

1,2
-1,2

首先看上述的代码,print函数是带有默认参数的。

所以调用print(), print(-1)都可以准确的输出。

这种默认参数的情况会带来有些便利。(比如初始化一个商品对象,在99%的情况在都是正常的,那么这个商品是否正常的标记就可以默认为1,特殊的1%情况,再加上)

但是有以下三个要注意的情况。

  1. 默认参数只能放在函数声明处或者定义处,能放在声明处就放在声明处 。
    上述代码把那行注释打开,默认参数在声明和定义处都有了,那么就会有编译错误。(两次默认赋值是不被允许的。)

  2. 大部分情况,别人调用你的代码只能看到函数声明,如果你写在定义处,别人根本不知道你的默认参数是什么。

  3. 如果你是在定义处写的默认参数,那么你在使用该函数前就需要把函数定义放在前面。不然编译阶段通过无默认参数的函数声明无法确定这个函数是带默认参数的。

所以,默认参数写在声明处啊。^ ^

2.如果某个参数是默认参数,那么它后面的参数必须都是默认参数

因为非默认参数的参数必须要给出具体值,而调用函数传递参数的时候是从左到右的,所以非默认参数前面的都必须要传值进来。
那么默认参数后面的当然也得都为默认参数。

3.不要重载一个带默认参数的函数

看下这个函数:

class Test
{
public:int func(int a){return a;}int func(int a, int b = 1){return a + b;}
} ;

你调用func(1)的时候,谁知道你想调用哪一个。
更多C++相关知识体系,请移步C++知识目录。

c语言中函数参数处理顺序以及默认参数原则相关推荐

  1. c语言中函数参数为空是什么意思,C语言函数参数为空和void

    C语言中函数参数的为空和用void标注他们的效果一样吗? #include 2 //int add(); 3 int add(void); 4 int main(void) 5 { 6     int ...

  2. python默认参数只被解释一次_深入讲解Python函数中参数的使用及默认参数的陷阱...

    C++里函数可以设置缺省参数,Java不可以,只能通过重载的方式来实现,python里也可以设置默认参数,最大的好处就是降低函数难度,函数的定义只有一个,并且python是动态语言,在同一名称空间里不 ...

  3. python函数设置默认参数_深入讲解Python函数中参数的使用及默认参数的陷阱

    这篇文章主要介绍了Python函数中参数的使用及默认参数的陷阱,文中将函数的参数分为必选参数.默认参数.可变参数和关键字参数来讲,要的朋友可以参考下 C++里函数可以设置缺省参数,Java不可以,只能 ...

  4. 在c语言中 函数的作用是什么,C语言程序中函数的定义

    C语言程序中函数的定义 C语言的函数问题是困扰很多学者的问题的,c程序中什么是函数呢?下面啦小编为大家精心推荐的c程序中函数的定义,希望能够对您有所帮助. C语言读书笔记--函数 先来看看函数的一般形 ...

  5. c语言中函数的介绍(血书20000字!!!!)

    文章目录 函数 一:函数是什么? 二:C语言中函数的分类 1:库函数 (1):库函数存在的意义: (2):库函数的学习与使用 2:自定义函数 (1):自定义函数的组成 (2):例题 例题一:写一个函数 ...

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

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

  7. 决定c++语言中函数的返回值类型的是,全国2009年10月高等教育自学考试C++程序设计试题及部分参考答案...

    全国2009年10月高等教育自学考试 C++程序设计试题 课程代码:04737 一.单项选择题(本大题共20小题,每小题1分,共20分) 在每小题列出的四个备选项中只有一个是符合题目要求的,请将其代码 ...

  8. C语言函数为什么不可以声明默认参数?

    为什么C语言函数声明不可以带有默认参数? 我们都知道C++可以在.h文件函数声明中添加默认参数. 比如 void err_exit(int, const char *, ...) __attribut ...

  9. C语言中函数参数传递的方式:值传递,地址传递

    ** C语言中函数参数传递的方式:值传递,地址传递 ** 值传递:将实参的值复制至形参的相应存储单元中,实参与形参占用不同存储单元,单向传递 地址传递:使用数组名或者指针作为函数参数,传递的是该数组的 ...

最新文章

  1. 数据结构与算法:16 Leetcode同步练习(六)
  2. c#_Func和Action委托简介
  3. 我司用了 6 年的 Redis 分布式限流器,很牛逼了!
  4. 重磅,Kubernetes 决定弃用 Docker!
  5. python引用传递_python 是值传递还是引用传递 知乎
  6. maven3.6.3 配置环境变量_JDK1.8简单配置环境变量---两步曲
  7. 华为服务器虚拟化断电,服务器断电日志查看
  8. jpa使用注解传递对象_注解(下)
  9. どんな時、自分が幸福だと思いますか?
  10. [转载] python函数分为哪几种_python常用函数
  11. 查看linux中某个端口(port)是否被占用***
  12. WebGIS项目中利用mysql控制点库进行千万条数据坐标转换时的分表分区优化方案...
  13. Dijkstra(堆优)模板
  14. Linux下PHP开发环境搭建(Apache2.4+PHP7.1+MySQL8.0)
  15. 学习笔记12--智能驾驶安全设计案例
  16. windows 大容量存储设备驱动异常(代码:39)U盘由于驱动问题无法用的解决方法
  17. Excerpt-16 March, 2019
  18. 有功、无功、视在功率及功率因素
  19. Python菜鸟小萌新对正则表达式的理解
  20. 前端性能优化学习 08 资源加载优化

热门文章

  1. 微信公众号开发的一些方法总结
  2. 非ipad/安卓协议的微信开发sdk接口
  3. 删除word新建的时候存在的横线
  4. Intellij IDEA 安装使用Jrebel热部署详解
  5. UI设计指南之可视化大屏【快速理解版】
  6. 动环监控4大优势,你知道几个?
  7. 51CTO博客接龙:闲话网名之tom_c
  8. init container
  9. 2022智源大会|燧原科技创始人张亚林:云计算基础设施的“系统化”
  10. 使用navicat创建mysql数据库