C语言函数,电商专业学习嵌入式软件开发第六十三天

第5章 函数

 

第5章
函数
1.
函数
2.
变量的功效域
1.
部分变量
2.
全局变量
3.
变量的积攒情势
小结

 

  • ###### C基本功第八天

1. 函数

  1. 从函数定义的角度看,函数可分为库函数和客户自定义函数两种
    1)
    库函数:由C系统提供,只需在前后相继前包括有该函数原型的头文件就能够在前后相继中央直属机关接调用
    2)
    顾客自定义函数:由顾客按须求写的函数,不止在前后相继中定义函数自身,并且在主调函数模块中还非得对该被调用函数进行项目表达,然后使用
  2. 从函数兼有别的语言中的函数和经过的七个成效,又可分为有重临值函数和无再次回到值函数
    1)
    有再次来到值函数:此类函数被调用实施完后将向调用者重临三个奉行结果,称为函数再次来到值;由顾客定义的这种要赶回值得函数,必得在函数定义和函数表达中一望而知再次来到值的体系
    2)
    无重临函数:此类函数在做到一定的管理任务,实施到位后不向调用者重回函数值。由于函数无须再次来到值,客商定义此类函数时可钦赐他的回来为”空类型(void)”
  3. 从主调函数和被调函数之间数据传送的角度可分为无参函数和有参函数
    1)
    无参函数:函数定义、函数表达及函数调用中均不带参数。主调函数和被调函数之间不举行参数字传送送。能够回到或不回来函数值
    2)
    有参函数:在函数定义及函数表达时都有参数,称为方式参数(形参卡塔尔。在函数调用时也非得付出参数,称为实际参数(实参)。实行函数调用时,主调函数将把实参的值传送给形参,供被函数使用
  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;
 }

被调函数的宣示和函数原型:
在主调函数中调用某函数早前应对该被调函数举办宣示,那于选用变量以前对变量举办变量表明是如出大器晚成辙的。指标是使剖释系统驾驭被调函数的回到值类型。
其貌似情势为
品类表达符 被调函数名(类型 形参,类型 形参,……卡塔尔国;
或者
品类表明符 被调函数名(类型,类型………卡塔尔国;

发表评论

电子邮件地址不会被公开。 必填项已用*标注