本章涉及指针 , 需要先学第八章内容
DESCRIPTION
函数. 本章涉及指针 , 需要先学第八章内容. 本章主要内容. 函数定义 参数的传递 数组的传递 函数的调用和嵌套 main 函数的参数 函数编程举例. 函数使用事例. #include "stdio.h" double fun(int n){/* 函数定义* / int i; double l=1; if(nTRANSCRIPT
函数
本章涉及指针 , 需要先学第八章内容
本章主要内容
• 函数定义• 参数的传递• 数组的传递• 函数的调用和嵌套• main函数的参数• 函数编程举例
函数使用事例• #include "stdio.h"• double fun(int n){/* 函数定义 */• int i;• double l=1;• if(n<2)return 1;• else for(i=2;i<=n;i++)l*=i;• return l;• }• void main()• { int n,m;• double c;• printf(" 输入 n m:\n");• scanf("%d%d",&n,&m);• c=fun(n)/(fun(m)*fun(n-m));/* 调用函数
*/• printf("%lf",c);• }
问题 :
计算
c= n!/(m!(n-m)!)
n 和 m 都是输入的整数
函数的定义• 函数定义格式 :
– [ 返回值类型 ] 函数名 ( 形式参数表 ){– 函数体– }
• 说明 :– 类型说明符省略时 , 相当于整形– 函数中声明的参数称为形式参数,调用时代入的值称为实际参数– 形式参数表可以为空 , 但是两侧的 ( ) 不能省略– 函数用 return 语句返回值 , 返回值类型必须与函数头声明的返回类型一致– 没有返回值时 , 类型应声明成 void, 这种情况下 , 可以没有 return 语句或用空 return– 函数必须先声明后使用,如果函数说明出现在调用之后时,要先用函数头说明
• 函数举例 :– float area(float radius)– { float a;– a=3.14*radius*radius;– return a;– }
函数声明在 main 函数后时• #include "stdio.h"• double fun(int n);• /* 函数的原型声明 , 还可以写作 double (int 任意变量名 ) 或 double fun(int )*/• void main()• { int n,m;• double c;• printf(" 输入 n m:\n");• scanf("%d%d",&n,&m);• c=fun(n)/(fun(m)*fun(n-m));/* 调用函数 */• printf("%lf",c);• }• double fun(int n){/* 函数定义 */• int i;• double l=1;• if(n<2)return 1;• else for(i=2;i<=n;i++)l*=i;• return l;• }
头文件的产生•
引用 ( 选学 )
• // 引用就是别名 , 给一个变量多个名字• #include <iostream.h>
• void main(){
• int a=20,&y=a;
• y=30;
• cout<<a<<endl;
• }
参数传递方式• 值传递• 地址传递• 引用传递
参数传递 - 数值传递• #include <iostream.h>• void f(int b){• b++;•
cout<<"b="<<b<<endl;• }• void main()• { int a=1;• f(a);•
cout<<"a="<<a<<endl;• }
参数传递 - 地址传递• #include <iostream.h>• void f(int *b){• (*b)++;•
cout<<"*b="<<*b<<endl;• }• void main()• { int a=1;• f(&a);•
cout<<"a="<<a<<endl;• }
参数传递 - 引用传递 ( 选学 )
• #include <iostream.h>• void f(int &b){• b++;•
cout<<"b="<<b<<endl;• }• void main()• { int a=1;• f(a);•
cout<<"a="<<a<<endl;• }
参数传递举例• #include "stdio.h"• void fun(int *b){• int t=5;• printf("1th b=%d\n",*b);• *b=t; /* 给 *b( 变量 a) 赋
值 */• printf("2th b=%d\n",*b);• }• void main(){• m1: int a=2;• m2: fun(&a);• m3: printf("3th a=%d\n",a);• }
#include "stdio.h"void fun(int *b){ int t=5; printf("1th b=%d\n",*b); b=&t; /* 给变量 b 赋值 t 的地址*/ printf("2th b=%d\n",*b);}void main(){ m1: int a=2; m2: fun(&a); m3: printf("3th a=%d\n",a);}
参数传递举例• #include <iostream.h>• void f(int a,int *b){• int t;• t=a;a=*b;*b=t;• }• void main()• { int x=2,y=3;• f(x,&y);• cout<<x<<","<<y<<endl;• }
一维数组传递• 数组传递是传递数组的首地址• 形式参数声明为指针、数组形式含义是相同的,都只是声明了一个指针,用来保
存实参传来的首地址• void fun(int p[N]); void fun(int p[]); void fun(int *p);/* 三种形式具有同样的含义 */• 举例:
– #include <iostream.h>– void fun(int *a){– int i;– for(i=0;i<10;i++)a[i]++;//a[i]++ 可以写成 (*(a+i))++ (*a++)++;– }– void main()– { int b[10]={0,1,2,3,4,5,6,7,8,9},i;– fun(b);– for(i=0;i<10;i++)cout<<b[i]<<",";– cout<<endl;– }
一维数组传递举例• #include <iostream.h>
• void fun(int a[]){
• int i;
• for(i=2;i<5;i++)a[i]++;
• }
• void main()
• { int b[10]={0,1,2,3,4,5,6,7,8,9},i;
• fun(&b[3]);
• for(i=0;i<10;i++)cout<<b[i]<<",";
• cout<<endl;
• }
二维数组传递• 与二维数组对应的指针是数组指针• void fun(int p[N][10]); void fun(int p[][10]); void fun(int (*p)[10]);/* 数组指针做为参
数 */ – #include "stdio.h"– void ainc(int p[][5],int line,int col){– int i,j;– for(i=0;i<line;i++)– for(j=0;j<col;j++)p[i][j]++;– }– void main(){– int a[3][5]={0},i,j;– ainc(a,3,5);/* 传递处理的首地址,和要处理元素个数 */– for(i=0;i<3;i++){– for(j=0;j<5;j++)– printf("%d ",a[i][j]);– printf("\n");– }– }
指针数组的传递• 与指针数组名对应的指针是指针的指针• void fun(int **p) void fun(int *p[]) void fun(int *p[N])/* 三种形式具有相
同含义 */ – #include "stdio.h"– #include "string.h"– void sort(char **pp,int len){– int i,j;– char *t;– for(i=0;i<len-1;i++)– for(j=i+1;j<len;j++)– /* 字符串逆序,则调整 b[i] 指针的次序 */– if(strcmp(pp[i],pp[j])>0){– t=pp[i];– pp[i]=pp[j];– pp[j]=t;– }– }– void main(){– char a[5][20]={"she","he","we","me","you"},*b[5];– int i;– for(i=0;i<5;i++)b[i]=a[i];– sort(b,5);– for(i=0;i<5;i++)puts(b[i]);– }
嵌套• #include <iostream.h>• void f1(){• cout<<1<<endl;• cout<<2<<endl;• }• void f2(){• cout<<3<<endl;• f1();• cout<<4<<endl;• }• void main(){• cout<<5<<endl;• f2();• cout<<6<<endl;• }
主函数参数• 主函数的形参类型和个数是固定的,第一个参数是整数,内存实参的个
数,第二个参数是字符指针数组,或字符指针的指针,内存全部实参字符串的首地址
• 如: main(int argc,char **argv) main(int argc,char*argv[])• 实参是通过在命令行执行时,后跟参数值实现的• 例如 : 程序名为 prog
– 形参: void main(int argc,char *argv[])– 调用: prog aaa bbb ccc
主函数参数举例• void main(int argc,char *argv[])• argc 为参数 +1• 例 :• #include <stdio.h>• void main(int argc,char *argv[])• { int i;• printf("%d\n",argc);• for(i=0;i<=argc;i++)puts(argv[i]);• }
例二主函数形式参数• // 把两个 1 位数字参数相加• #include <iostream.h>• void main(int argc,char *argv[])• { • int a,b;• a=argv[1][0]-'0';• b=argv[2][0]-'0';• cout<<a+b<<endl;• }
函数举例 -1// 问题:用牛顿迭代法求方程 f(x)=2*x*x*x-4*x*x+3*x-6 根//x=x0-f/f'#include <iostream.h>#include <math.h>double f(double x){
return 2*x*x*x-4*x*x+3*x-6;}double fb(double x){
return 6*x*x-8*x+3;}void main(){
double x0,x=0;x0=3.0;x=x0-f(x0)/fb(x0);while(fabs(x-x0)>1e-5){
x0=x; x=x0-f(x0)/fb(x0);
}cout<<x<<endl;
}
函数举例 -2
• 1. 分别用矩形法和梯形法求
5.2
0
2
.e xx
#include <iostream.h>#include <math.h>double f(double x){
return x*exp(-x*x);}void main(){
double a=0,b=2.5,h,s=0;int i,n;cin>>n;h=(b-a)/n;for(i=0;i<n;i++){
s+=f(a+i*h)+f(a+(i+1)*h);}s=s*h/2;cout<<s<<endl;
}
函数举例• 字符串函数的实现:
– strlen– strcpy– strcat– strcmp