天天看点

【C语言】-模块化设计学习笔记一、模块化设计思想二、函数三、预处理

目录

模块化设计思想

函数

函数的定义

函数的调用

预处理

一、模块化设计思想

在进行程序设计时,把一个大的程序按功能划分为若干小的程序,每个小程序完成一个特定的功能,把这些小程序之间建立必要的联系即可以完成整个程序的功能,这些小的程序就是模块。

通常规定模块只有一个入口和出口,使用模块的约束条件使入口参数和出口参数。

二、函数

2.1 函数的定义

1.库函数(系统定义的标准函数比如printf() scanf()...)

库函数的函数说明或声明一般放在系统的include目录下以.h为后缀的头文件中,比如stdio.h等,

如果程序要调用到某个库函数则用#include<头文件名>将库函数信息包含进本程序即可。

2.用户自定义函数

函数定义不能嵌套

//函数定义的一般形式

函数返回值类型 函数名(形参表)
{
    变量声明;
    语句;
    return 表达式;
}

//一个例子:高斯级数累加
int GaussSum(int a,int e)
{
    int nSum=0;
    for(i=a;i<e;i++)
        nSum+=1;
    return nSum;
}
           

函数返回值:函数返回值类型指函数体执行完毕之后返回给主调函数值的类型,它可以是数组以外的任意类型。如果函数没有返回值则用void来定义函数类型。

形参:形参在被调用之前,系统不会给它分配内存空间。形参不是函数定义所必需的,当函数设计不需要参数时,用void表示。

return语句:将函数中的一个确定之带回调用它的函数中去,在一个函数里可以有多个return,也可以没有return(没有返回值的情况),如果return表达式值的类型和函数返回值类型不匹配则以函数返回值的类型为准进行强制转换。

//多个return的情况
int Min(int a,int b)
{
    if(a>b)
        return a;
    else
        return b;
}
           

2.2函数的调用

//以前面的高斯级数累加函数为例调用
void fun() //fun()为GaussSum()的主调函数
{
    int start=5,end=10,nRet;
    int GaussSum(int a,int e);//函数声明
    nRet=GaussSum(start,end);//函数调用
}
           

函数声明不是必须的(被调函数在主调函数定义之后才定义且返回值不是整型则必须进行函数声明,函数声明可以在函数调用前的任意位置)

可以省去函数声明的情况:

  1. 被调用函数的定义在主调函数之前
  2. 所有函数定义之前,在函数外部(可以在头文件中也可以在程序开始处)预先对各个函数进行声明
  3. 返回值为整型,因为如果再调用之前没有做声明,那么系统会把第一次遇到的该函数形式作为函数声明,并将函数类型默认为int型。

函数调用:

函数名(实参表);
           

函数调用存在一个赋值过程,实参会把数值赋值给形参,然后系统为形参分配空间,之后无论形参怎样改变都不会影响实参。

三、预处理

C语言中“#”开头的都是预处理命令

3.1文件包含

//两种形式
#include"文件名"
#include<文件名>    //一个include只能包含一个文件,多个文件需要有多个include
           

功能:把指定文件插入到该命令行所在位置,替换该命令行,把指定文件和当前源程序文件连成一个源文件。

文件包含允许嵌套:比如文件1包含文件2,而文件2需要用到文件3则可以写成如下形式

//文件嵌套
#include<file3.h>
#include<file2.h>    //文件3必须出现在文件2之前
           

 3.2宏定义

1.不带参数的宏定义

#define 标识符字符串

#define M (a*a+3*b)
void main()
{
    int nSum;
    nSum=3*M;//等效为3*(a*a+3*b)
}


#define M a*a+3*b
void main()
{
    int nSum;
    nSum=3*M;//等效为3*a*a+3*b
}
           

特点:

  1. 编译时以字符串代替宏名只是简单的替换,不会有其它判断,上述两个例子可以很好的体现也一点,宏展开也叫做无脑替换。
  2. 宏定义末尾不用加分号,否则连同分号一起替换
  3. 宏定义必须写在函数之外,作用域为本源程序结束,如果要终止其作用域可以使用#undef
  4. 源程序中如果宏名在“ ”里,则不进行宏展开,将宏名当作字符串处理
    #define M
    int main()
    {
    printf("M");//运行结果为M
    }
               

2.带参数的宏定义

#define 宏名(形参表) 字符串
#define M(y) (y*y+3*y)
void main()
{
    int a=2;
    int nNum;
    nNum=M(a);
}
           

注意:宏定义的形参不必做类型说明,因为调用时会用实参代替形参,而函数中是将实参的值赋给形参,所以形参也要进行类型声明。

继续阅读