当前位置: 凤凰彩票官方app > 编程知识 > 正文

电商业专科学校业学习嵌入式软件开垦第四十七

时间:2019-11-14 16:27来源:编程知识
第5章 函数   第5章函数 1.函数 2.变量的作用域 1.局部变量 2.全局变量 3.变量的存储方式 小结   ###### 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. 函数的递归使用:一个函数在它的函数体内调用它自身称为递归调用,为了防止递归调用无终止进行,加条件判断

今天讲的是函数,明天开始讲指针。现在出现在笔记中的代码都是我写不出来的,看了一下这两天的代码量,感觉很是头疼,背下来都有难度。

什么是函数,为什么要使用函数?

  • 函数是完成特定任务的独立代码单元;
  • 降低复杂性,避免重复代码段,限制了改动带来的影响,隐含顺序,改进性能,
  • 进行集中控制,隐含数据结构,隐含指针操作,隐含全局变量。
    我们可以对函数进行调用,这样避免了我们一大串代码写在一个main函数中。

C语言中对函数的分类,下面来简单总结一下。

有无返回值参数就不多说了。void main 无返回值,不过老师不建议使用无返回值的函数,具体原因自己也不太清楚,待会可以百度一下;int main 有返回值。

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;
}

形式参数和实际参数

  • 形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用(如31行中的,a、b);
  • 实参出现在主调函数中,进入被调函数中也不能使用(如43行的m、n),实参可以是常量、变量、表达式、函数等,
  • 在进行函数调用时,都必须具有确定的值,以便把值传给形参;
  • 实参和形参在数量上、类型上、顺序上应严格一致,否则会报错(类型不匹配)
  • 函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,在函数调用过程中,形参的值发生改变,实参的值不改变。

1. 局部变量

  1. 局部变量:也称为内部变量。在函数内做定义说明的。其作用域仅限于函数内,离开函数后再使用变量是违法的
    局部变量作用域说明
    1) 主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用
    2) 形参变量是属于被调函数的局部变量,实参变量是属于主调函数的局部变量
    3) 允许在不同的函数中使用相同的变量名

1、什么是函数,为什么要使用函数?
函数是完成特定任务的独立代码单元;
降低复杂性,避免重复代码段,限制了改动带来的影响,隐含顺序,改进性能,
进行集中控制,隐含数据结构,隐含指针操作,隐含全局变量。
2、C语言函数的几种分类
从函数定义角度分类:库函数(#include<stdio.h>) 用户自定义函数(#include "add.h")
按有无返回值分类: 有返回值函数和无返回值函数
从主调函数和被调函数之间数据传送的角度分类:有参函数和无参函数
库函数从功能的角度分类:字符型分类函数、转换函数、目录路径函数、诊断函数、图形函数、输入输出函数、接口函数、字符串函数、内存管理函数、数学函数、日期和时间函数、进程控制函数等。

函数的返回值

函数的返回值只能通过return语句返回主调函数
return 语句的一般形式为:
return 表达式;或 return (表达式);

2. 全局变量

  1. 全局变量:也称为外部变量,是在函数外部定义的变量;其作用域是整个源程序,只有在函数内经过说明的全局变量才能使用,全局变量说符为extern
    全局变量作用域说明
    1) 外部变量定义必须在所有的函数之外,且只能定义一次。一般形式: [extern] 类型说明符 变量名, 变量名··· extern int a, b
    2) 外部变量可加强函数模块之间的数据联系但会使得函数的独立性降低
    3) 在同一源文件中,允许全局变量和局部变量同名,在局部变量的作用域内,全局变量不起作用

3、函数定义的一般形式
1、无参函数的定义形式
类型标识符 函数名()
{
声明部分
语句
}

函数的调用

在程序中是通过对函数的调用来执行函数体的
C语言中函数调用的一般形式
函数名 (实际参数表) //无参函数则无实际参数,如果有多个参数则用逗号隔开。

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;
}

函数的调用还是挺好用的,使函数的结构更加清晰,避免出错。

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、有参函数的定义形式
类型标识符 函数名(形式参数列表)
{
声明部分
语句
}

C语言中规定以下几种情况可以省去声明;

1:被调函数的返回值是整型或字符型,可以不对被调函数声明;
2:被调函数声明在主调函数之前
3:在所有函数之前预先说明了各个函数的类型
4:对库函数的调用不需要再做说明,但是必须把该函数的头文件用include命令包含。

例、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;
 }

函数的嵌套调用:

  • C语言不允许嵌套定义函数,但是允许在一个函数的定义中出现另一个函数。这样就出现了函数函数嵌套调用。
    计算 s=(22)!+(33)!

4、形式参数和实际参数
1、形参出现在函数定义中,在整个函数体内都可以使用,离开该函数则不能使用(如31行中的,a、b);
2、实参出现在主调函数中,进入被调函数中也不能使用(如43行的m、n),实参可以是常量、变量、表达式、函数等,
3、在进行函数调用时,都必须具有确定的值,以便把值传给形参;
4、实参和形参在数量上、类型上、顺序上应严格一致,否则会报错(类型不匹配)
5、函数调用中发生的数据传送是单向的,只能把实参的值传送给形参,在函数调用过程中,形参的值发生改变,实参的值不改变

函数的递归调用:

  • 一个函数在它的主体中调用他的自身称为递归调用。这种函数称为递归函数。
    执行的过程中将反复调用自身,每调用一次都进入新的一层。
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;
}

这是一个求阶层的问题,其中使用到了函数的递归调用。其中的ret=jieceng(n-1)*n这里。

例、
#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"

数组作为函数的参数

  • 数组可以作为函数的参数使用,进行数据传送。数组作为函数参数有两种形式,一种是把数组元素作为实参使用;另一种是把数组名作为函数的形参和实参使用。
    判断一个整型数组中个元素的值,如果大于0,则输出该值,否则输出0,
    1:数组元素作为实际参数时,数组元素的类型和函数形参的类型保持一致,这时数组元素是一个普通变量。
    数组名作为函数参数时,要求形参和实参都必须是类型相同的。
    2:数组元素做函数参数时,形参和实参是由编译器分配的两个不同的内存单元,在函数调用时发生的值传递是把实参变量赋予形参变量。
    在用数组名做函数参数时,不是进行值传送,即不是把参数组的每一个元素的值都赋予形参组的各个元素。因为实际形参数组并不存在,编译数组并不为形参数组分配内存。数组名就是数组的首地址,。数组做函数参数时说进行的传送只是地址的传送,也就是说把实参数组的首地址赋给形参数组名,形参数组名取得改首地址后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段空间。

6、函数的调用
在程序中是通过对函数的调用来执行函数体的
C语言中函数调用的一般形式
函数名 (实际参数表) //无参函数则无实际参数,如果有多个参数则用逗号隔开
函数调用的几种方式:
1、函数表达式:z=max(x,y);//一个赋值表达式,函数作为表达式的一项出现,这种方式要求函数是有返回值的
2、函数语句:printf("%d",a);scanf("%d",&b);//函数调用的一般形式加上分号构成语句;
3、函数实参:printf("%dn",max(x,y)); 函数作为另一个函数调用的实际参数出现;

局部变量和全局变量

  • 局部变量也称为内部变量,局部变量是在函数内定义的,其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。
    注意:
    1:主函数中定义的变量也只能在主函数中使用
    2:形参变量是属于被调函数的局部变量,实参变量属于主调函数
    3:允许在不同的函数中使用相同的变量名;
    4:在复合语句中定义的变量,作用域仅限于复合语句中。

  • 全局变量也称为外部变量,它是在函数外部定义的;他不从属于哪个函数,他属于一个程序源文件。其作用域是整个源程序。

*局部变量会屏蔽全局变量。

计算数组元素的和
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;
 }

变量的存储类别:

  • 动态存储方式与静态存储方式
    从变量值的生存期来划分可分为,静态存储方式和动态存储方式。
    静态存储方式是指在程序运行期间分配固定的存储空间的方式。
    动态存储方式是在程序运行期间根据需要进行动态分配存储空间的方式。
    用户存储空间可以分为三部分:
    (1)程序区
    (2)静态数据区
    (3)动态数据区
    全局变量存储在静态数据区,程序开始时分配,结束时释放,占据固定单元。
  • 动态存储区存放以下数据:
    函数形参,
    自动变量(未加static修饰的局部变量),
    函数调用的现场保护和返回地址。

被调函数的声明和函数原型:
在主调函数中调用某函数之前应对该被调函数进行声明,这于使用变量之前对变量进行变量说明是一样的。目的是使辨析系统知道 被调函数的返回值类型。
其一般形式为
类型说明符 被调函数名(类型 形参,类型 形参,......);
或者
类型说明符 被调函数名(类型,类型.........);

static声明局部变量

  • 有时希望函数中的局部变量的值在函数调用后不消失而保留原值,这使就指定局部变量为“静态局部变量”,用关键字static声明。

  • 对静态局部变量的说明:
    局部变量属于静态存储类别,在静态存储区内分配单元,整个程序运行期间都不释放。
    静态局部变量在编译时赋值,只赋值一次;
    不赋初值的话,编译器默认符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)静态数据区
(3)动态数据区
全局变量存储在静态数据区,程序开始时分配,结束时释放,占据固定单元。
动态存储区存放以下数据:
函数形参,
自动变量(未加static修饰的局部变量),
函数调用的现场保护和返回地址。

static声明局部变量
有时希望函数中的局部变量的值在函数调用后不消失而保留原值,这使就指定局部变量为“静态局部变量”,用关键字static声明。

对静态局部变量的说明:
局部变量属于静态存储类别,在静态存储区内分配单元,整个程序运行期间都不释放。
静态局部变量在编译时赋值,只赋值一次;
不赋初值的话,编译器默认符0;

编辑:编程知识 本文来源:电商业专科学校业学习嵌入式软件开垦第四十七

关键词: