⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 函数1.txt

📁 绝对的primer的源代码 值得珍藏。第五版 外加清华讲义 
💻 TXT
字号:
主要内容 



1.函数的定义和调用
2.变量的存储类型
3.函数的递归调用
4.内联函数
5.重载函数
6.默认参数的函数
第八讲函数


刘志敏
北京大学信息科学技术学院 


liuzm@pku.edu.cn 

3
函数的层次关系
§程序:完成一定功能的指令集合
§例如:输入一整数,判断是否为素数
§输入数据
§判断是否为素数
§显示结果
§根据功能划分成模块(函数),降低程序复
杂度
§库函数
§自定义函数
main( )
输入数据判断素数显示结果.. 
将验证素数的程序改为函数形式 



#include <iostream> 
#include <cmath> 
using namespace std; 
bool checkprime( int ); // 函数声明 
void main() // 主函数 
{ int a=0; // 定义整型变量,初始化为 
0 


cout << "请输入一个整数: 
a="; 
cin>> a; // 键盘输入一个整数 
if ( checkprime(a) ) //函数调用 


cout << a << "是素数" << endl; 
else 
cout << a << "不是素数" << endl; 
} 4

定义函数 
checkprime


形式参数和实在参数


//验证素数 
bool checkprime( intb) 
形式参数
{ 

int k=0; 
for (k=2; k<=sqrt((double)b); k++) // 循环 
{ 


if (b%k == 0) 
{ 
return 0; //函数返回 
} 
} 
}
return 1; // b不能被 
k整除,则返回 
1 
5 

bool checkprime( int b ); //定义 


b 是形式参数 


q形式参数特点: 
|未被调用不占内存单元; 
|被调用后系统为其分配内存单元; 
|调用结束释放内存单元; 
|作用域限定在函数内,属于局部变量。

7
函数调用
被调用函数嵌套在if 语句中,a 是
实在参数
if ( checkPrime ( a ) ) 函数调用
checkPrime ( b ) 函数
形式参数
8
函数调用(续)
q实在参数是一个具有确定值的表达式,
调用函数时,要将实在参数赋给形式参数
调用时
17 17
实在参数a 形式参数b 
函数调用
被调用函数嵌套在if 语句中,a 是
实在参数
if ( checkPrime ( a ) ) 函数调用
checkPrime ( b ) 函数
形式参数
8
函数调用(续)
q实在参数是一个具有确定值的表达式,
调用函数时,要将实在参数赋给形式参数
调用时
17 17
实在参数a 形式参数b 
9
输入a 函数
if (checkPrime(a)) 
checkPrime( b ) 
执行if 语句for: i=2,3 … 
==1 ==0 
b%i==0 !=0
输出输出return 0 return 1 
a是质数a不是质数返回
函数调用(续)
函数调用(续) 



int main() 

{ 
int a=0; cout << "请输入一个整数: 
a="; 
cin >> a; 

if ( checkprime(a) ) 


bool checkprime(int b) 
{int k=0; 
for (k=2; k<=sqrt((double)b); k++) 
{ if (b%k == 0) return 0; } 
return 1; } 

cout << a << "是素数" << endl; 
else 

cout << a << "不是素数" << endl; }

函数定义 



函数声明 



q格式:函数返回值的类型函数名(类型名形参 
1,
类型名形参 
2,...) 
{函数内局部变量说明
函数执行部分 
return 语句; 
} 

§函数返回值的类型:无返回值的,为 
void;不规定
类型的,默认为整型 
§形式参数表: 
§函数体:函数的局部变量,只允许在本函数内使用 
§函数返回: 
return 语句: 
return(表达式);函数
返回到调用处 
11
q格式:函数返回值的类型函数名(类型名
形参1,类型名形参2,...); 
|功能:说明函数的形式 
|位于程序的前部,告知系统有自定义的函
|只有当调用函数位于函数定义之后时,才
可以不进行函数声明

函数调用 



函数调用(续) 


q格式:函数名(实在参数表); 
|有返回值的函数可在表达式中用; 
|无返回值的,作为独立的语句出现 
§要在程序前部说明函数的原型 
§系统提供的函数,其函数原型在头文件中 
§被调用函数与调用函数在程序中先后顺序无关 
§被调用函数与调用函数可位于不同的源程序文件
(演示) 
13

q主函数和其它函数均可调用函数(main函数
除外,函数可递归调用) 
q参数传递仅是数值传递,形式参数中数据改
变不影响实在参数中的数据,因形式参数与
实在参数占用不同存储单元 
15
参数传递仅是数值传递
例:调用函数swap (a,b),交换a,b的值
void swap(int a,int b); 
void main() 
{ int a=2,b=3; 
cout <<a<<b; 
swap(a,b); 
cout <<"after swap"<<a<<b<<endl; 
} 
void swap(int x,int y) 
{ int t=x; x=y; y=t; 
}
结果2 3 after swap 2 3 
q函数调用的结果不影响实参,因形参与实参占不同的内
存空间
2 
a 
3 
b 
2 
x 
3 
y 
main swap 
nk

问题
问题问题:
::编程求解 
编程求解编程求解.x 

1x=
q分析:


1、定义函数 
m 
sop(m,k) =. pow(i,k ) 

i=1 

|i=1,2,…… ,m 
|pow(i,k) 
|求和 
|返回和值
2、主程序输入n和k,调用sop(n,k),输出结


参考程序 



参考程序 



#include <iostream> 
#include <cmath> 
using namespace std; 
int sop(int m, int n); // 声明函数SOP 


void main() 


{ 
int n, k; 
cout<<“input n and k:”; 
cin>>n>>k; 
cout<< "Sum of " << k 
<< "from th powers of integers 1 to " 
<< n<< " is "<< sop(n,k)<< endl; 

} 

17

//函数功能:计算1,2,...,m的l次幂的和 
int sop(int m, int n) //m,n为形参 
{ int i, sum=0; // 初始化累加器 


for(i=1; i<=m; i++ ) 
sum=sum+pow ( i, n ); // 累加 
return sum; // 返回值 
} 

q注:函数调用,形参与实参是按位置结合
实参:n k
形参:m n 


程序举例1


程序举例1(续) 


例:先编写一函数 
prime(int n)判断n为素数否,然
后,在 
100以内检验Goodbach猜想的正确性
(即:一个大于 
4的偶数可分解为 
2个素数之和。) 


q分析: 
|函数prime(int n)判断n是否为素数 
|主程序读入一个偶数m(>=4),产生 
6到m之间的偶数 
i,找到奇数 
j,满足 
j、(i-j)均为素数的条件 
#include <cmath> 
#include <iostream> 
using namespace std; 
bool prime(int n); 


19

20void main (void) 
{ int i , j , m ; 
cout <<"输入偶数m\n"; 
cin >>m; 
if(m<6||m%2) { 
cout<<“输入错误”<<endl; 
return; } 
for(i=6; i<=m; i+=2){ 
for(j =3;j <=i/2; j+=2) 
if(prime(j)&&prime(i-j)) 
{ cout<<i<<“= ”<<j<<"+“; 
cout<<i-j<<endl; 
break; } 
} 
} 
bool prime(int n) 
{ int j, k=sqrt(n); 
for(j=2 ; j<k; j++) 
if(n%j==0) 
return (false) ; 
return (true) ; 
} 
程序举例2


程序举例2(续) 



例:寻找并输出11 
~999之间的数m,满足m,m 
2,m 
3均
为回文数(回文数是指其各位数字左右对称的整数,
如121、1331等) 


q分析: 
|主程序产生11 
~999之间的数m, 
|函数bool 
symm(int 
n)判断n是否为回文数 
21

#include <iostream> 
using namespace std; 
bool symm(int n); //声明函数symm 
void main(void) 


{ int m; 
for(m=11; m<1000; m++) 
if (symm(m)&&symm(m*m)&&symm(m*m*m)) 

{ 
cout <<"m="<<m<<"\tm*m="<<m*m; 
cout <<"\tm*m*m="<<m*m*m<<endl; 

} 
} 22

函数定义 



bool symm(int n) //函数定义 


{ int i, m; 
i=n ; 
m=0 ; 
while(i) { 
m=m*10+i%10; 
i=i/10 ; 
} //数字倒序(123 
— >321) 
return ( m==n ); 

} 

23

24
变量的存储类型
q程序的内存区域:
|代码区:存放程序代码
|全局数据区:全局数据、
静态数据
|堆区:程序的动态数据
|栈区:存放局部数据
q函数调用过程:
|建立被调函数的栈空间
|保护调用函数的运行状态
和返回地址
|传递参数
|将控制转交被调函数
代码区
全局数据区
堆区
栈区.. 
func(a);
调用函数.. 
......
被调函数.. 
func 

变量的存储类型(续) 



变量的存储类型(续) 



q格式:存储类型数据类型变量名表 
q存储类型:全局变量、局部变量、静态变量,外部
变量 
|全局变量:在函数体外定义的普通变量,在程序
的每个函数中都可访问。作用范围从说明地方起
直到程序结束。 
|局部变量:在函数体中定义的普通变量 
2局部:在定义范围内,可以访问它们;在定义
范围外,不可访问 
2动态:调用该函数时,系统才为函数分配存储
25

单元;退出该函数,则该存储单元由系统收回 


|静态变量:static,在编译时分配存储单元,随
程序开始而开始 
2局部静态变量:在定义函数内存取,前次调用
变量的结果可以代入下次调用的变量中 
2静态全局变量:限制此变量仅能在本程序文件
中使用,不能延伸到其它文件 
|外部变量:为使全局变量的作用域延伸到它其它
文件或定义位置前面的函数中,用 
extern类型名变量名表 


变量的存储类型:程序举例 



程序举例


#include <iostream> 
func(int a, int b) 

using namespace std; 
{ static int m=0, i=2; 

func(int a, int b); 
i+=m+1;

main() 
m=i+a+b; 

{ 
return m; 

int k=4, m=1, p; 
}


p=func(k,m); 
cout <<p<<endl; 结果: 
8


p=func(k,m); 
17


cout <<p<<endl; 
} 27

编写一程序显示Fibonacci数列的前n个数。 
Fibonacci数列定义为: 
f1=1 (n=1), f2=1 (n=2), fn= 
fn-1+fn-2 (n>2) 

#include <iostream> 
using namespace std; 
long fib(int x); 
void main( ) 
{ int i,n; 


cin >>n; 
for(i=1;i<=n;i ++) { 
cout << fib(i)<<"\t " ; 
} 
} 

程序举例 



//函数fib产生Fibonacci数列 
f1=1 , f2=1 ,fn= fn-1+fn-2 
long fib(int x) 
{ static long f1=1,f2=1; 


long f; 

if(x>2) { 
f=f1+f2; 
f1=f2; f2=f; 
return f; 


} 
else return 1; 
} 

29

程序举例


例:编写一个函数对数组中的数据按升序排
序;另一个函数在排序的数组中查找一个
数,返其位置。主程序输入数据,输出排序
结果;输入待查找的数,显示查找结果。 


q分析: 
int const len=6; 
int array[len]; 
bubble();对数组中的数据按升序排序 
find(int num);在数组中查找 
num,返回位置



函数之间的数据传递 



函数bubble()对数组中的数据按升序排序 



int const len=6; 
int array[len]; //定义全局变量 
void bubble(); //函数声明 
int find(int num); //函数声明 
void main(void) 
{ int i,num; 


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

cin>>array[i]; //53 2 6 4 31 12 
bubble(); //对数组array中的数,排序 
for (i=0; i<len; i++) cout <<array[i]<<“"; 
cout <<"\n"; 
cin>>num; //输入要查找的数 
cout<<"The position of "<<num<<" is 


"<<find(num)<<endl; 
} 31

void bubble() 
{ int i,temp, sorted, j; 

for(j=1; j<len; j++){ 
sorted = 1; 
for(i=0; i<len-j; i++){ 


if(array[i]>array[i+1]) { 
temp = array[i]; array[i] = array[i+1]; 

array[i+1] = temp; sorted = 0; } 
} 
if(sorted) 


break; //若本轮没有交换,则提前完成排序 
} 
} 32

函数find(int num)查找num在数组中位置 



改进的程序: 数组作为函数的形参 



int find(int num) 
{ int mid, low=0, high=len; 


while(low<=high){ 
mid = (low+high)/2; 
if(num==array[mid]) 


return mid; 
else if(num<array[mid]) high = mid-1; 


elselow = mid+1; 
} 
if(num!=array[mid]) 


return -1; 
}
问题:用全局变量 
array,增加了函数之间的关联性(命名、数

据更新),降低了模块之间的独立性 
33

#include <iostream> 
using namespace std; 
void bubble(int a[], int len); 
int find(int a[], int len, int num); 
void main(void) 
{ int const len=6; 


int array[len],i,num; 
for (i=0;i<len;i++) 


cin>>array[i]; //53,2,6,4,31,12 
bubble( array, len); 
for (i=0;i<len;i++) cout<<array[i]<<" "; 
cout <<"\n"; cin>>num; 
cout<<“The position of ”<<num; 
cout<<" is "<<find(array,len,num)<<endl; 


} 34

函数bubble:采用冒泡法排序 



函数find(int num)查找num在数组a中位置 



void bubble(int a[], int size) int find(int a[],int len, int num) 
{ int i,temp, sorted, j; { 
for(j=1; j<size; j++){ int mid, low=0, high=len; 
sorted = 1; while(low <=high){ 
for(i=0; i<size-j; i++){ mid = (low+high)/2; 
if(a[i]>a[i+1]) { if(num ==a[mid]) 
temp = a[i]; a[i] = a[i+1]; a[i+1] = temp; return mid; 
sorted = 0; } else if(num <a[mid]) high = mid-1; 
} else low = mid+1; 
if(sorted) } 
break; if(num !=a[mid]) 
} return -1; 
} 35} 36


函数之间的数据传递 



几个通知 



q调用函数向被调用函数传递数据 
q周五:计算概论部分期中考试, 
1小时 
|实在参数向形式参数的单向传递 
q11月17日上午10:00--12:00,在软件机
|按位置结合 
房,程序设计上机考 
q被调用函数向调用函数的数据传递 
|机考期间,若有外部的 
IP用学生帐号登陆,系统
有记录,按作弊处理。 
|函数的返回值 
|禁用网络作弊:邮件、 
QQ 
|形式参数为数组类型:双向传递 
q答疑 
q全局变量 
|时间:周二 
/五晚: 
7:00-9:00 
q要保持局部变量的值 
|参加者:认为需要帮助的
|定义静态变量: 
static 
3738



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -