c++ main函数调用 类中的枚举_C开发实战-函数

函数概述

将编写的功能模块封装到一个容器中给其他模块调用,这个容器就是函数。
函数是C程序的基本模块,用于完成特定任务的代码单元。封装函数就能实现代码的重复利用,减少重复的代码块,让程序更加模块化,结构清晰,从而增强程序的可读性和降低后期维护成本。
而main函数作为C程序的入口函数,程序是从main函数开始执行的,其他的函数在main函数调用后才会执行,例如之前使用的printf()函数,puts()函数,fputs()函数,strlen()函数等等都是C语言提供的库函数,在日常开发中除了使用C语言提供的库函数完成一些通用的功能以外,开发者还需要针对业务功能开发对应的函数。

函数的定义

C语言函数的定义语法格式如下

返回类型  函数名(形式参数列表){数据定义部分;执行语句部分;}
  • 函数名:函数名命名最好见名知意,让开发者看到函数名就知道函数要实现的功能,函数名后面有个()代表为函数,而不是普通的变量名。
  • 形式参数列表:在定义函数时指定的形参,在未出现函数调用时,它们并不占用内存中的存储单元,因此称它们为形式参数或者虚拟参数,简称形参,表示它们并不是实际存在的数据,因此形参的变量不能被赋值。在定义函数时的形参是可选的,如果有形参则必须是数据类型加变量名的形式,多个形参使用逗号(,)隔开。如果没有形参,()中写void关键字或者不写。
//形式参数不能赋值,这里会编译错误int max(int left,int right =20){return left>right?left:right;}
  • 函数体:{}包含的内容就是函数体,即函数实现功能的过程。没有自定义函数之前代码都写在main函数中。而后期都是自定义函数,然后在main函数中调用自定义的函数,因为程序是从main函数开始执行,只有在main函数中调用自定义的函数,自定义的函数才会执行。
  • 返回类型 函数的返回值是通过函数的return语句,return后面的值可以是变量,也可以是一个表达式,但是要保证return语句中表达式的值和函数返回类型是同一数据类型,如果函数返回类型和return语句中表达式的值不一致,则以函数返回类型为准,即函数返回类型决定返回值的类型,对于数值类型的数据,函数可以进行自动类型转换。而如果返回类型为void表示函数不需要返回值。

函数在定义时需要在调用之前,因此通常将函数定义在main函数的上面,如果是程序只有一个C程序的源文件时,因为编译器是从上往下编译的。如果没有定义就使用,程序会出错。

8de778c9bac0c9e43a660b21f6332fb3.png

无参数无返回值的函数定义和调用

定义一个无参数,无返回值的函数,该函数主要是打印"inside hello method "换行,然后打印say hello 后换行。
需要注意的是定义函数时不能嵌套,例如不能将该函数定义在main函数的内部。

void hello() {printf("inside hello method");printf("hello function");return;}
  • void 表示函数没有返回值,return表示结束hello函数,因为返回类型是void ,因此return 后面不能跟常量、变量或者表达式。
  • hello表示函数名
  • ()表示该函数没有形参列表
  • {} 即函数体,表示函数完成的功能

如果想要该函数执行,必须在主函数中调用,调用无参数的函数只需要函数名加上()即可,例如hello();

/*    无返回值无参数的函数定义与调用不能在函数内部定义函数,必须在函数外部定义函数如果定义的函数没有形参,那么()可以写void,也可以什么都不写如果函数没有返回值,需要写void{}是函数体,函数实现的功能写在{}中函数结束之前需要有返回值返回值的类型看函数定义时所需要的类型函数的调用:函数名(形参列表);@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int main(int argc, char* argv[]){printf("inside main method...");//调用无返回值无参数的函数hello();system("pause");return 0;}

程序运行结果

38932e066dbf0006529096e3b4cc8af5.png

有参数无返回值的函数调用

定义一个返回类型为void(即没有返回值),函数名为sum,函数的形参是两个整数类型的变量,多个形参之间使用,隔开。该函数的功能是实现两个整数相加,并打印输出相加后的结果

/*有形式参数没有返回值的函数定义*/void sum( int left,int right) {int sum = left + right;//打印两个整数求和运算的结果printf("%d + %d = %d",left,right,sum);return;}

如果有需要完成两个整数相加的操作,就可以调用该函数

/*有形式参数没有返回值的函数的定义与调用函数定义时()的参数叫做形参,因为这个形参只是形式上的参数,定义函数时没有给函数开辟内存空间形参只有在被调用时才会开辟内存空间形参定义的格式为 类型名 变量名, 多个形参使用逗号(,)隔开@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int main(int argc, char* argv[]){printf("inside method...");//调用有形参没有返回值的函数//调用有形参函数时,必须传递对应的参数,此时的参数是实参,即会开辟内存空间//实参的类型和形参的类型保持一致,而且实参的顺序、个数和形参一致sum(10,20);//实参可以传递常量,也可以传递变量作为参数int left = 10;int right = 20;sum(left,right);//实参还可以传表达式sum(left+right,left*right);//即实参可以传常量,变量和表达式system("pause");return 0;}

当调用有形式参数的函数时,需要传递对应的参数,参数的顺序和数量以及数据类型需要一致。其中参数可以是常量,变量或者表达式。

程序运行结果

034fccf4c41262a98dbce6f742b23784.png

有返回值有参数的函数调用

定义一个返回值int类型,函数名为get_sum,参数为两个整数类型的函数,该函数的功能是完成两个整数的相加并返回,
函数的返回值类型(例如这里的int)和return的数据类型(例如这里的int)必须一致,返回值小于等于4个字节会存储在寄存器。大于4个字节会存储在内存中。

/*有参数,有返回值*/int  get_sum(int left,int right) {int sum = left + right;return sum;}

有返回值有参数的函数调用时除了传递实际参数外,还可以接受或者不接收函数的返回值,通常日常业务开发中如果下一个逻辑需要依赖上一个函数返回的结果时会接收函数的返回值。接收函数的返回值类型和函数的返回值类型必须一致。2而函数的参数传递只能是实际参数传递给形式参数,即单向传递。也可以直接调用函数,将函数的执行结果作为另外一个函数 的参数传递。

/*有参数,有返回值的定义和调用@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int main(int argc, char* argv[]){//有参有返回值的函数调用//调用有返回值的函数,可以不接收返回值get_sum(10,20);int x = 10;int y = 20;int result = 0;//也可以接收函数的返回值,因为返回的类型是int,所以接受返回值变量的类型也需要是intresult = get_sum(x,y);//函数的参数传递只能是实参传递给形参的单向传递,而且是传值(这里是传x,y的值)get_sum(x*y,x+y);//将get_sum函数的返回值作为printf()函数的参数printf("%d + %d = %d ",x,y,get_sum(x,y));system("pause");return 0;}

程序运行结果

34554469c46e5ba7274a9ace0701f73a.png

函数的执行流程

首先定义一个有返回值,有参数的函数GetSum来计算两个整数相加的和。

int  GetSum(int left, int right) {int sum = left + right;return sum;}

然后在main方法中调用该函数

/*函数的调用过程@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int main(int argc, char* argv[]){int x = 10;int y = 20;int result= GetSum(x,y);system("pause");return 0;}

程序运行时,会给每个函数分配独立的内存空间,即main()函数和GetSum()函数位于不同的内存空间,当main()函数被系统调用运行时,

int x=10;int y=20;

此时在main函数的内存空间中开辟8个字节存储2个整数变量并分别赋值为10和20
然后执行到int result= GetSum(x,y); 此时会进入到GetSum()函数内部,并给GetSum函数所在的内存空间开辟8个字节来存储left和right变量,并将实际参数x和y的值赋值给GetSum()函数的形式参数left,right,此时left=10;right=20;

然后执行int sum =left+right,即执行left+right并将相加的结果赋值给sum
然后执行return sum; ,由于sum的值小于4个字节,此时会将计算结果存储在寄存器中,如果是大于4个字节会直接存储在内存中。此时GetSum执行完成。

程序接着回到主函数,由于主函数中定义了result变量来接收GetSum函数的返回值,系统会在main函数的内存空间开辟四个字节的空间,并将寄存器中存储GetSum()函数的返回结果的值赋值给result变量。
到此整个程序就执行完成了。

需要注意的是实参传递给形参时传递的是变量的值,而不会把变量的空间传递给形参

在程序中定义一个交换两个整数变量的方法,其中形参的值由调用函数时的实参传递进来。

#define _CRT_SECURE_NO_WARNINGS#include #include /*函数的参数传递机制:传值如果实参是传变量本身给形参,只会是值传递给形参,不会把变量本身的空间传给形参@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*//*实现两个整数的交换*/void swap(int left,int right) {printf("开始执行swap()方法");//交换两个形参变量的值int tmp = left;left = right;right = tmp;//这里只会改变形参left和right的值printf("swap()执行完成之后形参:left = %d right = %d ", left, right);printf("结束执行swap()方法");}int main(int argc, char* argv[]){int x = 10;int y = 20;printf("swap()方法调用之前实参: x = %d y = %d ",x,y);//x,y的值没有交换,因为传参时实参传递给形参,形参的值改变不会改变实参的值swap(x,y);printf("swap()方法调用之后实参: x = %d y = %d ", x, y);system("pause");return 0;}

在swap()方法调用前后,实参x,y的值都没有发生改变,因为传递实参给形参,形参不会改变实参的值。
程序运行结果

eecc72239527414680b1437ebf448c90.png

return和exit()方法的区别

return 表示结束当前函数,return在非main函数中调用结束当前函数,如果return在main函数中会结束整个程序。
而exit()函数是C语言提供的库函数,用于结束当前程序,无论在main函数还是非main函数中调用。

#define _CRT_SECURE_NO_WARNINGS#include #include /*return和exit的区别return结束当前的函数return在非main函数中调用结束当前函数如果return在main函数中会结束整个程序exit是一个库函数,用来结束整个程序,不管exit在哪调用都是结束整个程序exit(0);@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int mul(int left,int right) {//退出程序exit(0);return left * right;}int main(int argc, char* argv[]){//退出程序int result = mul(10,20);//因为mul()函数中调用了exit()函数,因此不会打印result变量的值printf("result = %d ",result);system("pause");//表示结束main函数(即整个程序都结束),返回0给系统return 0;}

程序运行结果

7fb41a2b9197ce485e4f6bc4e197a238.png

C语言多文件编程

函数的声明

函数的声明表示该函数已经在其他地方定义,调用函数时通过编译。函数声明时没有函数体,函数声明结束时需要使用;表示结束
函数声明的语法格式为 返回类型 函数名(形参列表);,例如extern int add(int left,int right);,其中extern关键字表示声明函数,也可以省略不写,甚至声明函数时形参列表的变量名也可以不写,例如int mul(int,int);。

如果是一个源文件,除了在调用函数前定义函数外,也可以在调用之前先声明函数,然后再实现声明的函数。

#define _CRT_SECURE_NO_WARNINGS#include #include /*函数的声明VS函数的定义1.函数的定义 有函数体没有分号2.函数的声明没有函数体,有分号@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*///函数的声明要放在调用之前,使用;表示结束函数的声明//函数的声明没有函数体//extern表示声明变量或者函数,通常省略不写//函数的声明表示该函数已经在其他地方定义,调用函数时通过编译//函数声明时,形参的变量名可以省略extern int add(int left,int right);int mul(int,int);int main(int argc, char* argv[]){//声明放在调用之前printf("%d ", add(10, 20));system("pause");return 0;}/*函数的定义*/int add(int left,int right) {return left + right;}

C语言多文件编程

函数实现了程序的模块化,而多文件也是为了大型复杂程序的模块化。不同的文件可以封装不同的函数功能。

在C语言多文件编程中,我们把函数的声明封装在头文件中,例如my_math.h头文件中包含了获取两个数的最大值和两个数组的最小值两个函数。
为了防止头文件被重复包含,使用了#ifndef 和#endif。

//头文件中只声明函数,定义放在同名的my_math.c源文件中//Windows 函数名采用驼峰命名法,单词首字母大写,后面字母小写,例如MyMax//Linux 函数名单词所有字母都小写,多个单词使用下划线隔开,例如my_max//因为在Windows下编程,因此采用Windows的命名风格// ifndef endif 为了解决头文件的重复包含#ifndef _MY_MATH_H_ //如果没有定义宏MY_MATH_H#define _MY_MATH_H_ //定义宏MY_MATH_Hint MyMax(int, int);int MyMin(int, int);#endif // !MY_MATH_H

然后将函数的实现放在源文件my_math.c中,建议函数声明的头文件和函数实现的源文件文件名相同。

int MyMax(int left,int right) {return left > right ? left : right;}int MyMin(int left,int right) {return left < right ? left : right;}

程序的入口源文件通常叫main.c,在main.c中如果需要调用MyMax()和MyMin这两个函数,首先需要使用#include "my_math.h"包含头文件,即函数所声明的文件。包含系统路径下的头文件使用<>,包含项目路径下的头文件使用""。

此时的项目结构

0869dca022a8dbc2cfa221c6b100e5be.png

然后就可以在程序中使用这两个函数了

#define _CRT_SECURE_NO_WARNINGS#include #include //包含当前路径下的my_math.h头文件  当前项目路径头文件使用"" 而系统路径下的头文件使用<>#include "my_math.h"/*多文件编程@author liuguanglei 18601767221@163.com@wechat 18601767221@website ittimeline.net@version 2020/11/24*/int main(int argc, char* argv[]){int left = 10;int right = 20;//求最大值int max=MyMax(left,right);printf("%d和%d的最大值是%d",left,right,max);//求最小值int min = MyMin(left, right);printf("%d和%d的最小值是%d", left, right, min);system("pause");return 0;}

程序的运行结果

7c5769c24813d87ad9e84e37d35c2de7.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值