截图
简介
这是一个关于C++程序设计基础PPT,这节课主要是了解函数性质( Function Character ) 指针参数 ( Pointer Parameters ) 栈机制 ( Stack Mechanism ) 函数指针 ( Function Pointers ) main参数 ( The main’s Parameters ) 递归函数 ( Recursive Functions ) 函数重载 ( Function Overload ) 。函数(function)表示每个输入值对应唯一输出值的一种对应关系。这种关系使一个集合里的每一个元素对应到另一个(可能相同的)集合里的唯一元素。函数f中对应输入值的输出值x的标准符号为f(x)。包含某个函数所有的输入值的集合被称作这个函数的定义域,包含所有的输出值的集合被称作值域。若先定义映射的概念,可以简单定义函数为,定义在非空数集之间的映射称为函数,欢迎点击下载C++程序设计基础PPT哦。
C++程序设计基础PPT是由红软PPT免费下载网推荐的一款数学课件PPT类型的PowerPoint.
C++程序设计教程(第二版)
第五章 函数机制
Chapter 5 Function Mechanism
第五章内容
函数
C++的函数是完成既定任务的功能(过程)体,它涵盖了数学函数和一般过程.所以基于过程编程本质上就是基于函数编程
函数机制
一是指程序运行过程中对函数调用的数据管理和处理过程
二是指编程中函数的使用规范.它包括函数参数的属性和传递规则,函数返回类型的匹配与审查,函数名字的识别原则,函数体效率的选择,函数体中数据的访问权限等
练习:采用函数调用方式,输出下列欢迎界面。
练习:用函数调用的方式求解两个数的差。
void main() {
int max(int x,int y) ;
int a,b,c;
cin<>>a>>b;
c=max(a,b); //a,b为实参
cout<<"The max is “<<c;
}
int max(int x,int y) //x,y 为形参
{int z;
if (x>y) z=x;
else z=y;
return(z);
}
形参与实参、函数名与返回值之间的关系:
说明:
(1)形参在函数被调用前不占内存; 函数调用时为形参分配内存;调用结束,释放内存。
(2)实参可以是常量、变量或表达式,但必须有确定的值。
(3)在被定义的函数中,必须指定形参的类型
(4)形参与实参类型一致,个数相同
(5)实参对形参进行单向“值传递” ,不能把形参的值反向地传送给实参。形参与实参占用不同的内存单元.
建议:
1)定义函数时都要指定函数类型。
2)定义函数时指定的函数类型与return 返回值的类型一致。
3)对于不带回值的函数,用void 定义为空类型,此时函数体内不能出现return语句。
在以下情况下可省去在主调函数中对被调函数声明。
1) 函数定义出现在函数调用之前
1. 函数性质 ( Function Character )
函数:对输入参数负责,埋头做自己的事,最终返回结果
函数组织:通过在函数中进行函数调用来扩展运行的规模,层层叠叠的函数构成树结构
做法:将若干个函数组织成文件,又将若干个文件构成程序的办法来进行编程分工
跨越数学函数的C++函数,有四种形态
返回类型 func ( 参数列表 ) ;
返回类型 func ( ) ;
void func ( 参数列表 ) ;
void func ( ) ;
黑盒原则:函数使用者应关注性能,而少去左右实现细节
int cost ( int n, int m ) {
return n*10; // 运输n次m斤
}
int cost ( int n, int m ) {
return m*10; // 运输m次n斤
}
// 选择下一个最好的
int cost ( int n, int m ) {
return (n>m? m:n)*10; // 保证运输次数最少
}
参数传递:形参是对实参的克隆,克隆必须遵守类型匹配规则
void f(Type a); //a为形参
void g(){
Type x;
f(x); //x为实参
}
2. 指针参数 ( Pointer Parameters )
传递指针:指针参数也是值传递的,指针值的真正用途是进行数据间访,以达到操作数据块(大小由之)的目的。
传递引用:引用参数本质上也是值传递的,它表现为名字传递,即以形参的名字来代替实参名字.如果实参不是实体名而是表达式,那么其表达式所对应的临时实体取名为形参,并要求其为常量引用
意义:指针和引用参数的存在,使函数实际上可以访问非局部的数据区,函数的黑盒性便名存实亡.但这并非一定坏事,指针是一把双刃剑,或灵巧或邪恶.引用是为了防范指针非安全的无意操作
void swap(int *p1, int *p2);
void main()
{
int x1=100,x2=200; int *pp1,*pp2;
pp1=&x1;pp2=&x2;
cout<<x1<<x2);
swap(pp1,pp2);
cout<<x1<<x2);
}
void swap (int *p1, int *p2) {
int temp;
temp=*p1;
*p1=*p2;
*p2=temp;
}
传递指针须附带传递单位数据的个数
3. 栈机制 ( Stack Mechanism )
运行时内存布局
栈区的演示程序(函数的嵌套调用)
int funcA( int x,int y);
void funcB( int & s);
int main(){
int a=6,b=12;
a=funcA(a,b);
}
int funcA(int x, int y){
int n=5;
funcB(n);
return;
}
未初始化局部数据的不确定性
#include<iostream>
void f(){
int b; // 未初始化
std::cout<<”B=>”<<b<<“\n”;
}//-------------------------
int main(){
int a; // 未初始化
std::cout<<”A=>”<<a<<“\n”;
f();
}//-------------------------
// 8804248
// 2788048
4. 函数指针 ( Function Pointers )
函数类型:函数类型因参数类型、个数和排列顺序的不同而不同,也因返回类型的不同而不同.
函数指针:指向代码区中函数体代码的指针.不同的函数类型,其函数指针也不同
用法:函数指针经常用作函数参数,以传递连函数本身都不知道的处理过程(函数)
4.1不同的函数指针,不能相互赋值
int g(int);
int (*gp)(int) = g;
void f();
void (*fp)();
fp = f;
gp = fp; // error
指定函数指针类型,定义函数指针数组
typedef void (*MenuFun)();
void f1(){ cout<<"good!\n"; }
void f2(){ cout<<"better!\n"; }
void f3(){ cout<<"best!\n"; }
MenuFun fun[]={f1,f2,f3};
6. 递归函数 ( Recursive Functions )
形式上:一个正在执行的函数调用了自身(直接递归).或者,一个函数调用了另一个函数,而另一个函数却调用了本函数(间接递归)
本质上:程序在运行中调用了相同代码实体的函数,却在函数栈中重新复制了该函数的整套数据,由于每套数据中的参数也许不同,导致了计算条件发生变化,使得函数得以逐步逼近终极目标而运行
6.1 现实问题
猴子第一天摘了若干个桃子,当即吃了一半,还不过瘾,又多吃了一个;第二天早上有将剩下的桃子吃了一半多一个。以后每天如此,直到第十天想再吃时,只剩下一个桃子了,问猴子摘了多少个桃子呢?
求N!
一个球从100米高度落下,每次落地后反弹原高度的一半,再落下。问第10次落地后,共经过的距离为多少米?第10次落地后的反弹的高度?
6.2 分析递归的实质
递归的两个组成部分:
回推
递推
递归存在的条件:
递归结束的条件
递归调用的参数应该是逐步逼近结束条件
6.3 消除递归
int f( int n ){
for( i=1,s=1;i<=n;i++)
s=s*I;
return s;
}
6.4 递归的意义
可读性
效率
7. 1 函数重载 ( Function Overload )
定义:一组概念相同,处理对象(参数)不同的过程,出于方便编程的目的,用同一个函数名字来命名的技术称为函数重载
意义;
解决函数的命名的问题
例子:求x绝对值函数
int abs( int x )
double abs( double x )
#include< iostream.h>
int abs( int a ){
return (a>0)?a:-a;
}
double abs( double a){
return (a>0)?a:-a;
}
void main(){
cout<<abs(-10)<<endl;
cout<<abs(-12.23)<<endl;
}
7.2重载函数的匹配(编译)
规则
寻找严格匹配的函数
寻找相容的函数
例子
重载是不同的函数,以参数的类型,个数和顺序来分辨
void print(double);
void print(int);
void func(){
print(1); // void print(int);
print(1.0); // void print(double);
print(‘a’); // void print(int);
print(3.1415f); // void pirnt(double);
}
7.3参数默认:
一个函数,既可以严谨和地道的调用,也可以省略实参,使用默认的参数值调用,达到此种方便编程目的的技术称为参数默认
using namespace std;
void delay(int a = 2); // 函数声明时
int main(){
delay(); // 默认延迟2秒
delay(2); // 延迟2秒
delay(5); // 延迟5秒
}
void delay(int a){ // 函数定义时
int sum=0;
for(int i=1; i<=a; ++i)
for(int j=1; j<3500; ++j)
for(int k=1; k<100000; ++k) sum++;
}
默认参数的规则
默认参数的值只能在声明中
void point(int =3,int =4)//声明时
void point( int x,int y){ //定义时
cout<<x<<y<<endl;
}
默认参数的值只能从后往前设置。
默认参数的值设定不能出尔反尔。
void func( int a=1);
void func(int a=2);
7.4无名参数
例如:
void point( int a ,int ){//定义时,第二个形参省略)
cout<<a<<endl;
}
void main(){
print(12,15);//调用时必需有第二个实参
}
7.3重载和参数默认的选择
它们都是通过参数的变化来分辨处理任务的不同.如果参数决定了不同的处理过程,则应重载,否则参数默认更简捷一些
8. main参数 ( The main’s Parameters )
程序运行:操作系统读入命令以启动程序
重定向命令:操作系统读入命令后,识别并自我消化的参数
main函数参数:操作系统读入命令后,不能识别参数,将其直接传递给所启动的程序
命令重定向
// f0509.cpp
#include<iostream>
using namespace std;
int main(){
for(int a,b; cin>>a>>b;) cout<<a+b<<”\n”;
}
main函数参数
// f0510.cpp,标准的输入输出设备
#include<iostream>
using anmespace std;
int main(int argc, char** argv)
{
for(int i=0; i<argc; ++i)
cout<<argv[i]<<endl;
}
//从命令提示符开始
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
void main( int argc, char ** argv){
if(argc!=3) cout<< “ print error!”;
else{
ifstream fin(argv[1]);
ofstream fout(argv[2]);
for(string str;getline(fin,str);)
out<<str<<endl;
}
}
展开