文档库

最新最全的文档下载
当前位置:文档库 > 实验七(3) 函数与预处理命令

实验七(3) 函数与预处理命令

实验七(3)函数与预处理命令

实验目的:

1.理解函数的基本概念和特点

2.掌握函数的参数传递方式和调用方法

3.理解局部变量和全局变量的概念和变量的存储属性

4.理解内部函数和外部函数

5.掌握预处理命令的使用

实验相关内容简介:

C语言是函数式语言,必须有且只能有一个名为main的主函数,C程序的执行总是从main函数开始,在main中结束。C语言中函数不能嵌套定义,可以嵌套调用。

从用户的角度函数可以分为由系统提供给用户的标准函数(库函数)和用户自定义函数;从函数的形式分为无参函数和有参函数。

使用库函数时应注意调用函数的功能,函数参数的数目和顺序,及各参数的意义和类型,函数返回值的意义和类型,需要使用的包含文件。

1.函数定义的一般形式

实验七(3) 函数与预处理命令

图6.1 函数定义的一般形式

2.函数参数及传递方式

形式参数(形参):定义函数时函数名后面括号中的变量名;

实际参数(实参):调用函数时函数名后面括号中的表达式。

实验七(3) 函数与预处理命令

图6.2 函数实参和形参举例

实参和形参的说明:

(1) 实参必须有确定的值;

(2) 形参必须指定类型;

(3) 形参与实参类型一致,个数相同;

(4) 若形参与实参类型不一致,自动按形参类型转换——函数调用转换;

(5) 形参在函数被调用前不占内存,函数调用时为形参分配内存,调用结束,内存释放。

传递方式:

(1) 值传递方式

方式:函数调用时,为形参分配单元,并将实参的值复制到形参中;调用结束,形参单元被释放,实参单元仍保留并维持原值。

特点:形参与实参占用不同的内存单元,单向传递。

(2) 地址传递

方式:函数调用时,将数据的存储地址作为参数传递给形参。

特点:形参与实参占用同样的存储单元,“双向”传递,实参和形参必须是地址常量或变量。

3.函数的返回值

返回语句形式:

return (表达式);

或return 表达式;

或return;

功能:使程序控制从被调用函数返回到调用函数中,同时把返回值带给调用函数。

说明:

(1) 函数中可有多个return语句;

(2) 若无return语句,遇“}”时,自动返回调用函数;

(3) 若函数类型与return语句中表达式值的类型不一致,按前者为准,自动转换;

(4) void型函数为无返回值函数。

4.函数的调用和说明

调用形式:

函数名(实参表);

调用方式:

(1) 函数语句: 例 printstar();

printf(“Hello,World!\n”); (2) 函数表达式:

例 m=max(a,b)*2; (3) 函数参数:

例 printf(“%d”,max(a,b)); m=max(a,max(b,c)); 函数说明:

(1) 对被调用函数要求:

必须是已存在的函数, 如调用库函数,则在源程序开头要有相应的 #include <*.h> ;如为用户自定义函数,则须有函数类型说明。如果被调用函数定义出现在主调函数之前或已在所有函数定义之前,在函数的外部已做了函数说明,则在各个主调函数中不必对所调用的函数再作说明。

(2) 函数说明的一般形式:

函数类型 函数名(形参类型 [形参名],….. ); 或 函数类型 函数名( );

函数说明的作用是告诉编译系统函数类型、参数个数及类型,以便检验。函数定义与函数说明不同,函数说明的位置在程序的数据说明部分(函数内或外)。

5. 函数的嵌套调用和递归调用

(1) 嵌套调用:

C 规定:函数定义不可嵌套,但可以嵌套调用函数,如图6.3所示。

图6.3 函数嵌套调用示意图

(2) 递归调用

main( )

结束

a 函数

b 函数

调用函数b

a 结束

b 结束

调用函数a

函数直接或间接的调用自身叫函数的递归调用。

6.变量的存储属性

变量是对程序中数据的存储空间的抽象。变量的属性有数据类型,即变量所持有的数据的性质(操作属性)。另外,还有存储属性。

存储变量涉及到的存储位置有:寄存器中、静态存储区中、和动态存储区中。

(1) 变量的存储类型:

●auto ——自动型

●static ——静态型

●register ——寄存器型

●extern ——外部型

(2) 变量的分类:

生存期:变量存在的时间角度——静态变量与动态变量。

作用域:变量在某区域内有效——局部变量与全局变量。

(3) 变量的定义格式一般:

[存储类型] 数据类型变量表;

7.局部变量与全局变量

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

定义:在函数内定义,只在本函数内有效。

说明:main中定义的变量只在main中有效,不同函数中同名变量,占不同内存单元,形参属于局部变量,可定义在复合语句中有效的变量,局部变量可用存储类型:auto、register、static,默认为auto。

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

定义:在函数外定义,可为本文件所有函数共用。

有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件。

外部变量说明:extern 数据类型变量表;

外部变量可用存储类型:缺省或static

8.内部函数和外部函数

(1) 内部函数

如果一个函数只能被本文件中其他函数所调用,它称为内部函数。在定义内部函数时,在函数名和函数类型的前面加static。即:

static 类型标识符函数名(形参表)

例如: static int fun ( int a , int b )

b) 外部函数

定义函数时,如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可供其他文件调用。例如,函数首部可以写为extern int fun (int a, int b),这样,函数fun就可以为其他文件调用。如果在定义函数时省略extern,则隐含为外部函数。在需要调用此函数的文件中,用extern对函数作声明,表示该函数是在其他文件中定义的外部函数。

9.预处理命令的应用

(1) 作用:对源程序编译之前做一些处理,生成扩展C源程序。

(2) 种类:

宏定义: #define 文件包含: #include

条件编译: #if —#else —#endif 等 (3) 格式说明:

以“#”开头,占单独书写行,语句尾不加分号。

实验例题:

【例7.1】计算x 的立方。理解函数调用时实参和形参被分配内存空间的变化情况。 #include float cube(float x) { return(x*x*x); }

main()

{ float a, product;

printf("Please input value of a:"); scanf("%f", &a); product=cube(a);

printf("Cube of %.4f is %.4f\n",a,product); }

运行结果:

Please input value of a: 1.2 Cube of 1.2000 is 1.7280

分析:输入1.2,回车后输出1.2的立方1.7280。其内存变化情况如下: 变量

变量

实验七(3) 函数与预处理命令

实验七(3) 函数与预处理命令

实验七(3) 函数与预处理命令

实验七(3) 函数与预处理命令

实验七(3) 函数与预处理命令

变量 变量 变量 a a a a a product product product x x

(a)主函数main 执行为变量a ,product 分配内存单元,初始值不定 (b )通过scanf 函数为变量a 输入初始值1.2 (c )调用cube 函数,为形参x 分配内存,并将实参a 的值传递给形参x

(d )执行cube 函数,计算x 的立方,将值

返回赋予变量

product (e )调用cube 函数结束,释放为形参x 分配的内存空间

图6.4 计算x 的立方函数内存空间的变化情况

【例7.2】运行如下两个程序,分析运行结果,理解局部静态变量值是具有可继承性的。

程序1:

#include

main( )

{ void increment(void);

increment( );

increment( );

increment( );

}

void increment( )

{ int x=0;

x++;

printf("%d\n",x);

}

运行结果:

1

1

1

程序2:

#include

main ( )

{ void increment(void);

increment( );

increment( );

increment( );

}

void increment(void)

{ static int x=0;

x++;

printf(“%d\n”,x);

}

运行结果

1

2

3

【例7.3】运行下面程序,理解外部变量的定义,并分析外部变量定义时的注意事项和出现的副作用。

程序1:

#include

int i;

main()

{ void prt( );

for(i=0;i<5;i++)

prt( );

}

void prt( )

{ for(i=0;i<5;i++)

printf(“%c”,’*’);

printf(“\n”);

}

运行结果:

*****

程序2:

#include

main( )

{ void prt( ); int i;

for(i=0;i<5;i++)

prt( );

}

void prt( )

{int i;

for(i=0;i<5;i++)

printf(“%c”,’*’);

printf(“\n”);

}

运行结果:

*****

*****

*****

*****

*****

【例7.4】输入2个整数,比较大小,理解下面应用宏定义代表关系运算符的方式。#include "stdio.h"

#define LAG >

#define SMA <

#define EQ ==

void main()

{

int i=10;

int j=20;

printf("please input i:");

scanf("%d",&i);

printf("please input j:");

scanf("%d",&j);

if(i LAG j)

printf("\40: %d larger than %d \n",i,j);

else if(i EQ j)

printf("\40: %d equal to %d \n",i,j);

else if(i SMA j)

printf("\40:%d smaller than %d \n",i,j);

else

printf("\40: No such value.\n");

}

【例7.5】运行以下程序,理解带参宏。

下面程序的运行结果是。

#define N 10

#define s(x) x*x

#definef (x) (x*x)

main()

{ int i1,i2;

i1=1000/s(N);i2=1000/f(N);

printf(“%d%d\n”,i1,i2);

}

实验习题:

(1)新建一个文件,输入以下程序代码:

#include

#include

double fun( int n)

{

/* 这里是需要你完成的程序编写*/

}

main( )

{ printf("s =%f\n", fun ( 1000) );

}

输入代码无误后完成fun函数的内容,函数的功能是:求小于形参n同时能被3与7整除的所有自然数之和的平方根,并作为函数值返回。

(2)新建一个文件,输入以下程序代码:

#include

double fun( int n )

{

/* 这里是需要你完成的程序编写*/

}

main( )

{ printf("%f\n", fun(10));

}

输入代码无误后完成fun函数的内容,函数的功能是:计算并输出下列级数和:

1 1 1

S = ── + ── + … + ───

1×2 2×3 n(n+1)

例如,当n = 10时,函数值为:0.909091。

完成编程后运行程序,输入上面所举的数据例子,看看程序是否能得出正确的结果。