电商业专科学园业学习嵌入式软件开垦第六二十日澳门唯一金莎娱乐,C语言函数

电商业专科学园业学习嵌入式软件开垦第六二十日澳门唯一金莎娱乐,C语言函数

第5章 函数

 

第5章
函数
1.
函数
2.
变量的成效域
1.
局部变量
2.
全局变量
3.
变量的存款和储蓄情势
小结

 

  • ###### C根底第三日

1. 函数

  1. 从函数定义的角度看,函数可分为库函数和客商自定义函数两种
    1)
    库函数:由C系统提供,只需在程序前富含有该函数原型的头文件就可以在前后相继中平昔调用
    2)
    用户自定义函数:由客商按要求写的函数,不仅仅在程序中定义函数本人,并且在主调函数模块中还非得对该被调用函数进行项目说明,然后采用
  2. 从函数兼有其它语言中的函数和进程的七个职能,又可分为有再次来到值函数和无重临值函数
    1)
    有重返值函数:此类函数被调用实施完后将向调用者重返一个施行结果,称为函数再次来到值;由顾客定义的这种要回来值得函数,必需在函数定义和函数表达中一清二楚再次回到值的连串
    2)
    无重返函数:此类函数在完毕一定的管理职责,施行到位后不向调用者重返函数值。由于函数无须重回值,顾客定义此类函数时可钦命他的回来为”空类型(void)”
  3. 从主调函数和被调函数之间数据传送的角度可分为无参函数和有参函数
    1)
    无参函数:函数定义、函数表明及函数调用中均不带参数。主调函数和被调函数之间不进行参数字传送送。能够回来或不回去函数值
    2)
    有参函数:在函数定义及函数表明时都有参数,称为格局参数(形参卡塔 尔(英语:State of Qatar)。在函数调用时也亟须交给参数,称为实际参数(实参)。进行函数调用时,主调函数将把实参的值传送给形参,供被函数使用
  4. 函数定义的相仿方式
    1) 无参函数的貌似情势

<wiz_code_mirror>

 

 

 

 

 

1 类型说明符 函数名(){
2     类型说明
3     语句
4 }

 

 

 

其间类型表达符和函数名叫函数头
类型表达符指明了本函数的系列,函数的种类实际上是函数重返值的类型。函数名是由顾客定义的标志符,函数名后有一个空括号,当中无参数,但括号不可少。{}
中的内容称为函数体。在函数体中也许有项目表明,
那是对函数体内部所用到的变量的门类表明。在重重场馆下都无需无参函数有重回值void
2) 有参函数的相通形式

<wiz_code_mirror>

 

 

 

 

 

1 类型说明符 函数名(形式参数表)
2     形式参数类型说明
3     {
4     类型说明
5     语句
6     }

 

 

 

其一是花样参数表
其二是款式参数类型表明。在形参表中提交的参数称为花样参数
它们得以是各个类型的变量,必需给以连串表明,
各参数之间用逗号间隔。在张开函数调用时,主调函数将授予这几个样式参数其实的值

  1. 函数的参数:分为形参和实参;形参出以后函数定义中,在漫天函数体内都能够应用,
    离开该函数则不能接纳
    。实参出今后主调函数中,步向被调函数后,实参变量也不能够采纳,作用是作多少传送。发生函数调用时,
    主调函数把实参的值传送给被调函数的形参进而落实主调函数向被调函数的多少传送
    函数的形参和实参的特征
    1)
    形参变量独有在被调用时才分配内部存款和储蓄器单元,调用停止后,登时释放所分配的内部存款和储蓄器单元。形参独有在函数内部有效,函数提哦啊用结束重返主调函数后则无法再选用该形参变量
    2)
    实参能够是常量、变量、表达式、函数等,在扩充函数调用时,都必得具备鲜明的值,以便把那一个值送给形参
    3)
    实参和形参在数量上、类型上、顺序上应严酷平等,不然会产生“类型不合营”的谬误
    4)
    函数调用中产生的数量传送是单向的,即只好把实参的值传送给形参。由此在函数调用时,形参的值产生改动,而实参中的值不会转移
  2. 函数的值:指函数被调用后,施行函数体中的程序段所得到的并赶回给主调函数的值,(或称函数再次来到值)对函数的值的证实:
    1) 函数的值只可以用过 “return 表明式”
    语句再次来到主调函数
    ,该语句的功效是计量表达式的值,并回到给主调函数,
    2)
    函数值的品类和函数定义中等学校函授数的品类应保持生机勃勃致,如若双方不相近,则以函数类型为准,自动进行类型转变
    3) 如函数值为整型,在函数定义时得以节约类型表明
    4) 不再次来到函数值的函数,能够料定定义为空类型 (void)
  3. 被调函数
    无参函数平时方式: 品类表明符 被调函数名()
    有参函数日常方式: 连串表明符 被调函数名(类型 形参, 类型
    形参···)
  4. 函数的递归使用:多个函数在它的函数体内调用它本身名字为递归调用,为了以防递归调用无终止举办,加条件判定

不久前讲的是函数,几日前早先讲指针。现在出以后速记中的代码都是本身写不出去的,看了一下这两日的代码量,以为非常发烧,背下来都有难度。

2. 变量的成效域

//static静态局部变量
#include <stdio.h>
int fun(int a)
{
//  const int b = 2;//const代表不能修改后面的值
    static int b = 2;//static会保留上一次的值
    b++;
    return a+b;
}
int main(int argc,char *argv[])
{   
    int i;
    for(i = 0;i < 4;i++)//0,1,2,3
    {
        printf("%dn",fun(i));
    }
    return 0;
}

//函数递归-阶乘
#include <stdio.h>
long jiecheng(int n)//n = 5
{
    long ret = -1;
    if(n < 0)
        printf("n < 0,input error!n");
    else if(n == 0||n == 1)
        ret = 1;
    else
        ret = jiecheng(n-1)*n;//jiecheng(4)*5
    return ret;
}
int main(int argc,char *argv[])
{
    int n;
    long y;
    printf("请输入一个数:");
    scanf("%d",&n);
    y = jiecheng(n);
    printf("%d! = %ldn",n,y);
    return 0;
}

//函数嵌套-阶乘
#include <stdio.h>
int pf(int i)
{
    return i * i;
}
int jc(int a)
{
    int i;
    int s = 1;
    a = pf(a);//函数嵌套
    for(i = 1;i <= a;i++)
    {
        s*=i;
    }
    return s;
}
int main(int argc,char *argv[])
{
    int i;
    int sum = 0;
    for(i = 1;i <= 3;i++)
    {
        sum += jc(i);
    }
    printf("%dn",sum);
    return 0;
}

//函数嵌套调用-最大值
#include <stdio.h>
int max(int x,int y)
{
    return x > y ? x : y;
}
int add(int x,int y)
{
    return x+y;
}
int main(int argc,char *argv[])
{
    int a,b,c;
    printf("请输入两个数:");
    scanf("%d%d",&a,&b);
    printf("%dn",max(a,b));//函数实参
//  c = max(a,b);//函数表达式
//  printf("%dn",c);//函数语句
    c = max(a,add(a,b));
    printf("%dn",c);//函数语句
    return 0;
}

//函数调用-简易计算器
#if 0
#include <stdio.h>
void add(float x,float y)
{
    printf("x+y = %.2fn",x+y);
}
void sub(float x,float y)
{
    printf("x-y = %.2fn",x-y);
}
void mul(float x,float y)
{
    printf("x*y = %.2fn",x*y);
}
void div(float x,float y)
{
    printf("x/y = %.2fn",x/y);
}
int main(int argc,char *argv[])
{
    float a,b;
    char c;
    printf("请输算式:");
    scanf("%f%c%f",&a,&c,&b);
    switch(c)   
    {
        case '+':add(a,b);break;
        case '-':sub(a,b);break;
        case '*':mul(a,b);break;
        case '/':div(a,b);break;
        default:printf("input error !n");
    }
    return 0;
}
#else
#include <stdio.h>
float add(float x,float y)
{
    return x+y;
}
float sub(float x,float y)
{
    return x-y;
}
float mul(float x,float y)
{
    return x*y;
}
float div(float x,float y)
{
    return x/y;
}
int main(int argc,char *argv[])
{
    float a,b,c;
    char d;
    printf("请输算式:");
    scanf("%f%c%f",&a,&d,&b);
    switch(d)   
    {
        case '+':c = add(a,b);break;
        case '-':c = sub(a,b);break;
        case '*':c = mul(a,b);break;
        case '/':c = div(a,b);break;
        default:printf("input error !n");
    }
    printf("%.2fn",c);
    return 0;
}
#endif

//函数调用
#include <stdio.h>
void hello()
{
    printf("hello wordn");
}
void add1()
{
    int a,b;
    printf("请输入a和b的值:");
    scanf("%d%d",&a,&b);
    printf("%dn",a+b);
}
void add2(int a,int b)
{
    int c = a+b;
    printf("%dn",c);
}
int add3()
{
    int a,b;
    printf("请输入a和b的值:");
    scanf("%d%d",&a,&b);
    return a+b;
}
int add4(int a,int b)
{
    return a+b;
}
int main(int argc,char *argv[])
{
    hello();
    add2(12,46);

    return 0;
}

//斐波那契数列
#include <stdio.h>
int main()
{
    int n;
    int b[20];
    b[1] = 1;b[2] = 1;
    for(n = 3;n <= 20;n++)
    {
        b[n] = b[n - 1]+b[n - 2];
    }
    for(n = 1;n <= 20;n++)
    {
        printf("%dn",b[n]);
    }
    return 0;
}

1. 有个别变量

  1. 生机勃勃部分变量:也称得上内部变量。在函数内做定义表达的。其成效域只限于函数内,离开函数后再选拔变量是违法的
    后生可畏都部队分变量成效域表达
    1) 主函数中定义的变量也只幸亏主函数中利用,无法在任何函数中选择
    2)
    形参变量是归属被调函数的一些变量,实参变量是归属主调函数的局地变量
    3) 允许在今是昨非的函数中央银行使同朝气蓬勃的变量名

1、什么是函数,为何要接收函数?
函数是做到一定任务的单独代码单元;
下落复杂性,防止重复代码段,约束了匡正端来的影响,隐含顺序,改过质量,
展开聚焦央调控制,隐含数据结构,隐含指针操作,隐含全局变量。
2、C语言函数的二种分类
从函数定义角度分类:库函数(#include<stdio.h>)
顾客自定义函数(#include “add.h”)
按有无重回值分类: 有重临值函数和无重返值函数
从主调函数和被调函数之间数据传送的角度分类:有参函数和无参函数
库函数从功效的角度分类:字符型分类函数、转变函数、目录路线函数、确诊函数、图形函数、输入输出函数、接口函数、字符串函数、内部存款和储蓄器管理函数、数学函数、日期和岁月函数、进度调整函数等。

2. 全局变量

  1. 全局变量:也称之为外界变量,是在函数外界定义的变量;其成效域是一切源程序,独有在函数内通过证实的全局变量手艺动用,全局变量说符为extern
    全局变量作用域表达
    1) 外界变量定义必须在具有的函数之外,且一定要定义一回。经常方式:
    [extern] 类型表达符 变量名, 变量名··· extern int a, b
    2卡塔 尔(阿拉伯语:قطر‎外界变量可巩固函数模块之间的数量联系但会使得函数的独立性减弱
    3)
    在同生龙活虎源文件中,允许全局变量和生机勃勃部分变量同名,在一些变量的效益域内,全局变量不起功效

3、函数定义的平日情势
1、无参函数的概念情势
品类标志符 函数名()
{
扬言部分
语句
}

3. 变量的仓库储存方式

  1. 静态存款和储蓄 和 动态存款和储蓄
    静态存款和储蓄变量常常是在
    常量定义时就分定期存款款和储蓄单元并直接不改变,直至整个程序甘休;全局变量即归属此类存款和储蓄情势;
    动态储存变量是在程序试行进程中,使用它时才分配存款和储蓄单元,使用完成立刻释放,函数的款式参数即归属此类存款和储蓄情势
    静态存款和储蓄变量是一贯留存的,而动态储存变量则时断时续,对变量的存储类型说明:
auto 自动变量
register 寄存器变量
extern 外部变量
static 静态变量
  • 机动变量和存放器变量归于动态储存方式
    外界变量和静态变量归于静态存储格局
 例、void Hello()
 {
 printf("hello worldn");
 }

小结

  1. 函数的归类
    1) 库函数:由C系统提供的函数
    2) 客户定义函数:由客户自个儿定义的函数
    3)
    有再次回到值的函数向调用者重返函数值,应表达函数类型(即再次回到值的花色)
    4) 无重返值的函数:不回去函数值,表达为空(void)类型
    5) 有参函数:主调函数向被调函数传送数据
    6) 无参函数:主调函数与被调函数无传送数据
    7) 内部函数:只可以在本院文件中应用的函数
    8) 外表函数:可在全方位源程序中动用的函数
  2. 函数 定义 的相似形式
    [extern/static] 类型说明符 函数名([形参表]) 方括号内为可选框
  3. 函数 表明 的貌似情势
    [extern] 类型表明符 函数名 ([形参表])
  4. 函数 调用 的日常情势
    函数名 ([实参表])
  5. 函数的参数
    分为形参 和
    实参
    ,形参出今后函数定义中,实参出以往函数调用中,产生函数调用时,将把实参的值送给形参
  6. 函数的值
    指函数的再次来到值,是在函数中由 return 语句再次回到的
  7. 数组名作为函数参数
    不实行值传送而开展地址传送,形参和实参实际上为同三个数组的多少个称呼,因而形参和实参同期变化
  8. C语言中,允许函数的嵌套调用 和 函数的递归调用
  9. 可依附变量的数据类型、变量功效域和变量的仓库储存类型对变量分类
  10. 变量的作用域是指变量在程序中的有效约束,分为风华正茂部分变量 和 全局变量
  11. 变量的存放类型是指变量在内部存款和储蓄器中的存款和储蓄方式,分为静态存款和储蓄 和
    动态存款和储蓄
    ,表示了变量的生存期

2、有参函数的概念方式
花色标志符 函数名(情势参数列表)
{
声称部分
语句
}

例、int max(int a,int b,int c)    //max 是一个整型函数,返回值是一个整数,形参a、b均为整型量。
 {
 int maxx=0;
 if (a>b)
 maxx=a;
 else
 maxx=b;

 if (max>c)
 return maxx;
 else
 return c;
 }

 我们可以直接在main函数中调用以上两个函数

 int main(int argc, char const *argv[])
 {
 int m=4,n=5,c=6;
 int d=0;
 d=max(m,n,c)
 printf("%dn",d);
 return 0;
 }

4、格局参数和实在参数
1、形参出以后函数定义中,在漫天函数体内都足以运用,离开该函数则不能够选择(如31行中的,a、b);
2、实参出今后主调函数中,步入被调函数中也不能够动用(如43行的m、n),实参能够是常量、变量、表明式、函数等,
3、在展开函数调用时,都必得具有鲜明的值,以便把值传给形参;
4、实参和形参在数额上、类型上、顺序上应严谨平等,不然会报错(类型不合营)
5、函数调用中发出的数据传送是单向的,只可以把实参的值传送给形参,在函数调用进度中,形参的值发生改变,实参的值不改造

例、
#include <stdio.h>
void text(int n ); //函数的声明
void text(int n)       //函数的定义
{
int i;
for (i = n-1; i > 0; i--)
{
n=n+i;
}
printf("函数中的n=%dn",n);
}

int    main(int argc, char const *argv[])
{
int n;
printf("请输入一个数:");
scanf("%d",&n);
text(n);           //函数的调用
printf("原来的n=%dn",n);
return 0;
}

5、函数的再次来到值
函数的再次回到值只可以经过return语句重临主调函数
return 语句的相近格局为:
return 表达式;或 return (表达式);
1、该语句的效力是计算表明式的值,并回到给主调函数,函数中允许三个return语句,不过每一回调用函数只好有四个return语句
被施行,每一遍调用只可以有二个重临值。
2、函数值的系列和函数定义中的函数类型应该保持风姿浪漫致,假诺不等同,以函数类型为准
3、无再次来到值的函数,能够断定定义为”空类型”,类型表明符为”void”

6、函数的调用
在程序中是透过对函数的调用来推行函数体的
C语言中等学园函授数调用的相同格局
函数名 (实际参数表) //无参函数则无实际参数,要是有多少个参数则用逗号隔断
函数调用的三种方法:
1、函数表明式:z=max(x,y);//一个赋值表明式,函数作为表达式的风流罗曼蒂克项现身,这种方式须求函数是有重回值的
2、函数语句:printf(“%d”,a);scanf(“%d”,&b);//函数调用的貌似形式充分分号构成语句;
3、函数实参:printf(“%dn”,max(x,y));
函数作为另三个函数调用的实际上参数现身;

计算数组元素的和
int sum(int *a,int n)
{
int sum=0;
int i;
for (i = 0; i < n; ++i)
{
sum+=a[i];
}
return sum;
}

int main(int argc, char const *argv[])
{
int a[10]={1,2,3,4,5,6,7,8,9,10};
int s=0;
s=sum(a,10);
printf("累加结果为:%dn",s );
return 0;
}

 交换两个数的值
 void swap(int x,int y)
 {
 int t=0;
 t=x;
 x=y;
 y=t;
 // printf("在函数中x=%d,y=%dn",x,y);
 }
 void swap2(int *x,int *y)
 {
 int t=0;
 t=*x;
 *x=*y;
 *y=t;
 }
 int main(int argc, char const *argv[])
 {
 int a=3,b=8;
 int *p,*q;
 p=&a;
 q=&b;
 printf("交换前a=%d,b=%dn",a,b);
 swap(a,b);
 swap2(p,q);
 printf("交换后a=%d,b=%dn",a,b );
 return 0;
 }
 int main(int argc, char const *argv[])
 {
 int x=3,y=5,t=0;
 printf("交换前x=%d,y=%dn",x,y );
 t=x;
 x=y;
 y=t;
 printf("交换后x=%d,y=%dn",x,y );
 return 0;
 }

被调函数的宣示和函数原型:
在主调函数中调用某函数以前应对该被调函数举办宣示,那于接纳变量在此以前对变量进行变量表明是同等的。目标是使剖析系统驾驭被调函数的回来值类型。
其雷同情势为
连串表达符 被调函数名(类型 形参,类型 形参,……卡塔 尔(阿拉伯语:قطر‎;
或者
品种表明符 被调函数名(类型,类型………卡塔 尔(阿拉伯语:قطر‎;

C语言中明确之下二种状态可以节约表明;
1:被调函数的重临值是整型或字符型,能够不对被调函数注解;
2:被调函数扬言在主调函数在此之前
3:在颇负函数早前先行表达了豆蔻梢头大器晚成函数的序列
4:对库函数的调用无需再做验证,但是必须把该函数的头文件用include命令满含。

函数的嵌套调用:
C语言不容许嵌套定义函数,不过允许在一个函数的概念中冒出另四个函数。这样就现身了函数函数嵌套调用。
计算 s=(22)!+(33)!

函数的递归调用:
三个函数在它的基本点中调用他的自家称为递归调用。这种函数称为递归函数。
推行的进程师长反复调用本身,每调用二遍都跻身新的意气风发层。

int f(int x)
{
    int y;
    z=f(y);
    return z;
}

那是八个递归函数,可是运转该函数将无平息的调用其本身。
为了防范递归函数无休憩的实行,必须在函数内有终止递归的手法,常用的法子是加条件剖断,满意条件之后就不再递归逐层退出。

long jiecheng(int n)
{
    long ret = -1;
    if(n<0)
        printf("n<0,input errorn");
    else if(n==0||n==1)
        ret = 1;
    else
        ret = jiecheng(n-1)*n;
}
int main()
{
    int n;
    long y;
    printf("input a intrager number:n");
    scanf("%d",&n);
    y=jicheng(n);
    printf("%d!=%ldn",n,y);
    return 0;
}

数组作为函数的参数
数组能够作为函数的参数使用,进行数据传送。数组作为函数参数有二种样式,大器晚成种是把数组成分作为实参使用;另风流浪漫种是把数组名作为函数的形参和实参使用。
剖断一个整型数组中个成分的值,假设大于0,则输出该值,不然输出0,
1:数组元素作为实际上参数时,数组成分的档次和函数形参的档案的次序保持风姿浪漫致,当时数组成分是三个枯燥没味变量。
数组名作为函数参数时,需求形参和实参都必需是系列相仿的。
2:数组成分做函数参数时,形参和实参是由编写翻译器分配的多个分化的内部存款和储蓄器单元,在函数调用时发生的值传递是把实参变量给与形参变量。
在用数组名做函数参数时,不是进展值传送,即不是把参数组的每三个要素的值都给以形参组的逐黄金时代要素。因为实际形参数组并空头支票,编写翻译数组并不为形参数组分配内部存款和储蓄器。数组名就是数组的首地址,。数组做函数参数时说举行的传递只是地址的传递,也正是说把实参数组的首地址赋给形参数组名,形参数组名获得改首地址后,也就等于有了实际的数组。实际上是形参数组和实参数组为同意气风发数组,协作享有风流罗曼蒂克段空间。

部分变量和全局变量:形参独有在被调用时期才被分配单元,调用甘休马上放飞,形参只有在函数内才是卓有成效的,离开函数之后不可能在继承运用。这种变量有效性的节制称为变量的效率域。

C语言中的变量依照其成效域范围可分为局地变量和全局变量。
有的变量也称为内部变量,局地变量是在函数钦定义的,其效用域只限于函数内,离开该函数后再利用这种变量是不法的。
注意:
1:主函数中定义的变量也必须要在主函数中运用
2:形参变量是归于被调函数的一些变量,实参变量归于主调函数
3:允许在不相同的函数中接收相符的变量名;
4:在复合语句中定义的变量,功效域只限于复合语句中。

全局变量也称得上外界变量,它是在函数外界定义的;他不附归于哪个函数,他归于八个程序源文件。其功能域是风度翩翩体源程序。

意气风发部分变量会隐蔽全局变量。

变量的积存类别:
动态积存方式与静态存款和储蓄情势
从变量值的生存期来划分可分为,静态存款和储蓄方式和动态储存格局。
静态存款和储蓄格局是指在程序运转时期分配一定的积累空间的主意。
动态储存方式是在程序运营时期依据需求展开动态分配存款和储蓄空间的措施。
客商存储空间能够分成三有的:
(1)程序区
(2卡塔 尔(英语:State of Qatar)静态数据区
(3卡塔尔国动态数据区
全局变量存款和储蓄在静态数据区,程序开端时分配,截至时释放,侵夺一定单元。
动态存储区存放以下数据:
函数形参,
自行变量(未加static修饰的有的变量卡塔尔国,
函数调用的实地维护和再次来到地址。

static证明局地变量
有的时候希望函数中的局地变量的值在函数调用后不流失而保留原值,这使就钦点局地变量为“静态局地变量”,用关键字static注明。

对静态局地变量的表明:
一些变量归于静态存款和储蓄种类,在静态存款和储蓄区内分配单元,整个程序运营时期都不自由。
静态局地变量在编写翻译时赋值,只赋值一回;
不赋初值的话,编写翻译器暗许符0;

admin

网站地图xml地图