null第六章 函 数第六章 函 数——结构化程序
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
基础6.1函数的概念6.1函数的概念 结构化程序设计要求一种自顶向下的设计方法,也就是将复杂
的系统划分为相对独立的,功能较为单一的子系统的组合。 每个子系统称为模块,在C语言中表现为函数。复杂问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
main()abca1a2b1b2c1c2各模块之间的关系称之为接口。优点: 函数实现的功能单一
完整,可以独立设计,单
独调试。易于维护,通用
性强。null【例6-1】通过函数求两个数的最大值。/*example 6-1 通过函数求最大值 */
#include
int GetMax(int ,int); /* 函数的原型声明 */
void main(void)
{
int a,b,c,d; /* 说明变量 */
scanf("%d,%d,%d",&a,&b,&c);
d = GetMax(a,b); /* 调用函数GetMax求a、b的较大值赋给d */
d = GetMax(d,c); /* 调用函数GetMax求d、c的较大值赋给d */
printf("The Maximum of a,b,c is %d\n",d);
}
int GetMax(int x,int y)
{
int max;
if(x > y)
max = x; /* x>y成立,x为较大值 */
else
max = y; /* x>y不成立,y为较大值 */
return max;
}函数的分类及调用过程函数的分类及调用过程 函数可分为标准库函数和用户自定义函数。标准库函数是C语言系统提供的一系列的实现特定功能的模块,如已经学习过的输入输出函数、数学函数、字符串处理函数等等。 对于用户自定义函数,用户必须完整地定义函数的接口以及函数的实现细节,然后通过数据接口调用函数以实现所需的功能 用户自定函数的使用,应包括两个过程: ⑴ 函数的定义:函数定义的作用就是确定函数的名称、接口、以及内部的实现细节。⑵ 函数的调用: 函数的调用是根据数据接口的定义,将实际数据传递给函数,函数执行其功能得到所需结果的过程。null【例6-2】通过标准函数及用户定义函数实现求字符串中含有的实际字符的数量,输出结果。/* example 6-2 通过函数输出字符串的实际长度 */
#include
#include
int GetStringLength(char *p); /*用户函数原型声明*/
void main(void)
{
char pszStr[80];
int iStrLen;
gets(pszStr); /*调用字符输入函数输入字符串*/
iStrLen = strlen(pszStr); /*调用标准库函数求字符串长度*/
printf("The string length is %d\n",iStrLen);
gets(pszStr);
iStrLen = GetStringLength(pszStr);/*调用用户定义函数求字符串长度*/
printf("The string length is %d\n",iStrLen);
}null/* 用户定义求字符串长度函数 */
/* 函数名 GetStringLength*/
/* 参数 指向字符的指针p */
/* 返回值字符个数,整型 */
int GetStringLength(char *p)
{
int iCount;
iCount = 0;
while(*p != '\0')
{
iCount++;
p++;
}
return iCount;
}6.2 函数的定义和调用6.2 函数的定义和调用 ⒈函数的基本结构#include
void main(void )
{
int a,b,c;
scanf ( “%d,%d” , &a, &b) ;
c=max( a , b);
printf (“%d” ‘c) ;
}
int max(int x ,int y)
{
int z ;
z=x>=y? x : y ;
return ( z) ;
}主函数函数体函数的类型,返回值的类型。 函数名(用标识符命名),引用函数的标志,并得到结果。函数参数说明表。定义!引用!(1)函数的名称
(2)函数的类型
(3)函数的形式参数
(4)函数体函数定义的目的函数定义的目的函数定义是要确定如下四点:
名称
函数的类型
函数的参数
函数的功能⒉函数的定义⒉函数的定义
格式
pdf格式笔记格式下载页码格式下载公文格式下载简报格式下载
:
type 函数名(参数说明表)
{
内部说明语句 ;
功能语句 ;
} 如果函数有返回值,应含有return语句。int max(int x ,int y)
{
int z ;
z=x>=y? x : y ;
return ( z) ;
}说明: ⑴函数不能嵌套定义,但可以嵌套引用,包括引用自己。int max(int x,int y)
{
…
int cx(int c,int d)
{
…
} /*Error !*/
…
} ⑵函数如果无返回值,type 应说明为空类型void。函数无参
数应定义成void。void Bell(void)
{
printf(“\007”);
}⒊函数的调用⒊函数的调用⑴调用形式:
函数名(实参表) 一般引用方式有三种:
语 句 形 式: max(a,b);
表达式形式: c=max(a, b)*2 ;
函 数 参 数: c=max (a , max (b , d )) ;null【例6-3】函数调用举例,通过函数求xn,在主函数中输入x及n,并调用该函数,输出结果。/* example 6-3 函数调用举例 */
#include
float GetPow(float,int); /* 函数原型声明 */
void main(void)
{
float x,y;
int n;
printf("Please input x,n:");
scanf("%f,%d",&x,&n); /*输入x,n*/
y = GetPow(x,n); /* 给出实参列表,调用函数 */
printf(“x^n=%f\n”,y); /* 将函数的返回值赋给y */
}
float GetPow(float x,int n) /* 函数定义,名称:GetPow */
{
float z;
int i;
z = 1;
for(i=1; i<=n;i++) /* 循环累乘 */
z*=x;
return z; /* 返回累乘积 */
}⑵调用过程⑵调用过程void main (void)
{
int a ,b ,c ;
scanf (“%d,%d” ,&a,&b );
c=max( a ,b );
printf (“%5d” ,c );
}
int max ( int x , int y )
{
int z ;
z=x>y? x : y ;
return (z) ;
} ⑴先计算实参的值,从右向左向函数传递调赋值给形参。23a
bX
y23 ⑵转移在函数中运行,执行到一个return语句,将返回表达式
的值。由函数名带回给调用函数。z3函数如果没有return语句,由最后一个}返回一个不确定的值!null【例6-4】定义返回两个浮点数之和的函数,在主函数中输入数据,并调用函数,输出结果。/* example 6-4 通过函数求两个浮点数之和 */
#include
float fAdd(float ,float); /* 函数原型声明 */
void main(void)
{
float a,b,c;
printf("Pleaes input two number a,b:");
scanf("%f,%f",&a,&b);
c = fAdd(a,b); /* 调用函数 */
printf("a+b=%f\n",c);
}
/*-------------------------*/
/* 函数名 fAdd */
/* 参数:x,y,float型 */
/* 返回值:x+y */
/*-------------------------*/
float fAdd(float x,float y)
{
float z;
z = x + y;
return z;
}关于返回值的几点说明:关于返回值的几点说明: ⑴函数可以通过一个return语句返回一个值,也可以不返回值,
此时应在定义函数时用void类型加以说明。 ⑵函数中可以出现多个return语句,遇到一个return 语句,则
返回值,且返回调用函数,继续执行。int max ( int x , int y )
{
if (x>=y ) return x ;
return y ;
} ⑶返回值的类型应与函数的类型一致,如不一致,以函数类型
为准,先转换为函数类型后,再返回。int max(void)
{
float z;
…
return z;/* z先转化为整型*/
} ⑷为了确保参数和返回值类型正确,一般须在函数调用前对其
类型和参数的类型加以说明,该说明称之为原型声明。int imax ( int ,int ) ;
void main (void )
{
int x,y,z ;
…
z=imax ( x,y ) ;
…
} 原型声明语句,加;举例:通过函数求 xn 。举例:通过函数求 xn 。#include
double pow(float , int) ;
void main(void)
{
int i ;
for (i=1; i <=9 ; i++)
printf ( “%d , %f \n” , i, pow(2.5 ,i));
}
double pow(float x ,int n )
{
int i ;
double p=1 ;
for (i=1 ; i<=n ; i++)
p=p*x ;
return ( p) ;
}原型声明。定义函数调用函数。专题:函数间的数据传递专题:函数间的数据传递 函数在调用的过程中,调用函数和被调函数存在数据的相互传
递。数据的传递包括两个方面:⑴将值传递给被调函数;⑵将被调函数的结果返回给调用函数。调用函数被调函数向被调函数传递值。将结果返回给调用函数。
函数间数据传递方式函数间数据传递方式⑴通过函数参数传值或传地址;
⑵通过返回值传递结果;
⑶通过全局变量传递参数或结果。⑴传值方式⑴传值方式 通过实参与形参的结合,将数据值传递给形参,形参的改变不
影响实参。#include
int splus (int , int ) ;
void main (void )
{ int a , b , c ;
scanf ( “ %d , %d” , &a ,&b) ;
c= splus ( a , b ) ;
printf ( “ a*b= %d \n ” , c ) ;
}
int splus (int x ,int y )
{ int z ;
z=x*y ;
return (z) ;
}调用函数被调函数x、y形参。a、b实参变量的值。传递参数a:2b:3y:x:32z:6返回值null【例6-5】参数值传递方式说明举例。/* example 6-5 函数参数值传递实例 */
#include
void ExamFun(int , int); /* 函数原型声明 */
void main(void)
{
int a,b;
printf("请输入两个整数a,b:");
scanf("%d,%d",&a,&b);
ExamFun(a,b); /* 以实参a、b值传递方式调用函数 */
printf("函数调用后a的值%d,b的值%d\n",a,b);
}
void ExamFun(int x, int y) /* 函数定义 */
{
int t;
t = x;
x = y;
y = t; /* 形参变量x,y交换 */
printf("x的值%d,y的值%d\n",x,y);
}⑵传地址方式⑵传地址方式 形参定义为指针,实参为变量的地址,被调函数通过地址可以
修改地址对应的变量。#include
void swap ( int * , int * );
void main (void )
{
int a , b ;
scanf ( “%d , %d ” , &a , &b ) ;
if (a
void Exchange(int *,int *); /*函数原型声明,参数为指向整型的指针*/
void main(void)
{
int a,b;
printf("请输入a,b:");
scanf("%d,%d",&a,&b);
if(a > b)
{/* 如果a>b调用函数实现a、b的交换 */
Exchange(&a,&b); /* 调用函数,实参为变量a,b的地址 */
}
printf("a=%d\nb=%d\n",a,b);
}
void Exchange(int *x,int *y) /* 函数定义 */
{
int t;
t = *x;
*x = *y;
*y = t; /* 通过间接运算,实现形参x、y指向对象的交换 */
}函数的原型声明函数的原型声明如果被调函数是以下三种情况,必须声明。
(1)被调函数定义在调用函数之后;
(2)被调函数是标准库函数;
(3)被调函数从其他文件连接加入。函数的原型声明语句可以取两种形式:
⑴ 只有参数类型而不带参数名的形式⑵ 带有参数名的形式函数的原型声明的说明函数的原型声明的说明⑴ 函数原型声明最好写在主函数之外的程序开始处,如果程序较大,并有自己的头文件时,函数原型声明应统一写在头文件中 。⑵ 原则上整型函数、定义在调用语句函数之前的函数可不加原型声明, ⑶ 标准库函数的原型声明都包含于函数对应的头文件中,因此,使用标准库函数时,应在程序的开始包含对应的头文件 。6.3 变量的作用域与生存期6.3 变量的作用域与生存期 变量是内存数据的抽象,即将内存地址、数据表示抽象成一个
符号。此外,变量还有存储类型,存储类型确定了变量在时间上的
生存期和空间上的作用域。按空间的作用域可分为:全局变量局部变量按时间的生存期可分为:静态存储变量动态存储变量变量的四种存储类型变量的四种存储类型⑴自动类型 auto⑵寄存器类型 register⑶静态类型 static⑷外部类型 extern变量的说明格式:存储类型 类型 变量名表;确定变量在内存中的表示方法。 确定变量的生存期和作用域。
该项省略表示auto存储类型。⒈auto存储类型(局部变量)⒈auto存储类型(局部变量)定义在复合语句的开始处。块内生存、块内有效。#include
void main(void)
{
auto int a,b;
scanf(“%d,%d”,&a,&b);
if(b>a)
{
int iTemp;
iTemp=a;
a=b;
b=iTemp;
}
printf(“Max=%d”,a);
}a
b
的
作
用
域iTemp的作用域。生存期: 执行到复合语句建立内存
变量。执行出复合语句变量消
亡。iTemp⒉register存储类型(局部变量) 作用域和生存期和auto相同,
差别在于,如果CPU内部的寄存
器空闲,则使用寄存器作为变量
的存储单元,以提高速度。主要
用于循环变量,且应该是整型和
字符型。null【例6-7】通过函数求两个数的较小值。/* example 6-7 通过函数求两个数的较小值 */
#include
int iGetMin(int,int); /* 函数原型声明 */
void main(void)
{
int a,b,c;
printf("Please input two number a,b:");
scanf("%d,%d",&a,&b);
c = iGetMin(a,b); /* 调用iGetMin函数 */
printf("The min is = %d\n",c);
}
int iGetMin(int x,int y) /* 函数定义 */
{
int z;
z = x < y ? x : y; /* 取x、y的最小值赋给z */
return z;
}⒊局部static(静态)存储类型⒊局部static(静态)存储类型 作用域:在说明的复合语句内引用,出了复合语句不可见。 生存期:从程序开始运行直到程序结束,执行出 { }时,原值
并不消失,只是不能引用。
void row (void) ;
void main ( void )
{
int b ;
for (b=1 ; b<=9 ; b++ )
row ( ) ;
}
void row (void )
{
int a=1 ;
int b ;
for (b=1 ; b<=9 ; b++)
printf ( “%5d” , a*b ) ;
printf ( “ \ n ”) ;
a++ ;
}CHAP6EX6staticCHAP6EX5说明静态变量。a的作用域生存期从编译开始到程序结束。⒋外部变量(extern存储类型、全局变量)⒋外部变量(extern存储类型、全局变量)外部变量是定义在任何模块之外的变量。也称为全局变量。作用域:从说明变量开始直到文件结束。 生存期:在程序的整个执行过程中。任何函数对外部变量的修
改都会影响其他函数对外部变量引用时的值。#include
void add(void);
int a,b,c;
void main(void)
{
scanf(“%d,%d”,&a,&b);
add( );
printf(“%d”,c);
}
void add(void)
{ c=a+b; }全局变量。作用域关于全局变量的几点说明:关于全局变量的几点说明:⑴全局变量可以通过说明改变其作用域。void main( )
{
…
}
int i; /* i为全局变量*/
void max(int a,int b)
{
…
}作用域extern i;新的作用域⑵全局变量可以被不同的文件共享。 file1.c file2.c
int a ; extern int a ;文件1定义的外部变量。 文件2通过说明使用文件1的外部变量。如果只希望在本文件中使用,可以加static说明。 static关于全局变量的几点说明:关于全局变量的几点说明: ⑶模块设计的原则:内聚性强,耦合性弱。全局变量的使用占
用内存资源且增加模块的耦合性,因此,应尽量不使用全局变量。 ⑷当模块中出现和全局变量同名的局部变量时,局部变量在模
块中优先。int a;
void main(void)
{
a=5;
…
}
void fun(…)
{
int a;
a=6;
}全局变量应用举例:用函数交换两个全局变量的值。全局变量应用举例:用函数交换两个全局变量的值。#include
int a,b;
void main(void)
{
scanf(“%d,%d”,&a,&b);
fun( );
printf(“a=%d,b=%d\n”,a,b);
}
void fun(void)
{
int c;
c=a; a=b; b=c;
}a、b外部变量。ab全局变量的副作用全局变量的副作用#include
int i;
void prt(void);
void main( void )
{
for(i=0;i<5;i++)
prt( );
}
void prt(void)
{
for(i=0;i<5;i++)
printf(“%c”,’*’);
printf(“\n”);
}函数的作用:打印五个*,再回车。几次调用函数?i==0i==0i==0i==0i==0i==1i==2i==3i==4i==5i==5i==5i==5i==5全局变量传递参数全局变量传递参数 全局变量可以被调用函数和被调函数共享,任何函数对全局变
量的修改都会影响到其他函数所见的全局变量的值。#include
int c ;
void main ( void)
{
int a ,b ;
scanf ( “ %d ,%d ” , &a ,&b ) ;
splus (a , b ) ;
printf ( “a*b =%d \n ” ,c ) ;
}
void splus (int x , int y )
{ c=x*y ; }说明全局变量c6 说明:应尽量少用全局变量,应使函数内部的内聚性强,函数
之间的偶合性弱。null【例6-8】使用全局变量,通过函数求两个浮点数的积。/* example 6-8 使用全局变量通过函数求两个浮点数的积 */
#include
float Mul(void); /* 函数原型声明 */
float a,b; /* 在所有函数之外说明,a、b为全局变量 */
void main(void)
{
float c;
printf("Please input two number a,b:");
scanf("%f,%f",&a,&b);
c = Mul( ); /* 调用Mul函数 */
printf("The a*b is = %f\n",c);
printf("a = %f\nb = %f\n",a,b);
}
float Mul(void) /* 函数定义 */
{
float z;
z = a*b; /* 通过全局变量a、b求积 */
a = 3.0;
b = 4.0;
return z;
}null【例6-9】函数中的auto存储类别变量的性质示例。/* example 6-9 函数中auto存储类别变量的性质 */
#include
void Mul(void) ; /* 函数原型声明 */
void main ( void )
{
int b ;
for(b=1 ; b<=9 ; b++ )
Mul( ) ; /* 循环9次调用Mul函数 */
}
void Mul(void ) /* 函数定义 */
{
int a=1; /* 具有auto存储类别的变量 */
int i;
for (i=1 ; i<=9 ; i++)
printf ("%5d", a*i );
printf ("\n") ;
a++;
}null【例6-10】在函数中使用register存储类别以提高效率。/* example 6-10 函数中使用register存储类别求级数1+2+...+n */
#include
int Ser(int) ; /* 函数原型声明 */
void main ( void )
{
int n,sum;
printf("Please input n:");
scanf("%d",&n);
sum = Ser(n); /* 调用函数求级数之和 */
printf("1+2+...+%d = %d\n",n,sum);
}
int Ser(int x) /* 函数定义 */
{
register int i; /* 说明register存储类别变量 */
int s;
s = 0;
for(i=1; i<=x;i++)
{
s += i;
} /* i用于循环控制变量以提高速度 */
return s;
}null【例6-11】在函数中使用static存储类别实现输出9×9的乘法表。/* example 6-11 函数中static存储类别变量的性质 */
#include
void Mul(void) ; /* 函数原型声明 */
void main ( void )
{
int b ;
for(b=1 ; b<=9 ; b++ )
Mul( ) ; /* 循环9次调用Mul函数 */
}
void Mul(void ) /* 函数定义 */
{
static int a=1; /* 具有static存储类别的变量 */
int i;
for (i=1 ; i<=a ; i++)
printf ("%5d", a*i );
printf ("\n") ;
a++; /* 静态局部变量本次调用递增,下次调用维持 */
}null【例6-12】动态存储及静态存储变量的初值案例。/* example 6-12 动态存储与静态存储的初值 */
#include
int a; /* 全局变量为静态存储,初值为0 */
void main ( void )
{
auto int b;
register int c; /* 动态存储变量初值随机 */
static int d; /* 静态存储初值为0 */
printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
}null【例6-13】全局变量与局部变量同名的处理。/* example 6-13 全局变量与局部变量同名的处理方式示例 */
#include
int Fun(int);
int a = 2; /* 说明全局变量 */
void main (void)
{
int c,a=6; /* 局部变量a与全局变量同名,局部变量优先 */
printf("This a is location = %d\n",a);
c = Fun(a); /*a 是本函数说明的局部变量,初值为6 */
printf("c=%d\n",c);
}
int Fun(int x) /* 函数定义 */
{
printf("This a is extern = %d\n",a); /* 本函数a为全局变量 */
return a+x;
}null【例6-14】全局变量在程序中的副作用。/* example 6-14 全局变量的副作用 */
#include
int i; /* 说明全局变量 */
void Prt(void); /* 函数原型声明 */
void main(void)
{
for(i=0;i<5;i++)
Prt( );
printf("-----End-----\n");
}
void Prt(void) /* 定义函数 */
{
for(i=0;i<5;i++)
printf(“%c”,‘#’); /* 循环5次,打印5个# */
printf(“\n”); /*换行*/
}6.4 数组与函数参数6.4 数组与函数参数 问题:引用数组时只能引用数组元素。如果用参数传递数组元
素,则函数需要参数的量太多。为了解决此问题,可以通过指针传
递数组的地址。一维数组作为函数参数定义有三种方式:⒈形参为指针; int ave( int *p)
⒉形参为无下标数组; int ave(int a[ ])
⒊形参为有下标数组。 int ave(int a[10])3种数组作为函数参数:⒈一维数组作为函数参数;
⒉二维数组作为函数参数;
⒊字符数组作为函数参数举例:通过函数求数组元素的平均值。举例:通过函数求数组元素的平均值。#include
float mean( int *, int) ;
void main (void)
{
int array[10]={1,2,3,4,5,6,7,8,9,10} ;
float av ;
av=mean(array,10) ;
printf( “av=%f \n %d ” ,av ,array [0] ) ;
}
float mean( int *data ,int num )
{
int i ;
float avg=0 ;
for (i=0 ; i
void StrLow(char *ps);
void main(void)
{
char szStr[80];
gets(szStr);
StrLow(szStr);
puts(szStr);
}
void StrLow(char *ps)
{
int i;
for(i = 0; ps[i] !='\0'; i++)
{
if(ps[i] >= 'a' && ps[i] <= 'z')
{
ps[i] -= 32;
}/*End of if*/
}/*End of for*/
}null【例6-15】通过函数求数组的最大值,主函数调用并输出结果。/* example 6-15 通过函数求数组的最大值一维数组作为函数参数 */
#include
int GetMax(int *,int); /* 函数原型声明 */
void main(void)
{
int a[10] = {51,99,80,75,66,30,95,86,74,68};
int iMax;
iMax = GetMax(a,10);
printf("\nMax of a is %d\n",iMax);
}
/* 函数定义 */
/* 参数1:p指向整型的指针,用于传递数组的首地址 */
/* 参数2:num表示数组元素的个数 */
/* 返回值:数组元素的最大值 */
int GetMax(int *p, int num)
{
int max,i;
max = *p; /* 假定第一个元素为最大值 */
for(i=1 ; imax)
max = *(p+i);
}
return max;
}null【例6-16】通过函数将数组按升序排序,主函数调用并输出结果。/* example 6-16 通过函数对数组排序一维数组作为函数参数 */
#include
void Sort(int *,int); /* 函数原型声明 */
void main(void)
{
int i;
int a[10] = {51,99,80,75,66,30,95,86,74,68};
for(i=0;i<10;i++)
printf("%4d",a[i]); /* 输出原始数据 */
printf("\n");
Sort(a,10); /* 调用函数对数组排序 */
for(i=0;i<10;i++)
printf("%4d",a[i]); /* 输出排序结果 */
printf("\n");
}null/* 函数定义 */
/* 参数1:x无下标数组,用于传递数组的首地址 */
/* 参数2:num数组元素的个数 */
/* 返回值:无 */
void Sort(int x[], int num)
{
int i,j;
for(i=0 ; i< num-1 ;i++)
{
for(j=i+1;jx[j])
{
int temp; /* 说明局部临时变量,用于交换 */
temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
}
}null【例6-17】通过函数求3行4列二维数组所有元素的累加和,在主函数调用并输出结果。/* example 6-17 */
/* 通过函数求二维数组所有元素的累加和,二维数组作为函数参数 */
#include
int Acc(int x[][4]); /* 函数原型声明 */
void main(void)
{
int i,j;
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int sum;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
printf("%3d",a[i][j]);
printf("\n");
}
sum = Acc(a); /*调用函数,二维数组数组名作为实参传递首地址*/
printf("Sum= %4d\n",sum); /* 输出结果 */
}null/* 函数定义 */
/* 参数:x省略行数的二维数组,用于传递数组的首地址 */
/* 返回值:所有元素的累加和 */
int Acc(int x[][4]) /* 形参x为指针 */
{
int i,j;
int sum;
sum = 0;
for(i=0;i<3;i++)
{
for(j=0;j<4;j++)
sum += x[i][j]; /* 通过形参表示的a[i][j] */
}
return sum;
}null【例6-18】通过函数将字符串中的所有小写字母转换成对应的大写字母,在主函数调用并输出结果。/* example 6-18 */
/* 通过函数将字符串中的所有小写字母转换成对应的大写字母 */
/* 字符数组作为函数参数 */
#include
void StrUpr(char *);/* 函数原型声明,参数为指向字符的指针 */
void main(void)
{
char str[80];
printf("Input Source String: ");
gets(str);
StrUpr(str); /*调用函数,字符数组名作为实参,传递数组的首地址*/
printf("Transformed String: ");
puts(str);
}null/* 函数定义 */
/* 函数功能: 将字符串中的小写字母转换成对应的大写字母 */
/* 函数名: StrUpr */
/* 函数参数: s用于传递数组的首地址 */
void StrUpr(char *s)
{
while(*s!='\0')
{
if(*s >= 'a' && *s <= 'z')
{
*s -= 32; /* 如果是小写字母,转换为对应的大写 */
}
s++; /* 指针指向下一字符 */
}
}6.5 返回指针的函数6.5 返回指针的函数 概念:函数可以返回一个值,也可以返回一个地址(指针),
如果函数返回地址,该函数称为返回指针的函数。定义:
type *函数名(形参表)
{
…
}int *max(int *a, int *b)例:通过返回最大值的地址求最大值例:通过返回最大值的地址求最大值#include
int *pMax(int *,int *);
void main(void)
{
int a,b,*p;
scanf("%d,%d",&a,&b);
p = pMax(&a,&b);
printf("最大值是 = %d\n",*p);
}
int *pMax(int *x,int *y)
{
return *x > *y ? x:y;
}例:通过函数在某字符串中搜索一个特定的字符第一次出现的地址,在主函数调用并输出结果。 例:通过函数在某字符串中搜索一个特定的字符第一次出现的地址,在主函数调用并输出结果。 /* example6-19 */
/* 在字符串中查找给定的字符第一次出现的位置,返回其地址 */
#include
#include
char *Search( char * , char ) ; /* 函数原型声明 */
void main ( void)
{
char c , *p , str[80];
gets(str );
scanf( "%c" , &c);
p = Search(str ,c ); /* 调用函数 */
if (p==NULL )
printf ("char %c not found\n", c ) ;
else
printf ("The position is: %d\n" ,p-str ) ;
}续例:续例: /* 函数名: Search */
/* 函数参数1: p指向字符的指针,用于传递字符串的首地址 */
/* 函数参数2: ch字符变量,用于传递待查找的字符 */
/* 函数返回值:找到,返回其地址; 否则,返回NULL */
char *Search(char *s , char ch)
{
char *p=NULL ;
while (*s!='\0')
{
if (*s==ch)
{
p = s ; /* 找到,保留地址 */
break ;
}
else
{
s++; /* 继续,指针后移 */
}
}
return p ;
}null【例6-19】通过函数在某字符串中搜索一个特定的字符第一次出现的地址,在主函数调用并输出结果。/* example6-19 */
/* 通过函数在字符串中查找给定的字符第一次出现的位置,返回其地址 */
#include
#include
char *Search( char * , char ) ; /* 函数原型声明 */
void main ( void)
{
char c , *p , str[80];
gets(str );
scanf( "%c" , &c);
p = Search(str ,c ); /* 调用函数 */
if (p==NULL )
printf ("char %c not found\n", c ) ;
else
printf ("The position is: %d\n" ,p-str ) ;
}null/* 函数名: Search */
/* 函数参数1: s指向字符的指针,用于传递字符串的首地址 */
/* 函数参数2: ch字符变量,用于传递待查找的字符 */
/* 函数返回值:找到,返回其地址; 否则,返回NULL */
char *Search(char *s , char ch)
{
char *p=NULL ;
while (*s!='\0')
{
if (*s==ch)
{
p = s ; /* 找到,保存地址 */
break ;
}
else
{
s++; /* 继续,指针后移 */
}
}
return p ;
}6.6 指向函数的指针6.6 指向函数的指针 概念:函数为程序模块,函数要装载到内存中,函数在内存中
其首地址称为函数的入口地址,用函数名表示。C语言可以通过指
针指向函数的入口地址,从