C++函数初学总结

一.基础内容

1.函数的定义

(1)定义的语法形式:

数据类型       函数名(形式参数表)

{

            函数体             //执行语句

}

注释说明:

*数据类型是返回值类型(void无返回值)

*函数名按照标识符的取名规则可以任取

*形式参数:可有可无,且可以是变量名、数组名或指针名,作用是实现主调函数和被调函数的关系

*函数不允许嵌套定义

函数定义的例子:

定义一个函数,返回两数中的较大数

int max(int x,int y)
{
   return x>y? x:y;
}

该函数返回值是整型,有两个整型的形参,用来接受实参传递的两个数据,函数体内的语句是求两个数中的较大并将其返回主调函数。

特殊的函数形式:

空函数(实例)

#include<iostream>
using namespace std;
int js(int); //函数的声明
int main()
{
int sum=0;
for(int i=0;i<=10;i++)
sum+=js(i);  //函数的调用
ocut<<"sum+"<<sum<<endl;
return 0;
}
int js(int n)  //定义的函数体
{
int s=1;
for(int i=1;i<=n;i++)
s*=i;
return s;  //函数的返回值
}

空函数不完成什么工作,只占据一个位置,在大型函数设计中,空函数只用于扩充函数内容。

2.函数的声明和调用

1.(1)函数的声明:

类型说明符   被调函数名(含类型说明的形参表);

int js(int n);

或者是

int js(int);
(2)函数的调用:

函数名(实参列表)

sum+=js(i);
(3)函数的返回值:

return(表达式)

return s;
2.函数的传值调用:

(1)传值调用

这种调用方式是将实参的数据值传递给形参,即将实参拷贝一个副本存放在被调用的函数的栈区中。在被调用函数中,形参值可以改变,但不影响主函数的实参值。参数传递方向只是从实参到形参,简称单项值传递

#include<iostream>
using namespace std;
void swap(int a,int b)
{
int tmp=a;a=b;b=tmp;
}
int main()
{
int c=1,d=2;
swap(c,d);
cout<<c<<''<<d<<endl;
return 0;
}            //程序输出为:1 2

(2)传址调用

这种调用方式是将实参变量的地址值传递给形参,这时形参是指针,即让形参的指针指向实参地址,这里不再是将实参拷贝一个副本给形参,而是让形参直接指向实参,这就提供了一种可以改变实参变量的值的方法。现在用传址调用来实现swap:

#include<iostream>
using namespace std;
void swap(int &a,int &b)
{
int tmp=a;a=b;b=tmp;
}
int main()
{
int c=1,d=2;
swap(c,d);
cout<<c<<''<<d<<endl;
return 0;
}   //程序输出为:2 1
3.函数指针:

(1)定义与应用

指针变量:其内容为地址(存储位置)的变量,简称指针。它所指向的地址上存放的变量称为目标变量。


指针变量也同样可以赋值:


(2)指针变量作为函数参数

函数的参数可以是指针类型,它的作用是将一个变量的地址传送的另一个函数中。

指针变量作为函数参数与变量本身作函数参数不同,变量作函数参数传递的是具体值,而指针作函数参数传递的是内存的地址。


用指针变量作函数参数,在被调函数的执行过程中,应使指针变量所指向的函数值发生变化,这样,函数在调用结束后,其变化值才能保留回主调函数。

函数调用不能改变实参指针变量的值,但可以改变实参指针变量所指向变量的值。

用指针变量作函数参数,可以得到多个变化了的值。

(3)指向数组元素的指针

例子如下

int a[10],*p;
p=&a[0];  //数组第一个元素的地址
p=a;   //直接用数组名赋值;p为变量,a为常量

4.递归算法

简单的说,递归算法的本质就是自己调用自己,用调用自己的方法去处理问题,可以使问题变得简洁。

步骤如下:

保存调用前的变量和程序的返回地址——执行被调用的函数——满足条件退出递归,否则从变量值继续沿着返回地址向下执行程序

二.典型例题

1.函数的简单定义去解决问题:

(例1)

输入一个整数

输出奇数字个数

偶数字个数

#include<iostream>
using namespace std;
int oushu(int n);
int main()
{
   long t,x;
   int i=0,j=0;
   cin>>x;
   do
   {
       t=x%10;
       if(oushu(t)==1)
       i++;
       if(oushu(t)==0)
       j++;
       x=x/10;
   }
   while(x!=0);
   cout<<j;
   cout<<endl;
   cout<<i;
   return 0;
}
int oushu(int n)
{
    if(n%2==0)
    return 1;
    else
    return 0;
}

(例2)

描述 给定一个整数,请将该数各个位上数字反转得到一个新数。新数也应满足整数的常见形

式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零

输入输入共 1 行,一个整数N。

输出输出共 1 行,一个整数,表示反转后的新数。

#include<bits/stdc++.h>
using namespace std;
int fz(int n);
int main()
{
    int x;
    cin>>x;
    cout<<fz(x);
    return 0;
}
int fz(int n)
{
    int s=0;
    while(n)
    {
        s=n%10+s*10;
        n=floor(n/10);
    }
    return s;
}

(例3)

描述 求从1加到n的阶乘的和,输入n的值,按要求输出。输入 输入一个数n输出 输出从1加到n的和
#include<bits/stdc++.h>
using namespace std;
int jiecheng(int n);
int main()
{
	int x,sum=0;
	int j; 
	cin>>x;
	for(j=1;j<=x;j++)
	sum+=jiecheng(j);
	cout<<sum;
	return 0;
}
int jiecheng(int n)
{
	int s=1;
	int i;
	for(i=1;i<=n;i++)
	s=s*i;
	return s;
}

2.函数的递归算法解决复杂问题:

(例4)

描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。输入 第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。

输出对输入的每组数据M和N,用一行输出相应的K。

#include<iostream>  
using namespace std;  
int t,m,n;  
int up(int ,int);  
int main()  
{  
    cin>>t;  
    while(t--)  
    {  
     cin>>m>>n;  
     cout<<up(m,n)<<endl;  
    }  
        return 0;  
 }  
 int up(int m,int n)  
 {  
     if(m==0||n==1)  
     return 1;  
     else if(m<n)  
     return up(m,m);  
     else return up(m-n,n)+up(m,n-1);  
     }  

三.学习心得

总结函数本章以及初入递归算法的内容学习,我发现函数的基础不是很难但是十分重要,就像是一门语言中的语法一样,函数的应用极大的扩充了C++的应用范围以及提高了其普遍性与可应用性,所以应该好好掌握。而接下来的递归,我个人感觉比较难掌握,尤其是各类循环的辨识与循环的跳出,恐怕是个需要深入研究的知识。

猜你喜欢

转载自blog.csdn.net/fouram_godv/article/details/79677968