版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第一部分第一部分 C+C+结构化程序设计结构化程序设计本章内容本章内容 函数概述函数概述 函数的定义和调用函数的定义和调用 函数原型函数原型 参数的传递机制参数的传递机制 函数与指针函数与指针 嵌套调用和递归调用嵌套调用和递归调用 函数参数的缺省函数参数的缺省 函数重载函数重载 函数模板函数模板 内联函数内联函数 系统函数系统函数 作用域、生存期与可见性作用域、生存期与可见性 编译预处理编译预处理 带参数的带参数的main( ) main( ) 2 2例:求3 31694#include #includevoid main( )double sum; sum=sqrt(4)+sqrt (9)+
2、sqrt (16);coutsum=sumendl;求求 4!+9!+16!l 遇到的问题:遇到的问题:没有求阶乘的库函数!没有求阶乘的库函数!l 自己动手做函数自己动手做函数 函数应该有名字函数应该有名字 函数有入口(函数的参数)函数有入口(函数的参数) 函数有出口(函数的返回值)函数有出口(函数的返回值)4 4sqrt4293164xyxyFact (n )return f;5 5函数名函数名函数的参数(入口)函数的参数(入口) 可以有多个参数可以有多个参数函数的返回值(出口)函数的返回值(出口) 只能有一个返回值只能有一个返回值double Fact (int n )double f;r
3、eturn f;怎样实现函数的功能?怎样实现函数的功能?double Fact ( int n )double f=1.0for(int i=1; i=n; i+) f*=i;return f;函数的返函数的返回类型回类型#include double Fact( int n )double f=1.0for(int i=1; i=n; i+) f*=i;return f;void main( )double sum; sum=Fact(4)+Fact(9)+Fact(16);cout“4!+9!+16!=sumendl;不使用函数会怎样?6 6#include void main( )int
4、 i1, i2, i3;double s, s1, s2, s3; s1=1.0;for(i1=1;i1=4;i1+)s1*=i1;s2=1.0;for(i2=1;i2=9;i2+)s2*=i2;s3=1.0;for(i3=1;i3=16;i2+)s3*=i3;s=s1+s2+s3;#include void main( )int i;double s, s1, s2, s3; s1=1.0;for(i=1;i=4;i+)s1*=i;s2=1.0;for(i=1;i=9;i+)s2*=i;s3=1.0;for(i=1;i=16;i+)s3*=i;s=s1+s2+s3;#include void
5、 main( )int i;double s, s1; s=0;s1=1.0;for(i=1;i=4;i+)s1*=i;s+=s1;s1=1.0;for(i=1;i=9;i+) s1*=i;s+=s1;s1=1.0;for(i=1;i=16;i+) s1*=i;s+=s1;#include void main( )int i, j;int a3=4,9,16;double sum=0, temp; for(i=0; i3; i+)temp=1.0for(j=1; j=ai; j+) temp*=j;sum+=temp;cout“4!+9!+16!=sumendl;#include double
6、 Fact( int n )double f=1.0for(int i=1; i=n; i+) f*=i;return f;void main( )double sum; sum=Fact(4)+Fact(9)+Fact(16);cout“4!+9!+16!=sumendl;讨论:使用函数的好处讨论:使用函数的好处 减少重复的代码;减少重复的代码; 使用函数使用函数“分担分担”程序的部分功能;程序的部分功能; 使思路更加清晰:使思路更加清晰:程序所有功能可以分解为若干程序所有功能可以分解为若干个不同的函数完成。个不同的函数完成。main()是一个是一个“节目主持节目主持人人”,作为程序的主干;
7、,作为程序的主干; 可以把编程工作分配给一个可以把编程工作分配给一个team,每人负责编,每人负责编写若干个函数,有一个统一的写若干个函数,有一个统一的接口;接口; 修改主函数或某个函数,不影响其它;修改主函数或某个函数,不影响其它; 可重复使用!可重复使用!7 7#include double Factorial(int n)double temp=1.0;if(n=0) return 1.0;for(int i=1;i=n;i+)temp*=i;return temp;void main( )double s;s=Factorial(6)+Factorial (17)+Factorial
8、(20);cout6!+17!+20!=sendl; 函数的定义函数的定义函数的调用函数的调用函数的首部函数返回值的类型函数名形参的类型和名称函数体内部变量说明部分可执行语句部分两种形式两种形式作为表达式一部分作为表达式一部分语句调用语句调用实参实参函数原型函数原型与变量一样,函数也需要先声明后使用。如果函数的调用在定义之前,则需要有函数原型。形式上,函数原型与函数定义的头部相同。8 8#include double Factorial(int x);/函数原型函数原型void main( )double s;s=Factorial (6)+Factorial (17)+Factorial (
9、20);cout6!+17!+20!=sendl; double Factorial(int n)double temp=1.0;if(n=0) return 1.0;for(int i=1; i=n; i+) temp*=i;return temp;C+语言源程序的特点语言源程序的特点l 源程序构成:源程序构成:一个一个C+源程序由一个主函数和若源程序由一个主函数和若干个相关的子函数组成。干个相关的子函数组成。l 主主函数:函数:总是以总是以main ( )作为开头,是源程序执作为开头,是源程序执行的起点,其结尾是源程序运行的终点。它是行的起点,其结尾是源程序运行的终点。它是唯唯一能够独立运
10、行一能够独立运行的函数,可以位于源程序的前面、的函数,可以位于源程序的前面、中间或者后面。中间或者后面。l 子函数子函数:是功能独立和简单的程序。它的运行需是功能独立和简单的程序。它的运行需要函数间的调用指令。要函数间的调用指令。l 函数种类:函数种类:包括用户自编写函数、系统函数(包括用户自编写函数、系统函数( 由由C+系统提供)。系统提供)。4.1 函数概述函数概述9 94. 2 函数的定义和调用函数的定义和调用1. 函数的定义函数的定义类型名类型名 函数名函数名(形式参数表)(形式参数表)语句序列语句序列 定义函数内容:函数名称、函数返值类型、函数定义函数内容:函数名称、函数返值类型、函
11、数参数个数和类型、以及编写实现的函数的功能的语句参数个数和类型、以及编写实现的函数的功能的语句函数定义的一般形式为:函数定义的一般形式为:1010函数定义各部分的含义函数定义各部分的含义 函数名:函数名:函数命名与变量名命名方法相同。作为一函数命名与变量名命名方法相同。作为一种种标识符标识符,函数名命名最好反映该函数的功能,做,函数名命名最好反映该函数的功能,做到到“见名知意见名知意”。如用。如用factorial好于好于F。 形式参数表:形式参数表:用圆括号括起来;参数间用逗号隔开;用圆括号括起来;参数间用逗号隔开;必须指明类型。若无参数,圆括号内什么也不写或必须指明类型。若无参数,圆括号内
12、什么也不写或写写void,但圆括号本身不能省略。,但圆括号本身不能省略。 类型名:类型名:实际是实际是返回值返回值的数据类型。可以是基本数的数据类型。可以是基本数据类型、构造数据类型、据类型、构造数据类型、指针或引用指针或引用。 return语语句实现函数的返值功能。句实现函数的返值功能。如果一个函数没有返回值,如果一个函数没有返回值,返回值类型标记为返回值类型标记为void。如果定义时没指定类型,如果定义时没指定类型,则默认的类型是则默认的类型是int型(注意不是型(注意不是void型)。型)。1111 花括号:花括号:花括号内是各种语句组成的函数体,花括号内是各种语句组成的函数体,函数是程
13、序运行的基本单位。函数的定义不可以嵌函数是程序运行的基本单位。函数的定义不可以嵌套,套,即函数体内不允许定义另一个函数。即函数体内不允许定义另一个函数。 return语句:语句:return 表达式;表达式;可以没有表达式,可以没有表达式,只一个只一个return(此时可以省略);如果没有(此时可以省略);如果没有return语句,函数执行至语句,函数执行至“”返回。函数内可以多个返回。函数内可以多个return语句,注意函数的返回值只能有一个。语句,注意函数的返回值只能有一个。/P79,例,例4.2:没有形参和返回值的函数:没有形参和返回值的函数注意 函数返回值是void,只能用语句方式调用
14、。 函数返回值是int(缺省)或其它,如果没有return语句,则可能返回一个任意的数。 当函数有返回值,如果不关心返回值是多少,也可以用语句方式调用。 当函数作为表达式时,表达式的值就是函数的返回值1212void alphabet() cout“abcdefgn”; main() alphabet();void alphabet() cout“abcdefgn”;return;/可以没有可以没有return语句语句main() int x;x=alphabet();coutxendl; /不能以表达式方式调用不能以表达式方式调用alphabet() /int alphabet() cout
15、“abcdefgn”;return 1;main() int x;x=alphabet();coutxendl; /输出输出1alphabet()cout“abcdefgn”;main() int x;x=alphabet();coutxendl; /x的值其实没有意义的值其实没有意义alphabet()cout“abcdefgn”;main() int dummy;dummy=alphabet();alphabet();/两种调用方法都可以两种调用方法都可以1313/P79,例,例4.1:定义求:定义求xn的函数的函数#includelong power(int x, int n) long
16、 p=1;/注意类型的一致注意类型的一致for(int i=1; i=n; i+) p=p*x;return p;main() long x;double y;x=power(3,4);/类型一致类型一致y=power(3, 2.5); /没有得到没有得到3的的2.5次方次方coutx=x,y=yendl;1414/求求xy,(x、y可以输入)可以输入)#includepower(int x, int n)int p=1;for(int i=1; ixy;z=power(x, y);/类型一致类型一致cout“z=zendl;/求求xy (x、y可以输入)可以输入)#includepower(
17、int x, int n)int p=1;for(int i=1; ixy;cout“z= power(x, y) endl;/不成功的例子不成功的例子#includepower(int x, int n) int p=1; cinxn;for(int i=1; i=n; i+) p=p*x;cout“p=”pendl;main()int x, y, z;x=3; y=4;z= power(x, y);cout“z=zendl;/成功但不好的例子成功但不好的例子#includepower() /不能写成:不能写成:power(int x, int n) int x, n;int p=1; ci
18、nxn;for(int i=1; i=n; i+) p=p*x;cout“z=”pendl;main()power();/函数的形参与函数内部的局部变量有什么不同?函数的形参与函数内部的局部变量有什么不同?/P80,例,例4.3:有多个:有多个return语句函数语句函数#includemax(int a1, int a2)/函数类型函数类型int可以省略可以省略 /返回返回a1、a2中大的数中大的数if(a1a2)return a1;elsereturn a2;void main()coutmax(3, 4)endl;coutmax(9, 8)endl; /返回语句可以有多个,但返回值只能有
19、一个!返回语句可以有多个,但返回值只能有一个!15152. 函数的调用函数的调用是指在一个函数执行中间,转去执行其他函数的过程。子函数一经定义,就可以被main()主函数、其他函数、甚至该子函数自身多次调用。函数调用形式为:函数调用形式为: 函数名函数名(实参表)(实参表);注意实参与形参在注意实参与形参在数量数量、类型类型、位置位置上的一致性上的一致性long F(int x, double y, bool z)/定义定义main()long u;u=F(3, 2.5, true);/调用调用1616#include double F(int x, double y, bool z)cout
20、x=xendl;couty=yendl;coutz=zendl;return 1.5;void main()long u=F(3.5, 2, 6);coutu=uendl;1717函数调用的嵌套函数调用的嵌套 函数可以反复调用。 函数的定义不可以嵌套,但是函数的调用可以嵌套。void main() int x, i;coutx;for(i=1; i=10; i+)coutpower(x,i)endl;long m=power(power(x, 2), 3);coutmendl; /如果如果x=2, 则则m=6418184. 3 函数原型函数原型l函数原形的一般形式:函数原形的一般形式:类型名类
21、型名 函数名函数名(形参表);(形参表);l用途:事先声明某函数的存在。即当调用用途:事先声明某函数的存在。即当调用函数语句出现在被调用函数定义之前的时函数语句出现在被调用函数定义之前的时候,必须事先对该被调用函数进行原型说候,必须事先对该被调用函数进行原型说明。明。 调用在前,定义在后,需要声明。调用在前,定义在后,需要声明。 定义在前,调用在后,可以没有声明,首部兼定义在前,调用在后,可以没有声明,首部兼做声明的作用。做声明的作用。l 函数原型即函数定义的第一行的内容,后函数原型即函数定义的第一行的内容,后面加上面加上“;”(分号分号)。 1919举例,P80,例4.4:求35#inclu
22、de int power(int x, int n)int i, p=1; for(i=1; i=n; i+) p=p*x; return p;void main()int x, s; coutx;s=power(x, 3)+power(x, 5);couts=sendl;#include int power(int x, int n);/函数原形函数原形 void main()int x, s; coutx;s=power(x, 3)+power(x, 5);couts=sendl;int power(int x, int n)int i, p=1; for(i=1; i=n; i+) p=
23、p*x; return p;#include int power(int a, int b);void main()int x, s; coutx;s=power(x, 3)+power(x, 5);couts=sendl;int power(int x, int n)int i, p=1; for(i=1; i=n; i+) p=p*x; return p;#include int power(int, int);void main()int x, s; coutx;s=power(x, 3)+power(x, 5);couts=sendl;int power(int x, int n)in
24、t i, p=1; for(i=1; i=n; i+) p=p*x; return p;#include int power(int, int);int power(int x, int n)int i, p=1; for(i=1; i=n; i+) p=p*x; return p;void main()int x, s; coutx;s=power(x, 3)+power(x, 5);couts=sendl;2020 函数原型举例,P82,例4.6#include f1(); /原型,标准写法:原型,标准写法:int f1(void);void main() coutthis is main
25、()n; /f1(); 与下边的调用有什么区别?与下边的调用有什么区别? coutf1()endl; int f1(void) /int和和void都可以省略都可以省略 f1() coutthis is f1()n; return 1; int f2(void) coutthis is f2()n; return 2;int f3(void) coutthis is f3()n; coutf2()endl; return 3;#include /原型原型int f1(), f2(), f3();void main() coutthis is main()n; coutf1()endl; int
26、 f1(void) coutthis is f1()n; coutf3()endl; return 1; 输出:输出:this is main()this is f1()this is f3()this is f2()23121214. 4 参数传递机制参数传递机制l 用实参去替换形参的过程称作参数传递。用实参去替换形参的过程称作参数传递。l 当一个函数被调用时,系统会给该函数的形参分配当一个函数被调用时,系统会给该函数的形参分配存储空间,同时要求提供与形参的类型、个数存储空间,同时要求提供与形参的类型、个数一致一致的实参。的实参。 #include int MyAdd(int x, int
27、y) return 2*x+3*y;void main() coutMyAdd(3, 4)endl;#include int MyAdd(int x, int y) return 2*x+3*y;void main() int x=3, y=4;coutMyAdd(x, y)endl;#include int MyAdd(int x, int y) return 2*x+3*y;void main() int x=3, y=4;coutMyAdd(y, x)endl;2222l 数值传递机制(传值方式)数值传递机制(传值方式) 将各个实参的值将各个实参的值 按位置先后顺序按位置先后顺序 拷贝(
28、传递)拷贝(传递)给与之对应的各个形参。传递后的形参与对应的给与之对应的各个形参。传递后的形参与对应的实参虽然数值相同,但却是不同的变量。实参虽然数值相同,但却是不同的变量。 P83,例,例4.7 将两个变量的内容交换将两个变量的内容交换#include void swap(int x, int y)int temp; temp=x; x=y; y=temp;void main() int a(15), b(18);swap (a, b); cout“调用调用swap的输出的输出: a=”a“,b=bendl; 调用swap的输出: a=15,b18#include void swap(int
29、 x, int y); /函数原型函数原型void main() int a(15), b(18); cout“调用调用swap前的输出前的输出: a=”a“,b=bendl; swap (a, b);cout“调用调用swap的输出的输出: a=”a“,b=bendl; void swap(int x, int y) int temp; cout“交换前的输出交换前的输出: x=”x“,y=yendl; temp=x; x=y; y=temp; cout“swap函数输出函数输出: x=”x“,y=yendl; 调用调用swap前的输出前的输出: a=15,b=18交换前的输出:交换前的输出
30、:x=15,y=18swap函数的输出:函数的输出:x=18,y=15调用调用swap的输出的输出: a=15,b=182323l 传地址调用机制传地址调用机制 形参是一个形参是一个指针,指针,实参传递的是地址。实参传递的是地址。 /P84例例4.8#include void swap(int *x, int *y); /函数原型函数原型void main() int a(15), b(18); cout“调用调用swap前的输出前的输出: a=”a“,b=bendl; swap (&a, &b); cout“调用调用swap的输出的输出: a=”a“,b=bendl; voi
31、d swap(int *x, int *y) int temp; cout“交换前的输出交换前的输出: *x=”*x“,*y=*yendl; temp=*x; *x=*y; *y=temp; cout“swap函数输出函数输出: *x=”*x“,*y=*yendl; 调用调用swap前的输出前的输出: a=15,b=18交换前的输出:交换前的输出:*x=15,*y=18swap函数的输出:函数的输出:*x=18,*y=15调用调用swap的输出的输出: a=18,b=152424传地址方式的一个典型应用传地址方式的一个典型应用 使用传地址的方式可以使函数得到使用传地址的方式可以使函数得到不止不
32、止一一个个返回值。返回值。 例:求解方程例:求解方程ax2+bx+c=0#include #includefun (double, double, double, double *, double *);main()double a, b, c, x1, x2;cinabc;if(fun(a, b, c, &x1, &x2)cout“x1=“x1“, x2=“x2endl;elsecout“无实数根n”;fun (double a, double b, double c, double *x1, double *x2)double t;t=b*b-4*a*c;if(t0)ret
33、urn 0;else t=sqrt(t);*x1=(-b+t)/(2*a); *x2=(-b+t)/(2*a);return 1; 2525l 函数的引用调用函数的引用调用 引用是给已知变量起个别名。引用是给已知变量起个别名。 引用作形参时,可以被认为是实参的一个引用作形参时,可以被认为是实参的一个别名,别名,传递后形参和实参实际是同一个量传递后形参和实参实际是同一个量。对形参的任何操作都直接作用于实参。形对形参的任何操作都直接作用于实参。形参变化,对应实参值也发生了变化。参变化,对应实参值也发生了变化。 引用调用与传地址调用的效果是一样的,引用调用与传地址调用的效果是一样的,但它比传地址调用
34、更方便、直观。但它比传地址调用更方便、直观。/P85例例4.9#include void swap(int &x, int &y); /函数原型函数原型void main() int a=15,b=18; cout主函数第主函数第1次输出次输出:“; couta=a“, b=bendl; swap(a, b); cout主函数第主函数第2次输出次输出: ;couta=a“, b=bendl;void swap(int &x, int &y) int temp; temp=x; x=y; y=temp;2626#include void F1(int &x
35、, int &y) x*=x;y*=2;void main() int x=3, y=4;F1(x, y);cout“x=”x“, y=”yendl;x=9,y=8#include void F1(int &y, int &x) x*=x;y*=2;void main() int x=3, y=4;F1(x, y);cout“x=”x“, y=”yendl;x=6,y=162727参数传递方式小结参数传递方式小结l 值的传递(值的传递(passing by value)数值传递机制:数值传递机制:形参是变量,实参也是变量或形参是变量,实参也是变量或常数(或表达式),调用
36、中行参发生改变,不常数(或表达式),调用中行参发生改变,不影响实参原来的值。影响实参原来的值。地址传递机制:地址传递机制:形参是指针,实参是地址。形形参是指针,实参是地址。形参改变,实参相应改变。参改变,实参相应改变。l 引用传递(引用传递(passing by reference)形参是引用(别名),实参是变量。实参和形形参是引用(别名),实参是变量。实参和形参实际是同一变量。形参改变,实参改变。参实际是同一变量。形参改变,实参改变。引用与引用与传地址传地址更加接近。更加接近。更加方便、直观和安全更加方便、直观和安全2828l 函数的参数是数组函数的参数是数组 形参是一个指向数组的指针,实参
37、是形参是一个指向数组的指针,实参是数组的首地址。数组的首地址。l 函数的返回值是数组函数的返回值是数组 一般返回一个指针即可一般返回一个指针即可数组与函数的关系数组与函数的关系2929数组作为函数的参数数组作为函数的参数当数组整体作为函数的参数时,当数组整体作为函数的参数时,采用传地址采用传地址的方法,避免了成批数据在形参和实参之间的方法,避免了成批数据在形参和实参之间进行复制。进行复制。地址可以用数组名,也可以用指向数组的指地址可以用数组名,也可以用指向数组的指针。针。例子:例子:P86,例,例4.10,数组排序,数组排序#include void sort (int *a); /函数原型函
38、数原型void main()int s10=2,3,5,1,7,9,0,4,8,6;sort(s);/实参是数组名,即数组地址实参是数组名,即数组地址for(int i=0; i10; i+) coutsi ;coutendl; void sort(int *a) /形参是指针形参是指针int temp;for(int i=0; i9; i+)for(int j=i+1; jaj)/*(a+i) temp=ai; ai=aj; aj=temp; #include void sort (int a10); /函数原型函数原型void main()int s10=2,3,5,1,7,9,0,4,8
39、,6;sort(s); /实参是地址实参是地址for(int i=0; i10; i+) coutsi ;coutendl; void sort(int a10)/形参形参形式上形式上是一个数组是一个数组int temp;for(int i=0; i9; i+)for(int j=i+1; jaj) temp=ai; ai=aj; aj=temp; #include void sort (int a);void main()int s10=2,3,5,1,7,9,0,4,8,6;sort(s); /实参是数组实参是数组for(int i=0; i10; i+) coutsi ;coutendl
40、;void sort(int a)/ 形参是数组形式形参是数组形式int temp;for(int i=0; i9; i+)for(int j=i+1; jaj) temp=ai; ai=aj; aj=temp; #include void sort (int a50);void main()int s10=2,3,5,1,7,9,0,4,8,6;sort(s); /实参是数组实参是数组for(int i=0; i10; i+) coutsi ;coutendl;void sort(int a100)/ 形参是数组形式形参是数组形式int temp;for(int i=0; i9; i+)fo
41、r(int j=i+1; jaj) temp=ai; ai=aj; aj=temp; #include void sort (int *a);void main()int s10=2,3,5,1,7,9,0,4,8,6;int *p=s;sort(p); /实参是指针所保存的地址实参是指针所保存的地址for(int i=0; i10; i+) coutsi ;coutendl; void sort(int *a) /形参是指针形参是指针int temp;for(int i=0; i9; i+)for(int j=i+1; jaj) temp=ai; ai=aj; aj=temp; #inclu
42、de void sort (int *a); /原型和定义原型和定义看起来看起来不一样不一样void main()int s10=2,3,5,1,7,9,0,4,8,6;int *p=s;sort(p); /实参是指针所保存的地址实参是指针所保存的地址for(int i=0; i10; i+) coutsi ;coutendl; void sort(int a) /形参是数组形式形参是数组形式int temp;for(int i=0; i9; i+)for(int j=i+1; jaj) temp=ai; ai=aj; aj=temp; 3030/ P87例例4.11#include void
43、 fun (int *p); /函数原型函数原型void main( )int a =2,4,6,8,10 ; fun(a); /调调fun()函数函数 for(int i=0; i5; i+) coutai ; cout=p; q-, p+ ) t=*q; *q=*p; *p=t; 3131二维数组作参数二维数组作参数l二维数组作函数参数时,二维数组作函数参数时,形参形参可以使用二维可以使用二维数组指针的各种等价形式:数组指针的各种等价形式: 二维数组:二维数组:x行数行数列数列数 省略行数的二维数组省略行数的二维数组x 列数列数 指针指针*pf 行指针行指针 (*px) 指针数组指针数组*
44、py 指针的指针指针的指针*pl二维数组作参数时,采用的是传地址方式。二维数组作参数时,采用的是传地址方式。3232P87,例,例4.12:求二维数组中每行元:求二维数组中每行元素的最大值及最大值所在列的位置。素的最大值及最大值所在列的位置。#include const int N= 5;void fmax(int (*p)N); /函数原型,函数原型,行指针作形参行指针作形参void main( ) int aNN=0, 0,-5,3,6,12, 1,-1,9,7,0, 0,1,3,-5,8, 0,1,-1,-2,0; fmax(a); /调调fmax( )函数,函数,数组名作实参数组名作实
45、参void fmax (int (*p)N) int i, j, r=0, c=0, hmax;for(i=0; iN; i+)hmax=*(*(p+i)+0); /pi0 for (j=0; jhmax)/pij hmax=*(*(p+i)+j); r=i; c=j; coutr c ;coutmax=hmaxendl; #include const int N= 5;void fmax(int *pN); /指针数组作形参指针数组作形参void main( ) int aNN=0, 0,-5,3,6,12, 1,-1,9,7,0, 0,1,3,-5,8, 0,1,-1,-2,0;int *
46、p= a0, a1, a2, a3, aN-1; fmax(p); /调调fmax( )函数,函数,指针数组名作实参指针数组名作实参void fmax (int *pN) int i, j, r=0, c=0, hmax;for(i=0; iN; i+)hmax=pi0; for (j=0; jhmax) hmax=pij; r=i; c=j; coutr c ;coutmax=hmaxendl; #include const int N= 5;void fmax(int *p); /指针的指针作形参指针的指针作形参void main( ) int aNN=0, 0,-5,3,6,12, 1,
47、-1,9,7,0, 0,1,3,-5,8, 0,1,-1,-2,0;int *q= a0, a1, a2, a3, aN-1; fmax(q); /调调fmax( )函数,函数,指针数组名作实参指针数组名作实参void fmax (int *p) int i, j, r=0, c=0, hmax;for(i=0; iN; i+)hmax=pi0; for (j=0; jhmax) hmax=pij; r=i; c=j; coutr c ;coutmax=hmaxendl; #include const int N= 5;void fmax(int pNN); /数组作形参,也可以没有行数数组作
48、形参,也可以没有行数void main( ) int aNN=0, 0,-5,3,6,12, 1,-1,9,7,0, 0,1,3,-5,8, 0,1,-1,-2,0; fmax(a); /调调fmax( )函数,函数,数组名作实参数组名作实参void fmax (int pNN) int i, j, r=0, c=0, hmax;for(i=0; iN; i+)hmax=pi0; for (j=0; jhmax)/pij hmax=pij; r=i; c=j; coutr c ;coutmax=hmaxendl; #include const int N= 5;void fmax(int *p
49、); /普通指针作形参普通指针作形参void main()int aNN=0, 0,-5,3,6,12, 1,-1,9,7,0, 0,1,3,-5,8, 0,1,-1,-2,0; fmax(a0); /初始地址作实参初始地址作实参/可不可以写成可不可以写成a00?写成?写成a呢?呢?void fmax(int *p) int i, j, r=0, c=0, hmax; for(i=0; iN; i+) hmax=*(p+0); for(j=0; jhmax) hmax=*(p+j); r=i; c=j; coutr c max=hmaxendl; p+=N; /修改指针,指向下一行修改指针,指
50、向下一行 33334. 6 函数与指针函数与指针 4. 6. 1 函数返回指针或返回引用函数返回指针或返回引用 1.指针型函数指针型函数 函数的返回值是一个指针(地址),则称该函数为函数的返回值是一个指针(地址),则称该函数为指针函数。指针函数主要用在当函数结束时,需要指针函数。指针函数主要用在当函数结束时,需要大量的数据从被调用函数返回调用函数的情况。大量的数据从被调用函数返回调用函数的情况。指针函数的定义形式:指针函数的定义形式:类型类型 *函数名函数名(参数参数) 3434#include const int N= 5;void fmax(int pN);void main()int a
51、NN=0,0,-5,3,6,12,1,-1,9,7,0, 0,1,3,-5,8,0,1,-1,-2,0;fmax(a);void fmax(int pN)int i, j, hmax;for(i=0; iN; i+)hmax=pi0;for(j=0; jhmax)hmax=pij;coutmax=hmaxendl;#include const int N= 5;int * fmax(int pN);/返回一个指针返回一个指针void main()int aNN=0,0,-5,3,6,12,1,-1,9,7,0, 0,1,3,-5,8,0,1,-1,-2,0;int *b;b=fmax(a);f
52、or(int i=0;iN;i+)coutbiendl;int * fmax(int pN)int i, j;static int hmaxN;for(i=0; iN; i+)hmaxi=pi0;for(j=0; jhmaxi)hmaxi=pij; return hmax;3535返回指针的函数使用时要注意:返回指针的函数使用时要注意: 不能把局部作用域内数据的地址作为不能把局部作用域内数据的地址作为返回值,因为函数返回后,函数的局部变返回值,因为函数返回后,函数的局部变量占有的空间被释放,量占有的空间被释放,引用已消失空间的引用已消失空间的地址是危险的地址是危险的。因此在因此在fmax( )
53、函数中将函数中将字符型指针数组字符型指针数组hmax声明为声明为static(静静态态),),这样在函数返回后静态变量不会消这样在函数返回后静态变量不会消失,对地址的引用是安全的。失,对地址的引用是安全的。36362. 返回引用返回引用 函数也可以函数也可以返回引用返回引用,系统在处理返回引用与,系统在处理返回引用与返回值时是有区别的:函数返回值时,系统生成一返回值时是有区别的:函数返回值时,系统生成一个返回值的副本(或称临时变量),由这个临时变个返回值的副本(或称临时变量),由这个临时变量给到调用函数的接受变量。而返回引用时,不生量给到调用函数的接受变量。而返回引用时,不生成副本,直接将引用
54、的值给到调用函数。成副本,直接将引用的值给到调用函数。 由于引用只是另一个量的别名,因此由于引用只是另一个量的别名,因此返回引用返回引用绝不能返回不在作用域范围内的变量(或对象)的绝不能返回不在作用域范围内的变量(或对象)的引用引用。因为一个变量(或对象)一旦退出其所在的因为一个变量(或对象)一旦退出其所在的作用域,对它的任何引用也就毫无意义。作用域,对它的任何引用也就毫无意义。 3737P97,例,例4.16:函数返回引用函数返回引用/P92例例4.16#include int &f1(int &a1); /函数函数f1( )返回引用返回引用int f2(int a2);vo
55、id main() int x=2; int b1=f1(x); int b2=f2(x); coutb1=b1 b2=b2endl; coutx=xendl;int &f1(int &a1)/a1和和x是一个变量是一个变量 a1+=a1; return a1; /返回值给了返回值给了a1,也就是,也就是xint f2(int a2)/将将x当时的值(当时的值(4)复制给)复制给a2 a2+=a2; return a2; /b1得到的是得到的是a2的值的值8。int &f1(int &a1)int aa;aa=a1*2;return aa; /错误错误改为改为f
56、1(x);int b1=x;结果相同结果相同38384. 6. 2 函数指针函数指针l 函数也占据内存空间,即函数也占据内存空间,即函数函数也有地址也有地址。因此。因此可以声明一个可以声明一个指向函数的指针指向函数的指针,可以通过这个,可以通过这个指针调用函数。这个指针就成为函数指针。指针调用函数。这个指针就成为函数指针。声明函数指针的一般形式:声明函数指针的一般形式:类型类型 (* *指针)(参数表)指针)(参数表)注意:类型是被指函数的返回值的类型。注意:类型是被指函数的返回值的类型。对比:对比: int *f1(int a, int b )/函数函数 int (*f2)(int a, i
57、nt b);/指针指针3939#includedouble f1(double x, double y)return x+y;void main()double z;double (*p)(double a, double b);p=f1;z=(*p)(3.14, 1.23);/z=f1(3.14, 1.23);coutz=zendl;#includedouble f1(double x, double y)return x+y;void main()double z;double (*p)(double, double)=f1;z=(*p)(3.14, 1.23);coutz=zendl;4
58、040l 主要用途:如果函数的参数是函数。主要用途:如果函数的参数是函数。实参是具体用到的函数名,而形参只实参是具体用到的函数名,而形参只能是一个指向函数的指针。能是一个指向函数的指针。/使用一个指向函数的指针使用一个指向函数的指针#include #includedouble fun(double (*f1)(double),double (*f2)(double), double x)return (*f1)(x)/(*f2)(x);void main()coutfun(sin,cos,3.14/6)endl;coutfun(cos,sin,3.14/6)endl;414110151)co
59、s5sin3()(2g1(x)nnnnxnxxgxl P93P93例例4.174.17:编写能完成各种有限:编写能完成各种有限级数的求和函数,调用它,分别级数的求和函数,调用它,分别求:求: 4242/求和求和double sig(double x) double s=0.0; for(int n=1; n=5; n+) s+=x; return s;/被加的不是被加的不是x,而是,而是g1(x)=xndouble sig(double x) double s=0.0; for(int n=1; n=5; n+) s+=g1(x, n); return s;/g1(n)的功能是可以求出的功能是
60、可以求出x的的n次方次方double g1(double x, int n)double s1=1; for(int i=1; i=n; i+) s1*=x; return (s1);/被加的可能是被加的可能是g1(x, n),也可能是,也可能是g2(x, n)/g2(x, n)=3*sin(n*x)+5*cos(n*x)double sig(double x) double s=0.0; for(int n=1; n=5; n+) s+=g1(x, n); return s;double g1(double x, int n)double s1=1; for(int i=1; i=n; i+) s1*=x; return (s1);double g2(double x, int n)double s2;s2=3*sin
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 补充协议没执行原合同
- 装修保洁合同免责协议
- 订未交完协议结案合同
- 设备长期维修合同范本
- 账务调整服务合同范本
- 购买猪饲料的合同范本
- 购销装修材料合同范本
- 路基工程施工合同范本
- 路面劳务分包合同范本
- 转让房源出租合同范本
- 冬季食品安全培训讲座课件
- 2025北京中国人民大学通州校区建设部招聘1人考试参考试题及答案解析
- 压缩空气储能技术在地下钢内衬储气库中的应用与结构参数敏感性分析
- 基坑坍塌事故专项应急预案桌面演练脚本(2篇)
- 国有企业服务采购操作规范TCFLP 0054-2022
- 2025年消防安全知识答题库(附答案)
- 喷漆外包管理办法
- 稽留流产的课件
- 租车挂靠协议书
- 绿色插画风小蝌蚪找妈妈绘本故事
- 掘进工区内部管理制度
评论
0/150
提交评论