8_函数1.0null第八章第八章 本章要点 本章要点函数的概念
函数的定义与调用
函数的递归调用
变量的作用域
函数的作用域
程序设计的艺术程序设计的艺术《三国演义》中有这样一段描写:
懿问曰:“孔明寝食及事之烦简若何?”使者曰:“丞相夙兴夜寐,罚二十以上皆亲览焉。所啖之食,日不过数升。”懿顾谓诸将曰:“孔明食少事烦,其能久乎?”
此话音落不久,诸葛亮果然病故于五丈原。
“事无巨细”,“事必躬亲”
管理学的观点是极其排斥这种做法的,认为工作必须分工,各司其职
其中的思想,在程序设计里也适用 假如不模块化假如不模块化读多少行的程序能让...
null第八章第八章 本章要点 本章要点函数的概念
函数的定义与调用
函数的递归调用
变量的作用域
函数的作用域
程序
的艺术程序设计的艺术《三国演义》中有这样一段描写:
懿问曰:“孔明寝食及事之烦简若何?”使者曰:“丞相夙兴夜寐,罚二十以上皆亲览焉。所啖之食,日不过数升。”懿顾谓诸将曰:“孔明食少事烦,其能久乎?”
此话音落不久,诸葛亮果然病故于五丈原。
“事无巨细”,“事必躬亲”
管理学的观点是极其排斥这种做法的,认为工作必须分工,各司其职
其中的思想,在程序设计里也适用 假如不模块化假如不模块化读多少行的程序能让你不头疼?
main()当中能放多少行程序?
假如printf()函数由10行代码替换,那么你见过的程序会成什么样子?
如果所有代码都在main()当中,怎么团队合作?
如果代码都在一个文件中,怎么团队合作?概述C是模块化程序设计语言 概述为什么使用函数为什么使用函数void main()
{
::::::
x=x*x*x;
y=y*y*y;
z=z*z*z;
ans1=x+y+z;
a=a*a*a;
b=b*b*b;
c=c*c*c;
ans2=a+b+c;
:::::
}重复多次的同一计算类型void main()
{
::::::
ans1=cube(x,y,z);
ans2=cube(a,b,c);
:::::
}int cube(int a,b,c)
{
int ans;
ans=(a*a*a)+(b*b*b)+(c*c*c);
return ans;
}函数主程序ans函数可以把相对独立的某个功能抽象出来,使之成为程序中的一个独立实体。可以在同一个程序或其他程序中多次重复使用为什么使用函数为什么使用函数【例】编写一个儿童算术能力测试软件main()
{
char ans = 'y';
clrscr( );
cover( ); /*调用软件封面显示函数*/
password( ); /*调用密码检查函数*/
while (ans =='y'|| ans =='Y')
{ question( ); /*调用产生题目函数*/
answers( ); /*调用接受回答函数*/
marks( ); /*调用评分函数*/
results( ); /*调用结果显示函数*/
printf(“是否继续练习?(Y/N)\n”);
ans=getch ( );
}
printf(“谢谢使用,再见!”);
}
自定义函数为什么使用函数为什么使用函数【例二】编写一个儿童算术能力测试软件main()
{
char ans = 'y';
clrscr( );
cover( ); /*调用软件封面显示函数*/
password( ); /*调用密码检查函数*/
while (ans =='y'|| ans =='Y')
{ question( ); /*调用产生题目函数*/
answers( ); /*调用接受回答函数*/
marks( ); /*调用评分函数*/
results( ); /*调用结果显示函数*/
printf("是否继续练习?(Y/N)\n");
ans=getch ( );
}
printf("谢谢使用,再见!");
}
/*定义所用函数*/
cover() { } /*软件封面显示函数*/
password(){ } /*密码检查函数*/
question(){ } /*产生题目函数*/
answers(){ } /*接受回答函数*/
marks(){ } /*评分函数*/
results(){ } /*结果显示函数*/
这些函数现在不编程或还不会编程,可先放空。
可以多人合作,每人完成若干个函数(模块化)。
可在另一个源程序文件中定义。Let’s try…
函数机制的优点函数机制的优点使程序变得更简短而清晰
有利于程序维护
可以提高程序开发的效率
提高了代码的重用性
如果把编程比做制造一台机器,函数就好比其零部件。
可将这些“零部件”单独设计、调试、测试好,用时拿出来装配,再总体调试。
这些“零部件”可以是自己设计制造/别人设计制造/现在的
产品函数类型函数类型 库函数:
由C语言系统提供;
用户无须定义,也不必在程序中作类型说明;
只需在程序前包含有该函数定义的头文件; 自定义函数:
用户在程序中根据需要而编写的函数;
main()
{ float x=2,y;
y=sqrt(x);
printf(“\ny=%.3f”, y);
}必须加上math.h这个头文件#include
函数定义函数定义函数类型 函数名(形参类型说明)
{
说明部分
语句部分
}现代风格:合法标识符函数返回值类型
缺省int型函数体<例> 有参函数(现代风格)
int max(int x,int y)
{ int z;
z=x>y?x:y;
return(z);
}<例>无参函数
printstar( )
{ printf(“**********\n”); }
或
printstar(void )
{ printf(“**********\n”); }形式参数表:是用逗号分开的一组变量,用来接收调用时传入的数据。函数的数据类型就是函数返回值的类型,称为函数类型。 函数定义函数类型 函数名(形参表)
形参类型说明
{
说明部分
语句部分
}传统风格: int max(x,y)
int x,y;
{ int z;
z=x>y?x:y;
return(z);
}函数定义函数定义函数定义void displayDiscount()
{
float price, discount;
printf("请输入价格");
scanf("%f, &price);
discount = 0.75 * price;
printf("折扣额为 %f", discount);
}double max(double x, double y)
{
double m;
m=x>y?x:y;
return m;
}该函数名为displayDiscount,无参数,使用void说明无返回值,函数体内的语句用于根据产品的价格求折扣后的价格。该函数名为max,它有两个double类型的参数,返回值为double类型。在函数体内有三条语句实现了求两个数中较大的数,并将它返回。函数参数 形式参数(形参)和实际参数(实参)
形参:定义函数时函数名后面括号中的参数
实参:调用函数时函数名后面括号中的参数例 比较两个数大小
main()
{int a,b,c;
scanf("%d,%d",&a,&b);
c= max(a,b) ;
printf("Max is %d",c);
}
int max(int x,int y)
{int z;
z=x>y?x:y:
return(z);
}实参形参c=max(a, b); (main函数)int max(int x,int y) (max函数)
{int z;
z=x>y?x:y:
return(z);
}z函数参数函数参数说明
形参在函数被调用前不占内存;函数调用时为形参分配内存;调用结束,内存释放。
实参可以是常量、变量或表达式,但必须是确定的值
a=5;b=2;
c=max(3, a+b);
形参必须指定类型,形参与实参类型一致,个数相同
若形参与实参类型不一致,自动按形参类型转换-函数调用时转换
c=max(3.8, 9);
实参和形参数据传递是“值传递”,即单向传递函数参数函数参数353592534运行结果:
3,5,34main()
{ int a=3,b=5,c;
c = n2(a,b);
printf("%d,%d,%d",a,b,c);
}
int n2(int x,int y)
{ x=x*x;
y=y*y;
return(x+y);
}函数参数函数返回值通过函数调用使主调函数得到一个确定的值,这个值就是函数的返回值。
函数的返回值是通过函数中的return语句实现的
return语句的一般形式:
return(表达式);或 return 表达式;
return语句的功能:
使程序控制从被调用函数返回到主调函数中,同时把返回值带回给主调函数<例> 比较两个数大小
main()
{ int a,b,c;
scanf("%d,%d",&a,&b);
c=max(a,b);
printf("Max is %d",c);
}
int max(int x,int y)
{ int z;
z=x>y?x:y:
return(z);
}函数返回值函数返回值说明:
如果主调函数需要返回值,则一定要有return语句
如果主调函数不需要返回值,则不用return
函数中可以有多个returnmain()
{ int a;
a=m(3, 5);
printf("a=%d",a);
}
int max(int x,int y)
{ if (x>y) return x;
else return y;
}运行结果:
a=5函数返回值函数返回值函数返回值函数值的类型一般应与return语句中表达式值的类型一致,如若不一致,在函数调用时自动转换成函数值的类型<例> 比较两个数大小
main()
{ float a,b;
int c;
scanf("%f,%f",&a,&b);
c=max(a,b);
printf("Max is %d",c);
}
int max(float x,int y)
{ float z;
z=x>y?x:y:
return(z);
}输入:2.5,3.8
运行结果:
Max is 3函数值的类型决定return回去的类型函数返回值 如果函数中没有return语句,则返回值是一个无意义的值
如果希望函数没有返回值,则在函数名前加上voidprintstar()
{ printf("**********");
}
main()
{ int a;
a=printstar();
printf("%d",a);
} 10void printstar()
{ printf("**********");
}
main()
{ int a;
a=printstar();
printf("%d",a);
}编译出错良好的程序设计习惯
①为了使程序具有良好的可读性并减少出错,凡不要求返回值的函数都应定义为void类型;
②即使函数类型为int型,也不要缺省不写函数返回值函数调用 函数调用的一般形式:
函数名(实参表)
说明:
实参与形参个数相等,类型一致,按顺序一一对应
实参表的求值顺序,因系统而定(VC是自右向左) int f(int a,int b)
{ return(a+b);
}
main()
{ int i=2,p;
p=f( i, ++i);
printf("%d",p);
}main()
{ int i=2;
printf("%d,%d", ++i, i);
}63, 2函数调用函数调用 函数调用的方式:
函数调用语句(不需要函数返回值)
printstar();
函数表达式(要有一个确定的返回值)
c=2*max(a,b);
函数参数
例1:m=max(a,max(a,b));
例2:printf("%d",max(a,b));函数调用函数调用对被调用函数的声明和函数原型
在一个函数中调用另一个函数需具备的条件:被调用函数必须是已经存在的函数库函数:在程序开头将定义该库函数的头文件包含#include"*.h"自定义函数:要在主调函数中对被调函数作声明声明的作用:告诉编译系统函数名、参数个数及类型,以便检查。
要在主调函数中对被调函数作声明,是由函数原型来完成的。函数调用函数调用函数原型的一般形式:
函数类型 函数名(参数类型1 参数名1, 参数类型2 参数名2,…);
或函数类型 函数名(参数类型1, 参数类型2,…);main()
{float add(float x,float y);
float a,b,c;
scanf("%f,%f",&a,&b);
c=add(a,b);
printf("%f",c);
}
float add(float x,float y)
{return(x+y);}对函数add的声明也可以写成:
float add(float,float);函数调用函数调用函数原型的说明:
①被调函数定义在主调函数定义之前,不用作函数声明
②函数声明在所有函数定义之前,则在主调函数中不必对所调用的函数作声明
main()
{ float add(float x,float y);
float a,b,c;
scanf("%f,%f",&a,&b);
c=add(a,b);
printf("%f",c);
}
float add(float x,float y)
{ return(x+y);
}float add(float x,float y)
{ return(x+y);
}
main()
{ float a,b,c;
scanf("%f,%f",&a,&b);
c=add(a,b);
printf("%f",c);
}float add(float x,float y);
main()
{ float a,b,c;
scanf("%f,%f",&a,&b);
c=add(a,b);
printf("%f",c);
}
float add(float x,float y)
{ return(x+y);
}函数调用函数调用示例函数调用示例问题描述:
根据用户的选择求不同形状的面积。#include
void AreaOfRect();
void AreaOfTriangle();
void AreaOfRound();
void main()
{
int select;
do {
printf(" 0、退出\n 1、长方形\n 2、三角形\n 3、圆形\n");
printf("请选择功能:");
scanf("%d",&select);
if(select == 0) break;
switch(select) {
case 1 : AreaOfRect(); break; //长方形
case 2 : AreaOfTriangle(); break; //三角形
case 3 : AreaOfRound(); break; //圆形
default : printf("输入有误,请在 0~4 之间选择。\n");
}
}while(1);
}void AreaOfRect()
{
int x,y;
printf("请输入长方形的长:");
scanf("%d",&x);
printf("请输入长方形的宽:");
scanf("%d",&y);
printf("面积为:%d\n",(x * y));
} void AreaOfTriangle()
{
int x,y;
printf("请输入三角形的底:");
scanf("%d",&x);
printf("请输入三角形的高:");
scanf("%d",&y);
printf("面积为:%d\n",(x * y)/2);
} void AreaOfRound()
{
int r;
printf("请输入圆形的半径:");
scanf("%d",&r);
printf("面积为:%d\n",3.14*r*r);
}函数原型字符串处理库函数字符串处理库函数与字符串有关的库函数在头文件string.h中定义
要使用标准库字符串处理函数,程序前应该包含:
#include string.hstrlenstrcpystrcmpstrcatputs,gets……函数调用——库函数的调用null常用的字符串处理函数
字符串输出函数puts
:puts(字符数组)
功能:向显示器输出字符串(输出完,换行)
说明:字符数组必须以‘\0’结束字符串输入函数gets
格式:gets(字符数组)
功能:从键盘输入一以回车结束的字符串放入字符数组
中,并自动加‘\0’
说明:输入串长度应小于字符数组长度null字符串连接函数strcat
格式:strcat(字符数组1,字符数组2)
功能:把字符数组2连到字符数组1后面
返值:返回字符数组1的首地址
说明:字符数组1必须足够大
连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消,
新串最后加‘\0’常用的字符串处理函数
null字符串拷贝函数strcpy
格式:strcpy(字符数组1,字符串2)
功能:将字符串2,拷贝到字符数组1中去
返值:返回字符数组1的首地址
说明:字符数组1必须足够大
拷贝时‘\0’一同拷贝
不能使用赋值语句为一个字符数组赋值<例> char str1[20],str2[20];
str1={“Hello!”}; ()
str2=str1; ()常用的字符串处理函数
null<例> strcpy与strcat举例#include
#include
void main()
{ char destination[25];
char blank[] = " ", c[]= "C++",
turbo[] = "Turbo";
strcpy(destination, turbo);
strcat(destination, blank);
strcat(destination, c);
printf("%s\n", destination);
}Turbo C++null字符串比较函数strcmp
格式:strcmp(字符串1,字符串2)
功能:比较两个字符串
比较规则:对两串从左向右逐个字符比较(ASCII码),
直到遇到不同字符或‘\0’为止
返值:返回int型整数,
a. 若字符串1< 字符串2, 返回负整数
b. 若字符串1> 字符串2, 返回正整数
c. 若字符串1== 字符串2, 返回零
说明:字符串比较不能用“==”,必须用strcmp1常用的字符串处理函数
null#include
#include
main()
{
char username[15],pwd[15];
printf("\n 请输入用户名: " );
gets(username);
printf("\n 请输入密码: ");
gets(pwd);
if((strcmp(username,"John")==0) &&
(strcmp(pwd,"123456")==0))
printf("\n 您已成功登录 \n ");
else
printf("\n 用户名和/或密码无效 \n ");
} 请输入用户名: john
请输入密码: 123456
用户名和/或密码无效 请输入用户名:John
请输入密码: 123456
您已成功登录null字符串长度函数strlen
格式:strlen(字符数组)
功能:计算字符串长度
返值:返回字符串实际长度,不包括‘\0’在内<例>对于以下字符串,strlen(s)的值为:
(1)char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’};
(2)char s[ ]=“\t\v\\\0will\n”;
(3)char s[ ]=“\x69\082\n”; 答案:1 3 1常用的字符串处理函数
null#include
#include
main()
{
char arr[] = "Beijing";
int len1, len2;
len1 = strlen(arr);
len2 = strlen("Shanghai");
printf("\n string = %s length = %d", arr, len1);
printf("\n string = %s length = %d \n","Shanghai",len2);
} string = Beijing length = 7
string = Shanghai length = 8编程练习编程练习——编程验证歌德巴赫猜想nullint sushu(int x)
{ int i;
for( i=2;i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3;i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
<例>歌德巴赫提出:一个不小于6的偶数必定能表示为两个素数之和,例如:6=3+3, 8=3+5,10=3+7,·············
编程验证此猜想,要求用户输入任意一个不小于6的偶数时,打印出它所能分解成的两个素数。/*是素数,该函数返回1,否则返回0*/如果i是素数,并且n-i也是素数,则可以将一个偶数n表示为两个素数之和:n=i +(n-i)程序的执行过程nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=3x=3i=2i<=3/2 ?循环终止1nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=31x=9i=2i<=9/2 ?不执行if语句i=3if语句为真,执行return,返回到被调用处if为假01nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=310nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=3i=5x=5i=2i<=5/2 ?if为假
不执行returni=3循环终止x=71nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=5x=7当x=7时,if语句一直为假11nullint sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}
main()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}
/*是素数,该函数返回1,否则返回0*/input a number(>=6):12i=511if为真屏幕显示:
12=5+7nullmain()
{ int n, i, j;
printf(“\ninput a number(>=6):”);
scanf(“%d”, &n);
for(i=3; i<=n/2; i+=2)
if( sushu(i)&& sushu(n-i) )
printf(“\n%d=%d+%d”, n, i, n-i);
}int sushu(int x)
{ int i;
for( i=2; i<=x/2; i++)
if( x%i==0) return 0;
return 1;
}用户自定义函数main函数两次调用了用户自定义函数main:调用函数
sushu:被调用函数调用函数和被调用函数之间通过参数和返回值进行沟通调用函数被调用函数参数返回值实参对形参进行单向值传递return语句的用法及注意事项函数声明函数调用 函数调用 通过在程序中使用函数名称,可以执行函数中包含的语句,这称为调用函数
函数之间允许相互调用,也允许嵌套调用
函数还可以自己调用自己,称为递归调用
#include
void main()
{
:::::::::
set_discount();
displayDiscount();
::::::::
::::::::
}float set_discount()
{
::::::::::
::::::::::
}
float displayDiscount()
{
::::::::::
::::::::::
}函数嵌套调用 函数嵌套调用 void reverse()
{
::::::::::
::::::::::
}#include
void main()
{
:::::::::
palindrome();
::::::::
::::::::
}void palindrome()
{
::::::::
reverse();
::::::::
}从一个函数调用另一个函数称为函数的嵌套调用 函数嵌套调用 【例】求两个正整数a、b的最小公倍数。
最小公倍数可按下面的公式求出:
最小公倍数=
若要求最小公倍数则必先求最大公约数
可分别用三个函数实现各部分功能
(1) 用函数hcf(m,n)求m,n的最大公约数;
(2) 用函数lcd(x,y)求x,y的最小公倍数;
(3) 在主函数中进行输入和输出;
函数嵌套调用 nullint hcf(int m,int n)
{ int t,r;
r=m%n;
while(r!=0)
{m=n;
n=r;
r=m%n; }
return(n);
}int lcd(int x,int y)
{
int h,l;
h=hcf(x,y);
l=(x*y)/h;
return(l);
}main()
{
int s,a,b;
scanf("%d%d",&a,&b);
s=lcd(a,b);
printf("最小公倍数为:%d",s);
}设输入为98 和32则x=98
y=32则m=98
n=32返回4nullint hcf(int m,int n)
{ int t,r;
r=m%n;
while(r!=0)
{m=n;
n=r;
r=m%n; }
return(n);
}int lcd(int x,int y)
{
int h,l;
h=hcf(x,y);
l=(x*y)/h;
return(l);
}main()
{
int s,a,b;
scanf("%d%d",&a,&b);
s=lcd(a,b);
printf("最小公倍数为:%d",s);
}设输入为98 和32则x=98
y=32h=4返回784nullint lcd(int x,int y)
{
int h,l;
h=hcf(x,y);
l=(x*y)/h;
return(l);
}main()
{
int s,a,b;
scanf("%d%d",&a,&b);
s=lcd(a,b);
printf("最小公倍数为:%d",s);
}设输入为98 和32int hcf(int m,int n)
{ int t,r;
r=m%n;
while(r!=0)
{m=n;
n=r;
r=m%n; }
return(n);
}s=784函数递归调用 函数递归调用 /* 此函数用于计算 a 的阶乘 */
int factorial(int a)
{
if (a == 1)
return 1;
else
{
a = a * factorial(a-1);
return a;
}
}在一个函数体内调用自身称为函数的递归调用 null<例>汉诺塔问题
汉诺塔(Hanoi)问题是一个著名的问题,其初始模型如图
所示。其来源据说是在约19世纪末欧洲的商店中出售一种智力玩
具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大
顺序串着由64个圆盘构成的塔,游戏的目的是将最左边A杆上的
圆盘,借助最右边的C杆,全部移到中间的B杆上,条件是一次
仅能移动一个盘,且不允许大盘放在小盘的上面。64
片初始杆中间杆目的杆18,446,744,073,709,551,615次1844亿亿次。每次1微秒,需要60万年1
nnull先考虑二片的情况:A杆B杆C杆移动方法:
1. 将上面小片移到B杆上。
2. 将下面的大片由A杆移到C杆上。
3. 将B杆上的小片移到C杆上。nullA杆B杆C杆以移动二片的思路,考虑 N 片的情况:移动方法:
1. 将上面(N-1)片移到B杆上。
2. 将下面的第 N 片由A杆移到C杆上。
3. 将B杆上的(N-1)片移到C杆上。nullhanoi( n, one, two, three )
{
hanoi( n-1, one, three, two );
move( one, three );
hanoi( n-1, two, one, three );
}If( n == 1) move( one, three );
else
{
}null<例> Hanoi问题void move(char getone, char putone)
{ printf("%c--->%c\n",getone,putone); }
void hanoi(int n,char one,char two,char three)
{ if(n==1) move(one,three);
else
{ hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
main()
{ int m;
printf("Input the number of disks:");
scanf("%d",&m);
printf("The steps to moving %3d disks:\n",m);
hanoi(m,'A','B','C');
}null变量的作用域和存储类 1、定义语句出现的位置——作用域问题
2、变量值存在时间的长短(是否保留变量)
——生存期问题变量必须先定义,后使用。此外,还涉及到如下问题:变量的作用域变量的作用域作用域是某些事物起作用或有效的区域。限于陆地限于海洋限于空中变量的作用域和存储类 null程序中变量也有不同的使用范围,称为变量的作用域。变量的作用域决定变量的可访问性void displayDiscount()
{
float discount;
. . .
. . .
. . .
}
局部变量:不能在函数外使用float discount;
void main()
{
. . .
. . .
}
void displayDiscount()
{
. . .
. . .
}全局变量:可以在整个程序中使用变量的作用域和存储类 null局部变量---内部变量
定义:在函数内定义,只在本函数内有效
说明:
main中定义的变量只在main中有效
不同函数中同名变量,占不同内存单元
形参属于局部变量
可定义在复合语句中有效的变量运行结果:
main:a=3,b=4
sub:a=6,b=7
main:a=3,b=4局部变量和全局变量运行结果:5 4 3 2 1变量的作用域和存储类 null全局变量---外部变量
定义:在函数外定义,可为本文件所有函数共用
有效范围:从定义变量的位置开始到本源文件结束,及有extern说明的其它源文件若外部变量与局部变量同名,则外部变量被屏蔽局部变量和全局变量变量的作用域和存储类 null运行结果:max=8局部变量和全局变量变量的作用域和存储类 变量的存储类型变量的存储类型 存储类别:
了变量在计算机内部的存放位置→决定变量的“寿命”(何时“生”,何时“灭”)
一个完整的变量说明格式如下:
存储类别 数据类型 变量名
如 static int x , y ;
C程序的存储类别有:
■ register型(寄存器型)
■ auto型(自动变量型)
■ static型(静态变量型)
■ extern型(外部变量型)变量的作用域和存储类 C程序的变量存储位置C程序的变量存储位置变量的生存期
静态存储区中的变量:与程序“共存亡”
动态存储区中的变量:与函数“共存亡”
寄存器中的变量:同动态存储区C程序的变量存储类别C程序的变量存储类别变量的生存期
静态存储区中的变量 与程序“共存亡”
动态存储区中的变量 与函数“共存亡”
寄存器中的变量 同动态存储区■ register型(寄存器型)
变量值存放在运算器的寄存器中——存取速度快,一般只允许2~3个,且限于char型和int型,通常用于循环变量
■ auto型(自动变量型)
变量值存放在主存储器的动态存储区(堆栈方式);
优点——同一内存区可被不同变量反复使用。
以上两种变量均属于“动态存储型”,即调用函数时才为这些变量分配单元,函数调用结束其值自动消失。变量的作用域和存储类 C程序的变量存储类别C程序的变量存储类别变量的生存期
静态存储区中的变量 与程序“共存亡”
动态存储区中的变量 与函数“共存亡”
寄存器中的变量 同动态存储区■ static型(静态变量型)
变量值存放在主存储器的静态存储区
程序执行开始至结束,始终占用该存储空间
■ extern型(外部变量型)
同上,其值可供其他源文件使用
以上两种均属于“静态存储”性质,即从变量定义处开始,在整个程序执行期间其值都存在(≠都可用!!)未说明存储类别时,
函数内定义的变量默认为auto型
函数外定义的变量默认为extern型。变量的作用域和存储类 null例:
f(int a)
{ auto int b=0; /*自动变量:每次调用都重新初始化*/
static int c=3; /*静态局部变量:只在编译时赋初值1次*/
b=b+1;
c=c+1;
return(a+b+c);
}
main()
{ int a=2,i;
for(i=0;i<3;i++)
printf(“%d”,f(a));
}局部static变量具有全局寿命和局部可见性
局部static变量具有可继承性变量的作用域和存储类 nullmain()
{ void increment(void);
increment();
increment();
increment();
}
void increment(void)
{ int x=0;
x++;
printf(“%d\n”,x);
}<例>局部静态变量值具有可继承性运行结果:1
1
1main()
{ void increment(void);
increment();
increment();
increment();
}
void increment(void)
{ static int x=0;
x++;
printf(“%d\n”,x);
}运行结果:1
2
3练习练习7.编写函数fun,它的功能是:求出一个字符串中指定的字符的个数,并返回此值。例如,若输入字符串:123412132,输入字符为:1,则输出3。
8.编写函数fun,它的功能是:在字符串中的数字字符前加一个$字符。例如,输入a1b23cd45,则输出为a$1b$2$3cd$4$5.
9.编写函数fun,它的功能是:计算一个字符串中子串出现的次数,并返回此值。例如,若输入主字符串:abaabhoyabat,输入子字符串:ab,则输出为3。
10.编写函数fun,其功能是:将s所指字符串中ASII值为偶数的字符删除,串中剩余字符形成一个新串放在t所指的数组中。例如,若s所指字符串中的内容为ABCDEDG12345,其中字符B的ASCII码值为偶数应当删除,其他依次类推。最后t所指的数组中的内容应是ACEG135.null
11.编写函数fun,它的功能是:求出4*5二维数组周边元素之和,作为函数值返回。二维数组中的值在主函数中赋予。
12.编写函数fun,其功能是:求处一个2*4整型二维数组中最大元素的值,并将此值返回调用函数。
本文档为【8_函数1.0】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。