7函数
函数
模块化。C++的基本程序单位。
所有在函数体中说明的变量都是局部变量(仅在定义的函数中有效)
参数
函数间传递信息
局部变量
优点
分而治之(有利于程序开发)
避免代码重复,软件重用(重用已有的函数来构造新的程序)
抽象-隐蔽内部的细节
示例:寻找三个数中最大值和最小值
#include <stdio.h>
int maximum( int,int,int );/*function prototype*/
int main()
{ int a, b, c;
printf( "Enter three integers: " );
scanf( "%d%d%d", &a, &b, &c );
//实参
printf( "Maximum is: %d\n", maximum(a,b,c));
return 0;
}
/* Function maximum definition */
//形参
int maximum( int x, int y, int z )
{
int max = x;
if ( y > max )
max = y;
if ( z > max )
max = z;
return max;
}
函数定义
函数定义格式
函数性质及返回值类型说明 函数名标识符( 形式参数定义 )
{
语句序列 /* 0~n个语句 ,语句前可带 标号标识符 :*/
}
返回值类型说明 :省缺是 int。void - 函数没有返回值
形式参数定义 :用逗号分隔的参数说明列表,说明了每个形式参数的名字(可加默认值)、类型以及函数调用时的参数传递方式。若无参数,则为空或void
{语句序列 } 构成函数体,语句序列中所包含的return语句( return;或 return 表达式; 其中最后的return;可省略) 用于从函数中返回。
函数原型
1.函数名
2.参数类型: 函数的各形式参数类型,所带参数名被忽略,可定义默认参数(不能重复定义)
3.返回值类型:函数返回值的数据类型 (省缺是 int)
4.原型仅在函数先调用后定义或调用和定义不在同一个文件时使用
函数调用:传值和传引用
调用函数时一般要传递参数
传值
1.把实在参数的值传递给函数的形式参数
2.函数的执行对实在参数没有影响
3.函数不需要修改实在参数时,用传值方式(避免意外改变)
传引用
1.把实在参数的地址传递给函数的形式参数
2.函数的执行可以改变实在参数
3.函数确实需要修改实在参数时,用传引用方式
4.要求实在参数有“左值性质”
变量的存储类别和作用域
auto,register,extern,static
存储期:在内存中的存在期
作用域:在程序中可以引用该变量的区域
连接:变量在多个源文件中能够被识别
“最近嵌套原则”(如何处理同名变量)
自动存储
在定义的块中建立、存在和撤销
auto: 局部变量(包括形式参数)的省缺说明符
auto double x, y;
register: 为变量分配高速寄存器
只能用于auto变量
register int counter = 1;
静态存储
变量在整个程序运行期间都存在,省缺值为0
static: 可以用于函数中的局部变量
1.函数运行结束,变量的值依然存在
2.只能在定义变量的函数中访问该变量
3.static还可用于全局变量和函数头的定义
extern: 全局变量和函数性质的省缺定义,在所有的函数中都能访问
作用域:文件作用域 、函数作用域 、块作用域 、函数原型作用域
文件作用域
1.在函数外面定义的标识符,能够被从标识符说明到文件结束之间的所有函数引用
2.全局变量、函数定义、函数原型
如:
#include <stdio.h>
int x = 1; /* global variable */
int main()
{
...
}
函数作用域
1.只能在函数体中引用
2.标号是唯一具有函数作用域的标识符
如:
#include <stdio.h>
int main()
{
...
goto L1;
...
L1: printf(...);
...
}
块作用域
1.在程序块中声明的标识符具有块作用域
2.块作用域开始于声明处,结束于程序块的右花括号(有例外)
3.函数的形式参数、函数的局部变量、在复合语句中声明的变量具有块作用域
4.如果外层块和内层块有相同名字的变量,外层说明会被内层说明屏蔽(最近嵌套原则)
注意:for、while等语句中声明的变量
示例
#include <stdio.h>
int main()
{
int x = 5;
printf("local x is %d\n", x );
{ /* start new scope */
int x = 7;
printf( "x in inner scope is %d\n",
x );
}
printf("local x is %d\n", x );
return 0;
}
函数原型作用域
1.函数原型参数表中的参数名标识符具有函数原型作用域
2.函数原型中的参数名可以省略,也可以在程序的其它地方再次定义
如:
void a( int pram1,int param2);
void b( float pram1);
int main()
{ int pram1;
...
}
示例
#include <stdio.h>
void a( void ); /* function prototype */
void b( void ); /* function prototype */
void c( void ); /* function prototype */
int x = 1; /* global variable */
int main()
{int x=5;
a();/* a has auto local x */
b();/* b has static local x */
c();/* c uses global x */
a();/* a reinitializes auto local x */
b();/* static local x retains its
previous value */
c();/* global x also retains its value */
printf( "local x in main is %d\n", x );
return 0;
}
void a( void )
{int x = 25;
printf( "local x in a is %d \n", x );
++x;
printf( "local x in a is %d \n", x );
}
void b( void )
{static int x = 50;
printf("local static x is %d \n", x );
++x;
printf( "local static x is %d \n", x );
}
void c( void )
{printf("global x is %d \n",x );
x *= 10;
printf( "global x is %d \n",x );
}
递归函数
1.函数直接或间接调用自己
2.通过解决简单的问题,达到解决整个问题的目的
示例
#include <stdio.h>
long factorial( int );
int main()
{ int i;
for ( i = 1; i <= 10; i++ )
printf("%2d,%ld\n",i,factorial(i));
return 0;
}
long factorial( int number )
{
if ( number <= 1 )
return 1;
else
return (number*factorial(number-1));
/*return (factorial(number-1)*number);*/
}

递归算法的基本思想
将一个问题向下分解为具有同样的解决方法但规模不断缩小的子问题,不断分解,直到分解出的子问题有一个已知的解。
递归算法具有两个基本特征:
1.递推归纳:归纳得出递推公式,问题规模由函数的参数表示
2. 递归终止(出口):结束递归,逐层返回
递归与迭代
重复
迭代:明显的循环
递归:反复的函数调用
终止
迭代: 循环条件不满足
递归: 执行到递归基础
二者都有可能导致无限循环
权衡
执行效率与软件结构,适用性
示例一:
有5人坐在一起,问第5个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第3个人,他说比第2个人大2岁。问第2个人,说比第1个人大2岁。最后问第1个人,他说是10岁。请问第5个人多大?


程序实现
#include <stdio.h>
age (int n) /*求年龄的递归函数*/
{
int c; /*c用来存放函数的返回值*/
if (n==1) c=10;
else c=age(n-1)+2;
return (c);
}
void main ( )
{ printf (“%d”,age(5));
}

例子二:求Fibonacci 数列
Fibonacci 数列: 0, 1, 1, 2, 3, 5, 8...每个元素是前面两个元素的和。
fib(n) = fib(n-1) + fib(n-2)

#include <stdio.h>
long fibonacci( long );
int main()
{long result, number;
printf( "Enter an integer: " );
scanf( "%ld", &number );
result = fibonacci( number );
printf( "Fibonacci( %ld ) = %ld\n",
number, result );
return 0;
}
/* Recursive function of fibonacci */
long fibonacci( long n )
{ if ( n == 0 || n == 1 )
return n;
else
return fibonacci( n - 1 ) +
fibonacci( n - 2 );
}
示例三:汉诺塔
void moveDisks(int diskNum, char sourcePole, char targetPole, char midPole)
{if (diskNum == 1)
printf(“%c -> %c”, sourcePole, targetPole);
else
{moveDisks(diskNum-1, sourcePole,midPole,targetPole);
printf(“%c -> %c”,sourcePole,targetPole);
moveDisks(diskNum-1,midPole,targetPole,sourcePole);
}
}
int main()
{
moveDisks(3, ‘1’, ‘3’, ‘2’);
return 0;
}
                    
                
                
            
        
浙公网安备 33010602011771号