第七章 函数
2020-02-24 10:38:46 7 举报
AI智能生成
C++ plus
作者其他创作
大纲/内容
函数和结构
结构与数组区别
可以按普通变量一样处理结构
结构是按值传递
缺点:数据大,复制结构增加内存要求,降低系统运行速度
结构名只是结构名称,不是地址。取地址要用&
数据可以被返回
单变量函数参数传递
按值传递
适用
结构比较小
格式
(struct )student std;调用:sum(std);定义:(struct) student sum( (struct) student std )
引用
std.name
按地址传递
(struct )student std;调用:sum(&std);定义:(struct) student sum( (struct) student *ptd )
ptd->name
(*ptd).name
其他
想返回结构指针,可以不用返回,在main()中定义一个结构,传递地址过去,存储结果。//不利于模块化??
函数和string对象
单变量(对象)
代码
#include<iostream>#include<string>using namespace std;//指令一定要在这里,不然下面的原型不能用 void show_str(string str1);int main(){\t string str1=\"i am a apple\"; show_str(str1); cout<<str1; return 0;} void show_str(string str1){span class=\"Apple-tab-span\" style=\"white-space:pre\
地址传递??
#include<iostream>#include<string>using namespace std;//指令一定要在这里,不然下面的原型不能用 void show_str(string *);int main(){\t string str1; show_str(&str1); cout<<str1; return 0;} void show_str(string *pstr1){span class=\"Apple-tab-span\" style=\"white-space:pre\
注意
名称string位于std中函数原型要void sum(std::string )
函数和array对象
前言
类对象基于结构,结构编程方面的考虑因素也适用于类对象
可以按值传递,也可以传递指针
说明
array位于名称空间std中
存在效率不高问题
在函数中,da[1]...
(*pa)[i]
当成结构,因为pa-> 不可以,所以只有这种?*(pa+i)可以吗???不可以,不要弄混了
其它
递归
c++不允许main() 调用自己c允许
原理
void recurs(argument){ statements1 if(test) recurs(arguments) statement2}
每个递归调用都创建自己的一套变量,如果要递归5次,每次传递都是n,5次调用后,将有5个独立的n,内存地址都不一样
例子
subdivide调用自己两次,一次针对左,一次针对右。//有点难想出。
subdivide调用次数呈几何数增长,调用依次导致两次调用,调用两次导致4词调用,一共调用64次,所以可以填充64个元素
函数指针
函数有地址,函数地址是存储其机器语言代码的内存开始地址
好处
允许在不同时间传递不同函数的地址,可以在不同的时间使用不同的函数
获取函数地址
函数头是其地址,think() 是函数。
函数作为参数的调用格式
process(think)
区分 process(think())
声明函数指针
double pam(int );double (*fp)(int);fp=pam;/doubel (*fp)(int)=pam
返回类型,参数个数,类型都必须与原函数相同
一般不在调用函数中直接声明函数指针,在传递过程中的被调函数定义中声明函数指针(如下)
*fp = pam,注意声明的时候有(),没有的意思是返回double *
这样子,说明estinmate 接受函数参数时,没有执行函数,只是接收。如果要执行函数,在es函数中在用 *fp 来调用
使用指针调用函数
在estimate使用 (*fp)当pamdouble x=(*fp)(5)
在C++中,可以直接用fp当作函数名double x=fp(5);
const 用于函数返回值
pre class=\"cjk\" align=\"LEFT\" name=\"code\" style=\
深入探讨
三者都是一样的
单函数指针
声明
父节点
初始化
自动声明
auto p1= f1;
用指针调用函数
函数指针数组
自动
但是可以声明同样类型的数组auto pb = pa;
调用
指向 函数指针数组 的指针
子主题
auto pc= &pa;
使用typedf简化
自己
简化
不容易犯错,容易理解
auto p1=f1;
容易错
停止整数数组录入的方法
哨兵数字 -1
输入英文使输入格式错误
输入n 个数组的数
先设置足够大的数N ,连续录入,若条件不符合则跳出。
停止字符串录入的方法
一行一行录入
cin>>str
一个一个录入
while((ch=cin.get()) != '\')
while( cin.get(ch) )
ctrl + z enter才结束。
int ch;while( (ch=cin.get()) != EOF; )
哨兵字符作为结束
函数
基本知识
使用函数步骤
原型
方式
头文件
一般是系统的函数用头文件。当然,也可以写。
写原型
原型语法
原型中可以有变量名,也可以没有,变量名相当于占位符
有时提供变量名,可以助于容易理解 。特别是两个类型一样时,当然也要变量名有意义。
需要原型原因
原型描述了函数到编译器的接口,将函数返回值的类型以及参数的类型和数量告诉编译器
原型功能
编译器正确处理函数返回值
编译器检查使用的参数数目是否正确
检查参数类型是否正确。不正确转换成正确的类型
编译阶段进行原型化——静态类型检查。可以捕获许多在运行阶段难以捕获的错误
C++中,不指定参数列表时,使用... ,表示将在后面定义参数列表。void say_bye(...);
定义
有返回值
返回值结果的类型应该是 typename类型或者可以被转换为typename 类型
返回值的类型 ,不能是数组,可以是其他任何类型——整数、浮点数、指针、结构、对象数组可以作为结构或对象返回
无返回值
函数返回原理
书p204
函数参数和按值传递
使用副本,不影响原来的数据
参数
类型
实参
形参
参量
形参和局部变量区别
形参从调用 的函数获取自己的值,局变从函数中获取自己的值
其它
cin>>number>>picks
(10*9)/(2*1) 和 (10/2)*9/1
当数很大时,前者的中间值(90)比后者大,可能会超出最大浮点数
函数和数组
定义的时候,[]可以不带任何值,表明可以将任何长度的数组传递给该函数
这个时候尽量要有n??
array虽然看上去是数组,实际上是指针。可以将array看作是数组那样使用
int array[] 替代了int *array,当用于函数头或函数原型时,两者是相同的
也就是可以进行array++运算 ??是的。
sizeof array 也是存储地址字节的长度,不是数组长度,这也是必须显式传递数组长度的原因,指针没有指出数组的长度
array[i] == *(array + i)&array[i] == array + i
可以改变数组的起始位置
为将数组类型和长度告诉数组处理函数,最好通过两个不同的参数传递它们:
数组参数的传递方式
地址传递,不是值传递
变量——使用该变量的副本数组——使用原来的数组
节省复制整个数组所需要的时间
坏处
破坏原来的数据
解决办法 const
const保护数组
表明指针ar指向的是常量数据,不能使用ar 修改数据
*(ar)=0;//invaildar++ //vaild
函数处理数组(元素区间法)
方法
传统:数组的数据类型,起始位置,元素数量 给函数
制定元素区间,传递两个指针,一个指向开头,一个指向指针标识数组的尾部。
标识数组尾部的参数是指向最后一个元素后面的指针
元素引用
数组表示法
指针法
for(pt=begin ; pt != end ; pt++)
为什么不直接for(; begin !=end; begin ++)//??
应用
指向不通区间
指针和const
指向的值不能改变
含义
指针指向一个常量对象
int age=39;const int *pt = &age;
const变量和指针对应关系
const变量const指针
const int age = 39;const int *pt =&age; //valid
*pt+=1 ;age+=1; //invalid
const变量常规指针
const int age = 30;int *pt =&age //invalid
非要这样做,可以通过强制类型转换突破现象//??怎么样?
指向指针的指针情况情况:
const int **pp2;int *p1;pp2=&p1 //invalid
原因
const int **pp2;int *p1;const int n=13;pp2=&p1; *pp2=&n;*p1=10;//造成混乱
const int **pp2;const int *p1;pp2=&p1;//valid;
总结
如果数据类型不是指针,非const数据,const 数据地址——const指针非const数据地址 ——非const指针
指向的位置不能改变
指针本身声明为常量
int age = 39;int * const pt = &ageconst int * pt =&age//对比
关系
const int age = 39;int * const pt = &age;
函数和二维数组
int data[3][4] = {...}data ——数组名,该数组有3个元素。每个元素是指向由4个int组成的数组。
感觉没什么区别:data +1 的区别。
a[][];&a=0x6bfee0a=0x6bfee0&a[0]=0x6bfee0a[0]=0x6bfee0&a[0][0]=0x6bfee0//含义不一样。不能理解
p style=\
int data[3]data ——数组名,指向第一个元素。
说明
(*ar2)[4]表示一个指向 由4个元素组成的数组 的指针,ar2是指向指针的指针
指针类型 指定了列数,sum()函数只接受由4列组成的数组。长度变量指定了行数,所以sum()对数组的行数没有限制
数组法
直接把ar2看作是二维数组
ar2[i][j]
*(*( ar2 + i ) +j )
ar2
ar2+r
*(ar2 + r)
*(ar2 +r ) + c
函数和c-风格字符串
函数调用
参数表示
字符串表示方式
char数组
char good[15]={};strlen(good)
“”括起的常量
strlen(\"i am a \")
char字符串指针
char *ptr=“i am a”;strlen(ptr);
表示方式都是char*类型,所以都可以作为函数参数
长度
不需要长度作为参数传递给函数
可用\看结尾
int sum(char *str);
int sum(char str[])
函数中的元素引用
就算 int sum(char *str);也可以
返回c-风格字符串的函数
p227
一定要使用new来创建。
用const防止被修改
自由主题
0 条评论
回复 删除
下一页