C++函数

引言

1.c程序结构

c程序有很多源程序文件

源程序文件中有预处理命令,全局变量声明和很多函数(一个程序文件只能有一个main函数,程序总是从main函数开始执行的)(在程序运行过程当中,由主函数调用其他函数,其他函数可以相互调用)

函数又有函数首部和函数体

函数体又有局部变量和执行语句

2.函数的分类

(1)系统函数,即库函数(标准函数):可直接使用

(2)用户自己定义的函数(自定义函数)

库函数

C++常用的有数学计算i函数,字符串函数,标准输入输出函数等

如:sin(alpha)          strlen("Hello")        getchar()        putchar()         scanf()         time()

当用户使用任一库函数时 ,在程序中必须包含相应的头文件,如#include<iostream>  #include<cmath>  #include<cstring>    #include<time,h>

自定义函数

可以用于定义也重用的代码以及组织和简化编码

例如需要分别计算1-10,20-35,100-130的整数的和,可以编写以下代码

重复

int z=0,i,q=0,a=0;
for(i=1;i<=10;i++){
     z+=i;}
for(i=20;i<=35;i++){
      q+=i;}
for(i=100;i<=130;i++){
      a+=i;}

函数的定义和调用

通过定义和调用函数使得函数不必重复编写

1.函数的定义:函数名称,参数,返回值类型以及函数的组成

定义函数的语法:   类型说明  函数名(形式参数列表说明,,,,)     //函数头

                                         {

                                                              函数体

                                                               }

看一个例子如何定义函数并调用一个函数

int sum(int n1,int n2){
 int result=0;
  for(i=n1;i<=n2;i++)
       result+=i;
  return result;
}
int main()
{
cout<<"输出1-10的和"<<sum(1,10)<<endl;
cout<<"输出20-35的和"<<sum(20,35)<<endl;
cout<<"输出100-130的和"<<sum(100,130)<<endl;
 return 0;
}

函数可以返回一个值,返回值的类型是函数返回值的数据类型:有些函数只是完成某些要求的操作,而不返回值,在这种情况下返回类型是void

形参:函数参数列表称为形式参数。

实参:当调用函数时,就给参数传一个值,这个值称为实际参数。

参数列表:指明函数中参数的类型,顺序和个数。

函数类型说明:是指函数返回值的数据类型。

参数是可选的,也就是说函数可以不包含参数的(无参函数)(有参函数)

函数中包括一个函数体,是执行函数语句的集合,定义了该函数该干什么。

注意:在函数头中,如果是有参函数,需要对每个函数进行独立的数据类型声明。

int max(int n1,int n2)     //正确

int max (int n1,n2)    //错误

2.函数的调用

根据函数是否有返回值,调用函数有两种途径。

如果返回一个值:int larger=max(3,4)

int max(int n1,int n2){
 int result;
  if(n1>n2)
    result=n1;
   else
     result=n2;
  return result;
}

large==result          n1=3          n2=4

如果函数返回void(不带返回值的函数,不需要return语句,但return语句能用于终止函数执行并返回到函数的调用处),对函数的调用必须是一条语句。

void printfmarker(char c,int count)
{
  for(int i=0;i<count;i++)
    cout<<c;
    cout<<'\n';
}
void printgrade(double cj){
 if(cj>100||cj<0)
  return;      //没有返回值
 else if(cj>=90)
  cout<<cj<<'A'<<endl;
else if(cj>=80)
 cout<<cj<<'B'<<endl;
 else if(cj>=70)
  cout<<cj<<'C'<<endl; 
else if(cj>=60)
  cout<<cj<<'D'<<endl;
else 
 cout<<cj<<'F';
}
int main(){
printgrade(68);
return 0;
}

提醒(1)在函数调用时,无论有无参数传递,调用函数时函数名后面一定要有括号

(2)实参前面不需要参数类型说明,形参前面必须有类型说明。

当程序调用一个函数时,程序控制就转移到被调用的函数。当执行到return语句或者时执行到表示这个函数结束的右括号那里时,被调用函数将程序控制返还给被调用者。

注意:对于带返回值的函数来说,return语句是必须的。一个函数中可以有一个以上的return语句,执行到哪一个return语句,哪一个return语句起作用。return语句可以是一个表达式,函数先计算表达式后再返回值。

为了更好的区分void和带返回值的函数

void函数

void printgrade(double cj){
 if(cj>100||cj<0)
  return;      //没有返回值
 else if(cj>=90)
  cout<<cj<<'A'<<endl;
else if(cj>=80)
 cout<<cj<<'B'<<endl;
 else if(cj>=70)
  cout<<cj<<'C'<<endl; 
else if(cj>=60)
  cout<<cj<<'D'<<endl;
else 
 cout<<cj<<'F';
}
int main(){
printgrade(68);
return 0;
}

带返回值的函数

char getgrade(double cj){
if(100>=cj&&cj>=90)
return 'A';
else if(cj>=80)
return 'B';
else if(cj>=70)
return 'C';
else if(cj>=60)
return 'D';
else 
return 'E';
}
int main()
{   cout<<getgrade(95);
return 0;
}

通过传值进行参数传递

 通过传值的方式将实参传递给形参

调用函数时,需要提供实参,它们必须与函数定义中所对应的形参次序数量上匹配,在类型上兼容。(类型兼容是指不需要经过显式的类型转换,实参的值可以传给形参,如int型的实参传给double型实参。)

按值传递:实参的值传给形参。无论形参在被调用函数中是否改变,其对应的实参变量在调用函数中都不受影响。

按值传递例子

void zj(int n){
n++;
cout<<"输出n的值"<<n;
}
int main(){
int x=1;
cout<<"输出x的值"<<x<<endl;
zj(x);
cout<<"输出x的值"<<x<<endl;
return 0;
}

即使将main函数中的变量x改名为n,结果仍不受影响。实参和形参是否同名没有任何区别。

形参是函数中具有自己存储空间的局部变量,局部函数是在调用函数时分配的,当函数返回到调用者后它就消失了。

说明:(1)在未出现函数调用时,形参并不占内存的存储单元,只有在函数开始调用时,形参才被分配内存空间,并且调用结束后,形参占用的内存单元被释放。

(2)实参对形参的传递是“值传递”,单向传递,在内存中实参和形参分别占不同的单元。

(3)形参只作用于被调函数,可以在其他的函数中使用相同的变量名。

函数先定义后使用

1.被调用函数的定义在主调函数之前的情况

2.被调用函数的定义在主调函数之后的情况

int main()
{float a,b,c;
float max(float n1,float n2);
 cin>>a>>b;
  c=max(a,b);
  cout<<c;
 return 0;}
float max(float n1,float n2){
float m; 
m=(n1>n2)?n1:n2;
return m;
}

定义是一个完整的函数单元,而原型说明仅仅是说明函数返回值及形参的类型。

3.使用库函数,必须在使用之前包括相应的头文件,一般在文件一开始之处。

模块化代码

使用函数减少冗杂的代码,提高代码的复用性。

#include<iostream>
using namespace std;
int gys(int n1, int n2) {
	int k = 1;
	int t = 2;
	while (t <= n1 && t <= n2) {
		if (n1 % t == 0 && n2 % t == 0)
			k = t;
			t++;
	}
	return k;
}
int gbs(int n1, int n2) {
	int t = 1;
	while (t % n1 != 0 || t % n2 != 0) {
		t++;
	}
	return t;
}
int main() {
	int x, y;
	cin >> x >> y;
	cout << gys(x, y) << "    " << gbs(x, y);
	return 0;
}

该程序体现(1)模块化编程思想,每个函数具有一个独立的功能,而不是将所有的代码都写在主函数中。(2)将其他函数和主函数中的其他代码分隔开,这样会使得函数逻辑更加清晰而且也增加了程序的可读性。(3)每个函数的错误就限定在该函数中,这样缩小了调试的范围。(4)其他程序中可以重复使用这些功能函数。

阶段性提醒

1.形参前面不要忘记类型说明。

2.带返回值的函数必须通过return返回一个于函数类型兼容的值。

3.return语句可以是一个值或者是一个表达式,函数先计算表达式后再返回值。

4.void类型函数return可有可无。

5.调用函数时,需要提供实参,它们必须与函数定义中所对应的形参次序数量上匹配,在类型上兼容。

6.函数要先定义后使用,如果出现被调用函数的定义在主调函数之后的情况,要在调用前添加函数声明。

变量的定义域

变量的定义域是指程序中的变量在哪一个区间内有效,即在哪一个区间内可以使用或者引用该变量。

变量的定义域取决于变量定义的位置。

在函数中定义的变量称为局部变量,在函数外定义的变量称为全局变量

在一般意义上,在内定义的变量称为局部变量。局部变量的作用域从声明变量的地方开始,直到包含该变量的块结束为止。

函数的形参也是局部变量,其作用域覆盖整个函数。

全局变量的作用域从声明变量的地方开始,直到该文件结束为止(一个文件一般是由一个或很多个函数构成的)。

{}之间语句就称为一个块。

局部变量的定义域

一个块内的变量      

不同函数的同名变量没有任何关系,各自占有独立的内存空间。

具有块作用域的变量在其作用域内,将屏蔽包含在本块中其它块中的同名标识符,即:变量名相同,局部更优先。

同一作用域不能重复定义同名变量。

文件作用域(全局变量作用域)

当局部变量与全局变量同名时,局部变量优先。

全局变量和静态局部变量如果未初始化,系统自动赋值为0。

在块作用域内可通过作用域运算符::来引用与局部变量同名的全局变量。

存储类型

外存:程序

内存:程序区(存放程序代码),静态存储区,动态存储区。(存放变量)

如果变量存储在静态存储区,那么变量一直保存到程序结束。

动态存储:在程序运行期间根据需要分配存储空间,函数结束后立即释放空间。若一个函数在程序中被调用多次,则每次分配单元有可能不同。       动态局部变量

静态存储:在程序运行期间有固定的存储空间,直到程序运行结束。   全局变量和静态局部变量

局部变量:

(1)动态局部变量(auto):其作用域的函数或复合语句结束时,空间被程序收回。动态局部变量未赋值时,其值为随机值

(2)静态局部变量(static):其作用域的函数或复合语句内,程序执行到静态局部变量时,为其在静态区开辟存储空间,该空间将一直被保留,直到程序结束。静态局部变量未赋值时,系统自动赋值为0。

在函数中的定义形式 :static int a;只赋一次初值,内存一旦开辟空间,就不会释放,控件之一直保留。

函数的嵌套调用

C语言中,所有函数都是平行独立的,无主次,相互包含。函数可以嵌套调用,不可嵌套定义

定义过程中也可以调用函数。(直接递归和间接递归)

必须要有递归结束条件(函数用if ,else)

举例:计算1+2+3+......+i;

#include<iostream>
using namespace std;
int main() {
	int sum(int);
	int i = 5;
	cout << sum(i) << endl;
	return 0;
}
int sum(int i) {
	int a;
	if (i == 1)
		return 1;
	else
		 a = i + sum(i - 1);
	return a;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值