6.4 带参数的函数

C语言学习栏目目录

目录

章节程序演示


 

现在,相信大家已经熟悉了带参数的函数。要掌握函数,还要学习如何编写自己的函数程序清单中有一个pound()函数,打印指定数量的#号(该符号也叫作编号符号或井号)。该程序还演示了类型转换的应用。


/************************************************************************
功能:定义一个带一个参数的函数
************************************************************************/

#include <stdio.h>
void pound(int n);		// ANSI函数原型声明
int main(void)
{
	int times = 5;
	char ch = '!';		// ASCII码是33
	float f = 6.0f;
	pound(times);		// int类型的参数
	pound(ch);			// 和pound((int)ch);相同
	pound(f);			// 和pound((int)f);相同
	system("pause");	// 暂停控制台
	return	0;
}
void pound(int n)		// ANSI风格函数头
{						// 表明该函数接受一个int类型的参数
	while (n-- > 0)
		printf("#");
	printf("\n");
}

运行该程序后,输出如下:

#####
#################################
######
请按任意键继续. . .

如果函数不接受任何参数,函数头的圆括号中应该写上关键字  void。由于该函数接受一个 int 类型的参数,所以圆括号中包含一个int类型变量n的声明。参数名应遵循C语言的命名规则。

声明参数就创建了被称为形式参数(formal  argument或formalparameter,简称形参)的变量。该例中,形式参数是 int 类型的变量 n。像pound(10)这样的函数调用会把 10 赋给 n。在该程序中,调用pound(times)就是把 times 的值(5)赋给 n。我们称函数调用传递的值为实际参数(actualargument或actual  parameter),简称实参。所以,函数调用pound(10)把实际参数10传递给函数,然后该函数把10赋给形式参数(变量n)。也就是说,main()中的变量times的值被拷贝给pound()中的新变量n。

注意 实参和形参

在英文中,argument和parameter经常可以互换使用,但是C99标准规定了:对于actual argument或actual parameter使用术语argument(译为实参);对于formal argument或formal parameter使用术语parameter(译为形参)。为遵循这一规定,我们可以说形参是变量,实参是函数调用提供的值,实参被赋给相应的形参。因此,在上程序清单中,times是pound()的实参,n是
pound()的形参。类似地,在函数调用pound(times + 4)中,表达式times + 4的值是该函数的实参。

变量名是函数私有的,即在函数中定义的函数名不会和别处的相同名称发生冲突。如果在pound()中用times代替n,那么这个times与main()中的times不同。也就是说,程序中出现了两个同名的变量,但是程序可以区分它们。

现在,我们来学习函数调用。第1  个函数调用是pound(times),times的值5被赋给n。因此, printf()函数打印了5个井号和1个换行符。第2个函数调用是pound(ch)。这里,ch是char类型,被初始化为!字符,在ASCII中ch的数值是33。但是pound()函数的参数类型是int,与char不匹配。程序开头的函数原型在这里发挥了作用。原型(prototype)即是函数的声明,描述了函数的
返回值和参数。pound()函数的原型说明了两点:

该函数没有返回值(函数名前面有void关键字);

该函数有一个int类型的参数。

该例中,函数原型告诉编译器pound()需要一个int类型的参数。相应地,当编译器执行到pound(ch)表达式时,会把参数ch自动转换成int类型。在我们的系统中,该参数从1字节的33变成4字节的33,所以现在33的类型满足函数的要求。与此类似,最后一次调用是pound(f),使得float类型的变量被转换成合适的类型。

在ANSI C之前,C使用的是函数声明,而不是函数原型。函数声明只指明了函数名和返回类型,没有指明参数类型。为了向下兼容,C现在仍然允许这样的形式:

void pound(); /* ANSI C之前的函数声明 */

 如果用这条函数声明代替pound.c程序中的函数原型会怎样?第 1 次函数调用,pound(times)没问题,因为times是int类型。第2次函数调用,pound(ch)也没问题,因为即使缺少函数原型,C也会把char和short类型自动升级为int类型。第3次函数调用,pound(f)会失败,因为缺少函数原型,float会被自动升级为 double,这没什么用。虽然程序仍然能运行,但是输出的内容不正确。在函数调用中显式使用强制类型转换,可以修复这个问题:

pound ((int)f); // 把f强制类型转换为正确的类型

注意,如果f的值太大,超过了int类型表示的范围,这样做也不行。

章节程序演示

程序清单演示了本章介绍的几个概念,这个程序对某些人很有用。程序看起来很长,但是所有的计算都在程序的后面几行中。我们尽量使用大量的注释,让程序看上去清晰明了。请通读该程序,稍后我们会分析几处要点。

(若程序再VS中无法运行Scanf函数,请参考:VS2015使用scanf报错解决方案


/************************************************************************
功能:演示本章介绍的几个概念
************************************************************************/

#include <stdio.h>
const int S_PER_M = 60;					// 1分钟的秒数
const int S_PER_H = 3600;				// 1小时的分钟数
const double M_PER_K = 0.62137;			// 1公里的英里数
int main(void)
{
	double distk, distm;				// 跑过的距离(分别以公里和英里为单位)
	double rate;						// 平均速度(以英里/小时为单位)
	int min, sec;						// 跑步用时(以分钟和秒为单位)
	int time;							// 跑步用时(以秒为单位)
	double mtime;						// 跑1英里需要的时间,以秒为单位
	int mmin, msec;						// 跑1英里需要的时间,以分钟和秒为单位
	printf("这个程序是对你比赛时间公制转换\n");
	printf("一英里的跑步时间和你的平均成绩\n");
	printf("速度(英里/小时).\n");
	printf("请输入以公里为单位的长跑\n");
	scanf("%lf", &distk);				// %lf表示读取一个double类型的值
	printf("下一步以分钟和秒为单位输入时间\n");
	printf("从输入分钟开始\n");
	scanf("%d", &min);
	printf("输入你的秒数 .\n");
	scanf("%d", &sec);
	time = S_PER_M * min + sec;			// 把时间转换成秒
	distm = M_PER_K * distk;			// 把公里转换成英里
	rate = distm / time * S_PER_H;		// 英里/秒×秒/小时 = 英里/小时
	mtime = (double)time / distm;		// 时间/距离 = 跑1英里所用的时间
	mmin = (int)mtime / S_PER_M;		// 求出分钟数
	msec = (int)mtime % S_PER_M;		// 求出剩余的秒数
	printf("你跑 %1.2f km (%1.2f 英里) 用 %d min, %dsec.\n",distk, distm, min, sec);
	printf("这个速度相当于跑了一英里 %d min, ",mmin);
	printf("%d sec.\n你的平均速度是 %1.2f mph.\n", msec,rate);
	system("pause");					//暂停控制台
	return 0;
}

程序清单把时间转换成分钟和秒,除此之外还使用了类型转换。为什么要进行类型转换?因为程序在秒转换成分钟的部分需要型参数,但是在公里转换成英里的部分需要浮点运算。我们使用强制类型转换运算符进行了显式转换。实际上,我们曾经利用自动类型转换编写这个程序,即使用int类型的mtime来强制时间计算转换成整数形式。但是,在测试的11个系统中,这个版本的程序在1个系统上无法运行,这是由于编译器(版本比较老)没有遵循C规则。而使用强制类型转换就没有问题。对大家而言,强制类型转换强调了转换类型的意图,对编译器而言也是如此。

下面是程序清单的输出示例:

这个程序是对你比赛时间公制转换
一英里的跑步时间和你的平均成绩
速度(英里/小时).
请输入以公里为单位的长跑
10
下一步以分钟和秒为单位输入时间
从输入分钟开始
36
输入你的秒数 .
23
你跑 10.00 km (6.21 英里) 用 36 min, 23sec.
这个速度相当于跑了一英里 5 min, 51 sec.
你的平均速度是 10.25 mph.
请按任意键继续. . .

源码 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值