函数
一、函数的概念
- 函数是一个完成特定工作且包装起来的独立程序模块。函数的种类包括库函数和自创函数。
- 库函数包括scanf(),printf()函数等。这两个函数包含在stdio.h函数库内。
- 自创函数即为自己根据题目要求来设计的函数,然后对函数进行封装,使用时直接调用即可。我们主要学习自创函数的结构与用法。
二、自创函数的定义及其应用
1.自定义函数定义的一般形式为:
函数类型 函数名称(形式参数) \\函数首部\\
{
函数实现过程 \\函数体\\
return (需要返回的值);
}
- 函数类型可以是c语言中的任意数据类型,例如double、char、int 等。
- 函数名是标识符的一种,命名规则与标识符相同。函数名后面的()不能少。
- 函数实现过程就是函数需要执行的代码,是函数的主题,同时也需要由{}包围。
- 如果有返回值,则在函数体中通过return语句返回。且返回值要与你所定义的函数的类型一致。
例如需要计算从1!+2!+3!+…+n!
本题目若是不使用函数的方法,则很简单,但是如果需要在一个程序内计算两个不同数值的乘阶之和,则需要输入两次for循环用于分别计算这两个数的乘阶之后,最后再使用一个变量进行储存,最后相加才能得出结果。
若使用函数的方法,则可以设计一个函数计算乘阶,最后再引用该函数进行计算。然后再引用该函数进行计算。
函数:
int fact(int n)
{
int a=1;
for(int i=1;i<=n;i++)
{
a=a*i;
}
return a;
}
最后结果保存在变量a中,最后通过return语句返回。a是 int 型,返回值也是 int 类型,它们一 一对应。
return是C语言中的一个关键字,只能用在函数中,用来返回处理结果。
此函数用于计算n的乘阶,这就是一个自创函数。但是并不能直接用,而是还需要在主函数中进行引用。
当然函数也会有没有返回值的函数,于int或其他数据类型函数不同的是,这类函数的前缀是viod,即为无返回类型。
函数:
void fact(int n)
{
int a=1;
for(int i;i<=n;i++)
a=a*i;
}
}
void是c语言的一个关键字,表示空类型或无类型,绝大部分情况下也就没有返回值。
三、如何调用自创的函数
1.当自创函数与主函数位于同一个cpp文件,且自创函数位于主函数之后,则需要声明函数,声明形式与声明变量一致。
#include <stdio.h>
int sum(int n); //调用函数//
int main()
{
intc x,y;
scanf("%d %d",&x,&y);
int result1=sum(x); //当n=x时的阶乘//
int result2=sum(y); //当n=y时的阶乘//
int result3=result1+result2;
printf("%d",result3);
}
int sum(int n){ //函数部分//
int i,a=1;
for(i=1; i<=n; i++){
a=a*i;
}
return a;
}
2.当自创函数与主函数在同一个cpp文件,且自创函数位于主函数之前,则不需要声明函数。
#include <stdio.h>
int sum(int n){
int i,a=1;
for(i=1; i<=n; i++){
a=a*i;
}
return a;
}
int main()
{
int x,y;
scanf("%d %d",&x,&y);
int result1=sum(x); //当n=x时的阶乘//
int result2=sum(y); //当n=y时的阶乘//
int result3=result1+result2;
printf("%d",result3);
}
3.当自创函数与主函数不在一个cpp文件时,则需要将两个函数位于同一个文件夹内使用#include"函数名.cpp"声明自定义函数。函数名与cpp上的格式一致。
#include <stdio.h>
#include "sum.cpp>
int sum(int n); //调用函数//
int main()
{
int x,y;
scanf("%d %d",&x,&y);
int result1=sum(x); //当n=x时的阶乘//
int result2=sum(y); //当n=y时的阶乘//
int result3=result1+result2;
printf("%d",result3);
}
既然自创函数又没有返回类型的类型,则也可以引用以void为类型的函数。
- 例如求1!+2!+3!+…+n!
函数:
#include <stdio.h>
void sum(int n); //调用函数//
int main()
{
int x;
scanf("%d",&x);
sum(x);
}
void sum(int n){ //函数部分//
int i,a=1;
for(i=1; i<=n; i++){
a=i*a;
}
printf("%d",a);
}
当函数没有返回类型时,就无发使用return返回a的值,所以需要在自创函数中实现接下来需要做的事情
,而此时sum函数里已经包含值,所以直接再函数中使用sum就可以得出值。一旦函数的返回值类型被定义为 void,就不能再接收它的值了。所以直接使用该函数即可。
##四.实际参数和形式参数,全局变量和局部变量。
###一.实际参数和形式参数
1.形式参数就是在定义函数或过程的时候命名的参数。通俗讲就是一个记号。实际参数就是在执行时,调用函数或过程时,传递给函数或过程的参数。通俗讲就是实际值。参数就是一个可变量,它随着使用者的不同而发生变化。
例如:
在中学的时候学过sin(x)函数,这里的x就是形式参数,当你需要求1的正弦值时,你会使用sin(1),这里的1就是实际参数。4 形参和实参间的关系:两者是在调用的时候进行结合的,通常实参会将取值传递给形参,形参去之后进行函数过程运算,然后可能将某些值经过参数或函数符号返回给调用者。
#include <stdio.h>
int sum(int n){ //这里的int n就是形式参数//
int i,a=1;
for(i=1; i<=n; i++){
a=a*i;
}
return a;
}
int main()
{
int x,y;
scanf("%d %d",&x,&y);
int result1=sum(x); //当n=x时的阶乘// //这里的x就是实际参数//
int result2=sum(y); //当n=y时的阶乘//
int result3=result1+result2;
printf("%d",result3);
}
二.局部变量和全局变量
1.局部变量
定义在函数内部的变量称为局部变量,它的作用域仅限于函数内部, 离开该函数后就是无效的。
int f1(int a){
int b,c; //a,b,c仅在函数f1()内有效
return a+b+c;
}
int main(){
int m,n; //m,n仅在函数main()内有效
return 0;
}
- 注意几点:
-
- 在 main 函数中定义的变量也是局部变量,只能在 main 函数中使用;同时,main 函数中也不能使用其它函数中定义的变量。main 函数也是一个函数,与其它函数地位平等。
-
形参变量、在函数体内定义的变量都是局部变量。实参给形参传值的过程也就是给局部变量赋值的过程。
-
可以在不同的函数中使用相同的变量名,它们表示不同的数据,分配不同的内存,互不干扰,也不会发生混淆。
-
在语句块中也可定义变量,它的作用域只限于当前语句块。
2.全局变量
1.在所有函数外部定义的变量称为全局变量,它的作用域默认是整个程序,也就是所有的源文件,包括 .c 和 .h 文件。
int a, b; //全局变量
void func1(){
//TODO:
}
float x,y; //全局变量
int func2(){
//TODO:
}
int main(){
//TODO:
return 0;
}
- 注意几点:
a、b、x、y 都是在函数外部定义的全局变量。C语言代码是从前往后依次执行的,由于 x、y 定义在函数 func1() 之后,所以在 func1() 内无效;而 a、b 定义在源程序的开头,所以在 func1()、func2() 和 main() 内都有效。
局部变量和全局变量的综合实例:
#include <stdio.h>
int n = 10; //全局变量
void func1(){
int n = 20; //局部变量
printf("func1 n: %d\n", n);
}
void func2(int n){
printf("func2 n: %d\n", n);
}
void func3(){
printf("func3 n: %d\n", n);
}
int main(){
int n = 30; //局部变量
func1();
func2(n);
func3();
//代码块由{}包围
{
int n = 40; //局部变量
printf("block n: %d\n", n);
}
printf("main n: %d\n", n);
return 0;
}
五.变量的储存类别
在c语言中变量有两种储存类别:自动类和静态类。
1.局部变量的存储类别:
(1)auto变量
int a;等价于auto int a;
auto变量的存储类别是动态的。一般我们很少在程序中显示申明变量为auto类型,因为代码块中的变量缺省情况下就是这种类型。
(2)static变量
用static声明的称为静态局部变量。此类型能作用于全局变量也可以应用于局部变量。静态局部变量的赋值是在编译时赋予的,在程序运行时已有初始值,以后每次函数调用时不再是重新赋值而是保留上次的函数调用结束的值。如果静态函数并未赋予初始值,则将会自动赋值0,而动态局部变量若为赋值时系统会自动赋予不确定的值。
例子:
动态局部变量:
#include <stdio.h>
void test()
{
int num = 0;
num++;
printf("%d ", num);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
输出结果为 1 1 1 1 1 1 1 1 1 1
因为动态变量在每次调用函数时都会重新赋值num为0,因为每次调用函数时num都等于0。
#include <stdio.h>
void test()
{
static int num = 0;
num++;
printf("%d ", num);
}
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
test();
}
return 0;
}
输出结果为1 2 3 4 5 6 7 8 9 10
因为静态变量每次函数调用时是重新赋值而是保留上次的函数调用结束的值,因此每次函数的值都为 上一次输出的值加一。
递归
1.什么是递归?
递归就是一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数。
简单的来说:递归就是一个函数自己直接或间接调用自己。
例如:
include <stdio.h>
void fact(int n);
int main()
{
fact(7);
return 0;
}
void fact(int n)
{
if(n==1){
printf("递归是我自己调用我自己\n");
}
else{
printf("%d\n",n);
fact(n-1);
}
}
运行结果为7 6 5 4 3 2 递归是我调用我自己
每次调用之后都会再次调用函数,直到n=1时结束本次程序。则就是递归最简单的概念和用法,即为我自己调用我自己。
主编:覃聪明
监制:满天星