一些必备的基础C语言语法(3)

一、递归

1.递归的基本概念

递归调用:一个函数直接或间接地调用了它本身,就称为函数 的递归调用,简称递归。 你中有我,我中有你-函数的递归调用

2. 递归函数的执行过程

(求一个函数的n阶乘)
源代码:

主体:

int main( ) {
    int n; 
    float y; 
    printf("\nInput n:");
    scanf("%d",&n);
    y=fact(n); /*函数调用*/ 
    printf("%d!=%-10.0f\n",n,y); 
    return 0;
}

实现函数:

/*求一个数的阶乘函数*/
float fact (int n){
    float f=0;
    if(n<0) {
        printf("n<0,error!");
    }
    else if (n==0 || n==1) /*递归结束*/{
        f=1;
    }
    else {
        f=n*fact(n-1);
    }
    return(f);
}

3、递归说明

• 当函数自己调用自己时,系统将自动把函数中当前 的变量和形参暂时保留起来,在下一轮的调用过程中 ,系统为新调用的函数所用到的变量和形参开辟另外 的存储单元(内存空间)。每次调用函数所使用的变 量在不同的内存空间。

• 递归调用的层次越多,同名变量的占用的存储单元 也就越多。

• 当本次调用的函数运行结束时,系统将释放本次调 用时所占用的内存空间。程序的流程返回到上一层的 调用点,同时取得当初进入该层时,函数中的变量和 形参所占用的内存空间的数据。 

4 、数值类递归例题

编写程序,求数列1,1,2,3,5,8,13,21,…… 的第N项。

思路:

这是一个数值问题

第1步:找出表示数列第N项的递归公式: FN = FN-1 + FN-2  

第2步:递归的结束条件,当N=1或N=2时,F N=1。 根据以上思路考虑编程。

long fib( int n ){                            /*  第 N 项 */
    if ( n <= 2 )  {    
        return( 1 );                          /*  结束条件 */
    }
    else   {
    return fib( n - 1 ) + fib( n - 2 );       /*第 N - 1 项 + 第 N - 2 项*/
}

5、编写递归程序要点:

1)找到正确的递归算法,这是编写递归程序的基础;

2)确定递归算法的结束条件,这是决定递归程序能否正常结束 的关键。

        数值问题, 可以表达为数学公式, 从数学公式推导出问题的 递归定义,然后确定问题的边界条件,从而确定递归的算法和递 归结束条件。

二、局部变量和全局变量

1、 变量的属性

操作属性 :变量的类型

存储属性:1)存储器类型:寄存器、静态存 储区、动态存储区

                  2)生存期:变量在某一时刻存在- ----静态变量与动态变量

                  3)作用域:变量在某区域内有效- ----局部变量与全局变量

2 、变量定义格式

格式: 存储类型 数据类型 变量表;

3 、局部变量与全局变量

int x,y;
int main( ){ 
    int a,b,c;
    int fun(int);
    x=10;    
    y=11;
    fun(a);
    ….
    return 0; 
}
    int fun( int m){
     x++;
     y++;
    …..
}

(1)局部变量---内部变量

定义 :在数或复合语句内定义 ,在定义它的数或复合语句内有效

•不同函数中同名变量, 占不同内存单元 

• 形参属于局部变量

 • 局部变量只在函数调用时起作用,函数调用结束有效值消失。

(2)全局变量---外部变量

定义:在函数外定义,可为本文件内所有函数共用。 有效范围是从定义该变量的位置开始到本源文件结束,及有 extern说明的其它源文件

三、动态变量与静态变量

1、变量的存储方式

 静态存储:程序运行期间分配固定存储空间。

 动态存储:程序运行期间根据需要动态分配存储空间。

2、变量的生存期 变量值保留的期限

静态变量: 从程序开始执行到程序结束。

动态变量: 从包含该变量定义的函数开始执行至函数执行结束。

3、变量的存储类型

(1)自动变量auto

自动变量存储特性:

•定义自动变量的函数被调用时,才为自动变量分配内存。

•函数调用结束时,为自动变量分配的内存被释放。

•自动变量仅在定义它的函数内部有效。

•自动变量被存放在内存的动态存储区。

结论:自动变量的生存期和可见性 自动变量的生存期和可见性(作用域)仅限于定义它的函数内部。自动变量是一种局部变量。

(2)静态变量static 

 静态变量static分为局部静态变量和全局静态变量。

 静态变量存储在内存的静态存储区,有固定的地址。

 静态变量在程序运行期间,变量值自始至终保留。

         局部静态变量:函数内部定义,函数外不可见。程 序运行期间,值保留。

         全局静态变量:函数外定义,仅本文件内部其他函 数可以访问。

静态变量存储特性 :

 在编译阶段,为静态变量分配内存。静态变量被存放在内存的 静态存储区。

 静态变量的生存期是在程序运行的整个时期,整个程序运行结束时,为静态变量分配的内存才被释放。

 静态变量仅在定义它的函数内部有效。

 在编译阶段定义静态变量的时,静态变量被置0。

 关键字static和auto决定变量被存放在内存的哪个数据区。

(3)外部变量extern 

外部变量的生存期是在程序运行的整个时期,可见性(作用域) 从定义它的位置到文件结束。

外部变量是一种全局变量。

同名的外部变量和局部变量,是不同的两个变量。函数内部说明了一个和外部变量同名的局部变量,则外部变量被屏蔽。

四、编译预处理

        编译预处理:在源程序文件中,加入“编译预处理命令”,使编译 程序在对源程序进行通常的编译 包括词法分析 语法分析 编译预处理 ( 词法分析、语法分析、 代码生成、代码优化)之前,先对这些命令进行预处理,然后 将预处理的结果和源程序一起再进行通常的编译处理,以得到 目标代码(OBJ文件)。

C提供的编译预处理命令

 宏命令

 文件包含命令

 条件编译命令

以#开头,以区别于语句。

1 、宏定义

也叫宏替换,是字符串之间的替换。

(1)不带参数的宏

形式:#define PI 3.1415926

作用:用标识符(称为“宏名”)PI代替字符串“3.1415926”。 在预编译时,将源程序中出现的宏名PI替换为字符串 “3.1415926”, 替换过程称为“宏展开”。

(2) 带参数的宏

一般形式: #define 宏名(参数表) 字符串

        作用:带参数的宏在展开时,将程序中出现的带实参的宏名 , 替换成由实参组成的字符串 。

注意:带参数的宏中括号的使用

思考:分别用函数和带参数的宏实现输出10以内自然数的平方。

2 、文件包含

格式 : #include “文件名”

作用:预处理时,把“文件名”指定的文件内容复制到本文件,再对合并后的文件进行编译。

在file1.c文件中,有文件包含命令#include "file2.c",预处理时, 先把file2.c的内容复制到文件file1.c,再对file1.c进行编译。

从理论上说,#include命令可以包含任何类型的文件,只要这些文 件的内容被扩展后符合C语言语法。

一般#include命令用于包含扩展名为.h的“头文件”,如stdio.h、 string.h、math.h。在这些文件中,一般定义符号常量、宏,或声明函数原型。

  • 33
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值