函数
1:函数是先定义后使用的。
2:函数定义于主函数之外,分配有储存空间,独立于其他函数的形式。
3:函数的一般形式:
4:类型标识符函数名(形参表)———形参表可以为空,但括号不能省略
{
函数语句——函数的主体,可以为空,但花括号不能省略
}
例:int f(int x)——x为形参
形参只是一个占位符,标志着在形参出现的位置应该有一个什么类型的数据。
5:函数调用
函数名(实参表)——实参表与形参表相对应
实参可以是常量、变量,还可以是表达式,但如果实参中存在变量,在函数调用时,变量应是有确定值的。
6:函数程序的典型结构:
1) :预处理指令
符号常量定义
函数声明
2) :主函数
3) :函数定义
为了避免函数在定义前被调用,在调用前声明函数的原型。
类型标识符 函数名(形参表);——已分号结束
7:参数传递
类型名&引用名=变量名
定义引用时一定要将其初始化成引用某个变量
引用只能引用变量,不能引用常量和表达式
8:指针变量
其内容为地址(储存位置)的变量,简称指针。它所指向的地址上存放的变量称为目标变量。
指针变量的一般形式:
类型标识符 *变量名 ——*为指针说明符
指针变量也可赋值: Int *i_point;
一个指针变量只能指向同一类型的变量。即整形指针变量只能指向整型数据的地址,而不能存放其他数据的地址。
& 正常操作表示:取地址; 说明变量时代表:引用变量。
说明变量时前加 * 代表:定义指针变量;正常语句中代表:取指针变量所指的目标内容。
不能对未赋值的指针变量做“取内容”运算。
9:指针的运算
++(--)表示指向下一个(或上一个)同种类型的数据。
10:函数的参数可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。
指针变量作为函数参数与变量本身做函数不同,变量做函数传递的是具体值,而指针变量做函数传递的是内存地址。
函数调用不能改变实参指针变量的值,但可以改变实参指针变量所指向的变量的值。
11:函数调用的三种传递方式:按值传递,地址传递,引用传递。
1):按值传递:
过程:首先计算出实参表达式的值,给对应的形参变量分配一个储存空间;
把已求出的实参表达式的值——存入到形参变量分配的存储空间中,成为形参变量的初值,供被调用函数执行时使用。
被调用函数本身不对实参进行操作!
2):地址传递
如果在函数定义是将形参说名成指针,调用函数是就需要指定地址值的形参。这时函数的传递方式就是按地址传递方式传递。
按值传递形参指针和实参指针指向同一地址。因此,被调用函数中对形参指针所指向的地址中内容的任何改变都会影响到实参。
3):引用传递
如果以引用为参数,既可以使得对形参的任何操作都能改变相应的数据,又使得函数调用显得方便、自然。引用传递方式实在函数定义形参前加上引用运算符“&”。
12:数组与指针
数组也可以用指针来表示。
在C++中,数组名就是数组的起始地址;数组指针就是数组的起始地址。数组元素的指针就是数组元素的地址。
指向数组元素的指针可通过指针引用数组元素。
Int a[10];
Int *p=a;
(p+1指向数组的下一个元素,而不是下一个字)
递归函数
1:直接或间接调用自身的函数称为递归函数。
通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。
基本思想:把一个不能解决或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,最小的问题可以直接解决。
2: 递归定义:使问题向边界条件转化的规则。递归定义必须能是问题越来越简单。
递归终止条件:所描述问题的最简单情况,他本身不再使用递归定义。
3:递归算法的三个步骤:
1):分析问题、寻找递归:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。
2):设置边界、控制递归:找出停止条件,即算法可解的最小规模问题。
3):设计参数、确定参数:设计函数体中的操作及相关参数。
4:半数集:给定一个自然数n,由n开始可以依次产生半数集set(n)中的数。
1):n∈set(n);
2):在n的左边加上一个自然数,但该自然数不能超过最近添加数的一半;
3):按此规则进行处理,直到不能再添加自然数为止。
例:set(6)={6, 16, 26, 126,36, 136}。
注:半数集是多重集。
例
1:求从1加到n的阶乘的和,输入n的值:
#include<iostream>
using namespace std;
int jie(int x);
int main()
{
int n;
cin>>n;
jie(n);
}
int jie(int x)
{
int n=1,m=0;
for(int i=1;i<=x;i++)
{n=n*i;
m=m+n;}
cout<<m<<endl;
}
2:数字反转问题:
#include<iostream>
using namespace std;
int fan(int n);
int main()
{
int n;
cin>>n;
fan(n);
}
int fan(int n)
{
int a=0;
while(n)
{
a=a*10+n%10;
n=n/10;
}
cout<<a;
}
3:验证“歌德巴赫猜想”:
#include<iostream>
using namespace std;
bool isPrime(int n)
{
int h;
if(n<2) return false;
for(h=2;h<n;h++)
if(n%h==0) return false;
return true;
}
int main()
{
int x;
cin>>x;
for(int a=2;a<=x/2;a++)
{
if((isPrime(a))&&isPrime(x-a))
cout<<x<<""<<"="<<" "<<a<<""<<"+"<<" "<<x-a<<endl;
}
}
学习心得
在编程中使用函数可以提高代码的复用性和维护性,并且可以拓展开发。
调用函数大致为5步:1通过函数名找到函数的入口地址,2给形参分配空间,3传参:就是把实参变量对应的空间的值传给形参,4执行函数体里的语句,5函数返回并释放内存空间。
在函数使用中要注意:
1:对所调用函数的错误返回码要仔细、全面地处理。
也就是在调用函数时,需要先判断是否调用成功,再使用。而在实现函数时,要将错误情况分开,返回不同的值。
2:防止将函数的参数作为工作变量。
将函数的参数作为工作变量,有可能错误地改变参数内容,所以很危险。对必须改变的参数,最好先用局部变量代之,最后再将该局部变量的内容赋给该参数。
3:一个函数仅完成一件功能。
这样对代码的复用性和维护性好。
4:为简单功能编写函数。
虽然为仅用一两行就可完成的功能去编函数好象没有必要,但用函数可使功能明确化,增加程序可读性,亦可方便维护、测试。
5:尽量不要编写依赖于其他函数内部实现的函数。
函数独立性。由于目前大部分高级语言都是结构化的,所以通过具体语言的语法要求与编译器功能,基本就可以防止这种情况发生。但在汇编语言中,由于其灵活性,很可能使函数出现这种情况。
6:检查函数所有参数输入的有效性。
7:函数名应准确描述函数的功能,提高代码的可读性。