null 第 七 章
函 数 第 七 章
函 数概 述函数定义的一般形式函数参数和函数值函数的调用函数的嵌套调用函数的递归调用数组作为函数参数局部变量和全局变量内部函数和外部函数null第七章 函 数学习要点:
掌握函数的定义方法
掌握函数的类型和返回值
掌握形式参数与实际参数、参数传递
掌握函数的正确调用,了解函数的递归调用
掌握局部变量和全局变量
变量的存储类型,作用域和生存期null第七章 函 数
7.1 概 述
一个 C 程序由一个主函数和若干个其它函数构成。
程序执行总是从主函数开始,由主函数调用其它函数,其它函数也可以互相调用。 nullmain ( )
{
……
fa( );
……
fb( );
……
}fa( )
{ ……
f1( );
……
}f1( )
{
……
}f3( )
{
……
}fb( )
{ f2( );
……
f3( );
……
}f2( )
{
……
}执行过程结构框图结构框图框图null 例 7.1
main ( )
{
printstar ( ) ;
print_message ( ) ;
printstar ( ) ;
}
printstar ( )
{
printf ( “ * * * * * * * * * * * * * * * * * \n ” ) ;
}
print_message ( )
{
printf ( “ How do you do ! \n ” ) ;
}运行过程示意null main ( )
{ ……
调用函数1 ;
……
调用函数2 ;
……
调用其它函数 ;
}函数1
{ …… }函数2
{ …… }C 程序的一般通用结构。 ……
其它函数null 说明:
1.一个源程序文件由一个或多个函数组成。以源程序文件为编译单位。
2. main( ) 函数由系统定义。
3. 函数定义 ,可以互相调用。在其它函
数中不能调用 main ( ) 函数。
4. 函数的种类
从用户来看: 标准函数(库函数)
用户自定义函数。
从形式来看: 无参函数, 有参函数。
不能嵌套函数定义严禁嵌套
main ( )
{
printstar ( ) ;
printstar ( )
{
printf (“ * * * * * * \n ” ) ;
}
}
因大括号位置不当引起函数定义上的嵌套.XX重点null 说明:
1.一个源程序文件由一个或多个函数组成。以源程序文件为编译单位。
2. main( ) 函数由系统定义。
3. 函数定义 ,可以互相调用。在其它函
数中不能调用 main ( ) 函数。
4. 函数的种类
从用户来看: 标准函数(库函数)
用户自定义函数。
从形式来看: 无参函数, 有参函数。
不能嵌套函数定义严禁嵌套
main ( )
{
printstar ( ) ;
printstar ( )
{
printf (“ * * * * * * \n ” ) ;
}
}
因大括号位置不当引起函数定义上的嵌套.重点null §7.2 函数定义的一般形式
一般格式:
存储类型 数据类型 函数名( 形式参数表列 )
{
声明部分
执行语句
}现代定义形式 传统定义形式 说明:
1. 数据类型指的是函数的返回值类型。
2. 可以定义和使用空函数空函数定义和使用 int max ( x , y )
int x , y ;
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}
int max (int x , int y )
{
int z ;
z = x > y ? x : y ;
return ( z ) ;
}
int max ( int x , int y )
{
int z ;
z = x > y ? x : y ;
return ( z ) ;
}重点
int max ( x , y )
int x , y ;
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}重点 说明:
1. 数据类型指的是函数的返回值类型。
2. 可以定义和使用空函数
格式: 数据类型 函数名 ( )
{
}
如: int dummy ( )
{
} 空函数的应用
应用:模块
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
过程中.
举例:
int dummy ( )
{
}重点null §7.2 函数定义的一般形式
一般格式:
存储类型 数据类型 函数名( 形式参数表列 )
{
声明部分
执行语句
}现代定义形式 传统定义形式 说明:
1. 数据类型指的是函数的返回值类型。
2. 可以定义和使用空函数空函数定义和使用 int max ( x , y )
int x , y ;
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}
int max (int x , int y )
{
int z ;
z = x > y ? x : y ;
return ( z ) ;
}
int max ( int x , int y )
{
int z ;
z = x > y ? x : y ;
return ( z ) ;
}重点
int max ( x , y )
int x , y ;
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}重点 说明:
1. 数据类型指的是函数的返回值类型。
2. 可以定义和使用空函数
格式: 数据类型 函数名 ( )
{
}
如: int dummy ( )
{
} 空函数的应用
应用:模块设计过程中.
举例:
int dummy ( )
{
}重点null §7.3 函数参数和函数值
一、形式参数和实际参数
例7.2
main ( )
{ int a , b, sc ;
scanf ( “ %d ,%d ” , &a ,&b) ;
s = sum ( a , b ) ;
printf ( “ sum = %d ” , s ) ;
}
int sum ( int x , int y )
{ int z ;
z = x+y ;
return ( z ) ;
}程序中 a , b 为实参; x , y 为形参演示函数参数传递演示重点main( )
{ int a, b, s;
a=2, b=3;
s= sum(a,b);
/* 其它处理 */
printf(“s=%d”,s);
} int sum(x , y)
int x, y;
{
int s;
/* 其它处理 */
s = x + y ;
return (s) ;
} a = 2b = 3S = 5null函数参数传递演示main( )
{ int a, b, s;
a=2, b=3;
s= sum(a,b);
/* 其它处理 */
printf(“s=%d”,s);
} int sum(x , y)
int x, y;
{
int s;
/* 其它处理 */
s = x + y ;
return (s) ;
} a = 2b = 3s = 5null关于形参与实参的说明:
1.形参变量在未出现函数调用时,并不占用内存单
元。调用时才为其分配内存单元,且调用结束后所
占用内存单元立即释放。
2. 实参可以是常量,变量(包括指针变量),数组名
( 包括数组元素 )或表达式等,但应有确定的值。
如: max ( 3 , a + b ) ;
3. 实参和形参在数据类型上应匹配。
4. 实参对形参的数据传递是“值传递”,即单向传递。
二者在内存中占据不同的内存单元。
如:
b a
x y232 3null1触发点1函数参数传递演示重点main( )
{ int a, b, s;
a=2, b=3;
s= sum(a,b);
/* 其它处理 */
printf(“s=%d”,s);
} int sum(x , y)
int x, y;
{
int s;
/* 其它处理 */
s = x + y ;
return (s) ;
} a = 2b = 3S = 5 在调用函数时,形参的值即使发生变化,也不会改变主调函数的实参值。
如:
main( )
{ int a = 3 , b = 4 ;
add ( a , b ) ;
printf ( “%d , %d \n” , a , b ) ;
}
add ( int x , int y )
{ x = x + 3 ;
y = y + 4 ;
} 输出: 3 , 45. 形参变量和实参变量可以同名。
main( )
{
int a = 3 , b = 4 ;
add ( a , b ) ;
printf (“%d ,%d \n”, a, b ) ;
}
add ( int a , int b )
{
a = a + 3 ;
b = b + 4 ;
} 343468ababab输出: 3 , 4null1触发点1函数参数传递演示重点main( )
{ int a, b, s;
a=2, b=3;
s= sum(a,b);
/* 其它处理 */
printf(“s=%d”,s);
} int sum(x , y)
int x, y;
{
int s;
/* 其它处理 */
s = x + y ;
return (s) ;
} a = 2b = 3S = 55. 形参变量和实参变量可以同名。
main( )
{
int a = 3 , b = 4 ;
add ( a , b ) ;
printf (“%d ,%d \n”, a, b ) ;
}
add ( int a , int b )
{
a = a + 3 ;
b = b + 4 ;
} 343468ababab输出: 3 , 4null变量或表达式 4. 若确定不需要带回返回值,则可以将函数定义
为:void 型。系统保证不使用函数的返回值。二、函数的返回值
格式: return ( ) ; 说明:
1. 一个函数中允许有多个 return 语句。 二、 函数的返回值
格式: return ( 变量或表达式 ) ;
如: int max ( int x , int y)
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}int max ( int x , int y )
{
return(x > y ? x : y ) ;
}说明:
1. 一个函数中允许有多个 return 语句。 例7.3 (p148)
main ( )
{ float a , b , c ;
scanf ( “%f ,%f”,&a,&b);
c = max(a,b) ;
printf(“max is =%d”, c );
} 2. 函数值的类型应和 return 语句中的变量(或表达式)的类型一致。 如不匹配,则以函数类型为准。对于数值型数据可以自动进行类型转换。如:int max(float x , float y )
{ float z ;
z = x > y ? x : y ;
return ( z ) ;
}输入: 1.5 , 2.5
输出: max is 22. 函数值的类型应和 return 语句中变量(或表达式)
的类型一致。 如不匹配,则以函数类型为准。
对于数值型数据可以自动进行类型转换。 3. 若被调函数中无 return 语句,则返回
一个不确定值。main ( )
{
int a , b , c ;
a = printstar ( ) ;
b = print_message ( ) ;
c = printstar ( ) ;
printf ( “%d , %d , %d \n” , a , b , c ) ;
}
...... 4. 若确定不需要带回返回值,则可以将函数定义
为:void 型。系统保证不使用函数的返回值。
如例7.1中可改为: void printstar ( )
{
…
}void print_message ( )
{
…
} 一个函数中允许有
多个 return 语句
int max ( int x , int y)
{
if ( x > y)
return ( x ) ;
else
return ( y ) ;
}多个 return 示例 函数返回值隐含的
自动类型转换
main ( )
{ float a , b , c ;
scanf ( “%f ,%f”,&a,&b);
c = max(a,b) ;
printf(“max is =%d”, c );
}
int max(float x , float y )
{ float z ;
z = x > y ? x : y ;
return ( z ) ;
}类型转换示例程序运行程序运行
输入: 1.5 , 2.5
输出: max is 2重点 无 return 语句
则返回一个不确定值
main ( )
{ int a , b;
a = printstar ( ) ; /* a,b不确定 */
b = print_message ( ) ;
printf ( “%d , %d \n” , a , b ) ;
}
printstar ( )
{
printf(“*******\n”);
}
printstar ( )
{
printf(“Hello world.\n”);
}返回不确定值示例 请找出有错的语句!
main ( )
{ int a , b;
a = printstar ( ) ;
b = print_message ( ) ;
printf ( “%d , %d \n” , a , b ) ;
}
void printstar ( )
{
printf(“*******\n”);
}
void printstar ( )
{
printf(“Hello world.\n”);
}请找错示例return返回
变量或表达式的值
int max ( int x , int y)
{ int z ;
z = x > y ? x : y ;
return ( z ) ; /* 返回变量的值 */
}
int min ( int x , int y )
{
return(x < y ? x : y ) ;
/* 返回表达式的值 */
}重点null4. 若确定不需要带回返回值,则可以将函数定义
为:void 型。系统保证不使用函数的返回值。二、函数的返回值
格式: return ( ) ; 说明:
1. 一个函数中允许有多个 return 语句。 二、 函数的返回值
格式: return ( 变量或表达式 ) ;
如: int max ( int x , int y)
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}int max ( int x , int y )
{
return(x > y ? x : y ) ;
}说明:
1. 一个函数中允许有多个 return 语句。 例7.3 (p148)
main ( )
{ float a , b , c ;
scanf ( “%f ,%f”,&a,&b);
c = max(a,b) ;
printf(“max is =%d”, c );
} 2. 函数值的类型应和 return 语句中的变量(或表达式)的类型一致。 如不匹配,则以函数类型为准。对于数值型数据可以自动进行类型转换。如:int max(float x , float y )
{ float z ;
z = x > y ? x : y ;
return ( z ) ;
}输入: 1.5 , 2.5
输出: max is 22. 函数值的类型应和 return 语句中变量(或表达式)
的类型一致。 如不匹配,则以函数类型为准。
对于数值型数据可以自动进行类型转换。 3. 若被调函数中无 return 语句,则返回一个
不确定值。main ( )
{
int a , b , c ;
a = printstar ( ) ;
b = print_message ( ) ;
c = printstar ( ) ;
printf ( “%d , %d , %d \n” , a , b , c ) ;
}
...... 4. 若确定不需要带回返回值,则可以将函数定义
为:void 型。系统保证不使用函数的返回值。
如例7.1中可改为: void printstar ( )
{
…
}void print_message ( )
{
…
} return返回
变量或表达式的值
int max ( int x , int y)
{ int z ;
z = x > y ? x : y ;
return ( z ) ;
}
int min ( int x , int y )
{
return(x < y ? x : y ) ;
}变量或表达式 示例 一个函数中允许有
多个 return 语句
int max ( int x , int y)
{
if ( x > y)
return ( x ) ;
else
return ( y ) ;
}多个 return 示例 函数返回值隐含的
自动类型转换
main ( )
{ float a , b , c ;
scanf ( “%f ,%f”,&a,&b);
c = max(a,b) ;
printf(“max is =%d”, c );
}
int max(float x , float y )
{ float z ;
z = x > y ? x : y ;
return ( z ) ;
}类型转换示例程序运行程序运行
输入: 1.5 , 2.5
输出: max is 2重点 无 return 语句
则返回一个不确定值
main ( )
{ int a , b;
a = printstar ( ) ; /* a,b不确定 */
b = print_message ( ) ;
printf ( “%d , %d \n” , a , b ) ;
}
printstar ( )
{
printf(“*******\n”);
}
printstar ( )
{
printf(“Hello world.\n”);
}返回一个不确定值示例 请找出有错的语句!
main ( )
{ int a , b;
a = printstar ( ) ;
b = print_message ( ) ;
printf ( “%d , %d \n” , a , b ) ;
}
void printstar ( )
{
printf(“*******\n”);
}
void printstar ( )
{
printf(“Hello world.\n”);
}请找错示例null§7.4 函数的调用
一、一般形式
格式: 函数名 ( 实参表列 )例 7.4 (p108)
main ( )
{
int i = 2 ;
int p ;
p = f ( i , ++i ) ;
printf ( “ %d ” , p ) ;
} int f ( int a , int b )
{ int c ;
if ( a > b )
c = 1 ;
else if ( a = = b )
c = 0 ;
else c = –1;
return ( c ) ;
} 结果?
可能是 –1 也可能是 0。因为:
按从左至右求值, 则为 f(2,3),即 (a
main( )
{ int a, b, s;
a=2, b=3;
clrscr( );
s= sum(a, b++);
/* 其它处理 */
printf(“s=%d”,s);
} int sum(x , y)
int x, y;
{
int s;
/* 其它处理 */
s = x + y ;
return (s) ;
} a = 2b = 3S = 5 函数的调用小结
1. 对无参函数,括号不能省。
2. 若有多个实参,则各参数之间应有逗号。
3. 实参和形参在个数和类型上要匹配。
4. 对实参表列的求值顺序不确定。
可从左至右,也可从右至左,视系统而定。
如 Turbo C 中就是按从右至左。总 结示例1. 极宽 1 main ( )
{ int i = 2 ;
int p ;
p = f ( i , ++i ) ;
printf ( “ %d ” , p ) ;
}
int f ( int a , int b )
{ int c ;
if ( a > b ) c = 1 ;
else if ( a = = b )
c = 0 ;
else c = –1;
return ( c ) ;
}重点
int yint x1. 极宽 1 结果: 可能是 –1 也可能是 0。
因为:
按从左至右求值, 则为 f(2,3),
即: (a b ) c = 1 ;
else if ( a = = b )
c = 0 ;
else c = –1;
return ( c ) ;
}实例结果: 可能是 –1 也可能是 0。
因为:
按从左至右求值, 则为 f(2,3),
即: (a b ) c = 1 ;
else if ( a = = b )
c = 0 ;
else c = –1;
return ( c ) ;
}实例结果: 可能是 –1 也可能是 0。
因为:
按从左至右求值, 则为 f(2,3),
即: (a b ) c = 1 ;
else if ( a = = b )
c = 0 ;
else c = –1;
return ( c ) ;
}重点
结果: 可能是 –1 也可能是 0。
因为:
按从左至右求值, 则为 f(2,3),
即: (a 0 )
{ y1 = y ;
x1 = x ;
}
else x2 = x ;
} while ( fabs ( y ) >= 0.0001 )