首先声明一下,这只是对我自己当下学习的简单记录,一步一个脚印(参考书籍《C Primer Plus》)
目录
前言
如何了解函数?定义函数、调用函数、创建函数
一、定义函数
明确地指定函数要做什么
二、调用函数
表明在调用出执行此函数
三、创建函数
通过一个简单的例题,用自己创建的函数来实现功能:
目标是创建一个在一行打印40个星号的函数,并在一个打印表头的程序中使用还函数。
#include <stdio.h>
#define WIDTH 40
void starbar(void); /*函数原型*/
int main(void) {
starbar(); /*调用函数*/
printf("\n\t一闪一闪亮晶晶\n");
printf("\t满天都是小星星\n");
starbar(); /*调用函数*/
}
void starbar(void) { /*定义函数*/
int count;
for (count = 1; count <= WIDTH;count++) {
putchar('*');
}
putchar("\n");
}
四、学习当然是做题靠谱呀
例1:(使用头文件)
假设要管理4家酒店的客房服务,每家酒店的房价不同,但是每家酒店所有房间的房价相同。对于预订住宿多天的客户,第2天的房费是第1天的95%,第3天是第2天的95%,以此类推,设计一个程序让用户指定酒店和入住天数,然后计算并显示总费用。同时,程序要实现一份菜单,允许用户反复输入数据,除非用户选择退出。
/* usehotel.c -- 房间费率程序 */
/* 与程序清单9.10一起编译 */
#include <stdio.h>
#include "hotel.h" /* 定义符号常量,声明函数 */
int main(void)
{
int nights;
double hotel_rate;
int code;
while ((code = menu()) != QUIT)
{
switch (code)
{
case 1: hotel_rate = HOTEL1;
break;
case 2: hotel_rate = HOTEL2;
break;
case 3: hotel_rate = HOTEL3;
break;
case 4: hotel_rate = HOTEL4;
break;
default: hotel_rate = 0.0;
printf("Oops!\n");
break;
}
nights = getnights();
showprice(hotel_rate, nights);
}
printf("Thank you and goodbye.\n");
return 0;
}
/* hotel.c -- 酒店管理函数 */
#include <stdio.h>
#include "hotel.h"
int menu(void)
{
int code, status;
printf("\n%s%s\n", STARS, STARS);
printf("Enter the number of the desired hotel:\n");
printf("1) Fairfield Arms 2) Hotel Olympic\n");
printf("3) Chertworthy Plaza 4) The Stockton\n");
printf("5) quit\n");
printf("%s%s\n", STARS, STARS);
while ((status = scanf("%d", &code)) != 1 ||
(code < 1 || code > 5))
{
if (status != 1)
scanf("%*s"); // 处理非整数输入
printf("Enter an integer from 1 to 5, please.\n");
}
return code;
}
int getnights(void)
{
int nights;
printf("How many nights are needed? ");
while (scanf("%d", &nights) != 1)
{
scanf("%*s"); // 处理非整数输入
printf("Please enter an integer, such as 2.\n");
}
return nights;
}
void showprice(double rate, int nights)
{
int n;
double total = 0.0;
double factor = 1.0;
for (n = 1; n <= nights; n++, factor *= DISCOUNT)
total += rate * factor;
printf("The total cost will be $%0.2f.\n", total);
}
/* hotel.h -- 符号常量和 hotel.c 中所有函数的原型 */
#define QUIT 5
#define HOTEL1 180.00
#define HOTEL2 225.00
#define HOTEL3 255.00
#define HOTEL4 355.00
#define DISCOUNT 0.95
#define STARS "**********************************"
// 显示选择列表
int menu(void);
// 返回预订天数
int getnights(void);
// 根据费率、入住天数计算费用
// 并显示结果
void showprice(double rate, int nights);
********************************************************************
Enter the number of the desired hotel:
1) Fairfield Arms 2) Hotel Olympic
3) Chertworthy Plaza 4) The Stockton
5) quit
********************************************************************
0
Enter an integer from 1 to 5, please.
2
How many nights are needed? 5
The total cost will be $1017.99.
********************************************************************
Enter the number of the desired hotel:
1) Fairfield Arms 2) Hotel Olympic
3) Chertworthy Plaza 4) The Stockton
5) quit
********************************************************************
5
Thank you and goodbye.
例2:
设计一个函数 min(x,y)
,返回两个 double
类型值的较小值。在一个简单的驱动程序中测试该函数。
#include <stdio.h>
double min(double x, double y);
/*函数的声明,返回两个double类型数中的较小数据,因此,返回值也是double类型*/
int main(void) {
double d1,d2;
printf("Enter tow float number:");
scanf("%lf %lf",&d1,&d2);
printf("you input %g and %g. The MIN is %g.\n",d1,d2,min(d1,d2));
return 0;
}
double min(double x, double y){
if(x < y) return x;
else return y;
/*对于常见的简单逻辑判断函数,除了使用if 语句之外,还常用?:运算表达式
* 这样表达更加简洁和清晰。
* return x < y ? x : y;
* */
}
/*double min(double x, double y) {
return x > y ? y : x;
}*/
例3:
设计一个函数 chline(ch,i,j)
,打印指定的字符 j 行 i 列,在一个简单的驱动程序中测试该程序。
#include <stdio.h>
void chline(char ch,int cols, int rows);
/* 函数声明,无返回值,三个参数分别是char, int, int。
* chline(ch,i,j)题目要求j行,i列,因此需要注意形式参数顺序和含义。
* */
int main(void) {
char c;
int i, j;
printf("Enter the char you want to print: ");
scanf("%c",&c);
printf("Enter the rows and cols you want to print: ");
/* 变量j 负责打印行,i 负责打印列,scanf()函数读取输入顺序为&j,&i*/
scanf("%d %d",&j,&i);
chline(c,i,j);
return 0;
}
void chline(char ch,int cols, int rows){
for(int m = 0;m < rows ;m++){
for(int n = 0;n < cols; n++)
printf("%c",ch);
printf("\n");
}
}
/* 循环嵌套时,外部循环控制行数,内部循环控制列。
* 外部循环的循环控制判断使用形式参数rows,并负责打印换行符。
* 内部循环控制判断使用形式参数 cols,并打印字符,无换行。
* */
/*void chline(char ch, int i, int j) {
for (int m = 0; m < j; m++)
{
for (int n = 0; n < i; i++)
printf("%c",ch);
printf("\n");
}
}*/
例4:
两数的调和平均数这样计算,先得到两数的倒数,然后计算两个倒数的平均值,最后去计算结果的倒数。编写一个函数,接受两个 double
类型的参数,返回这两个参数的调和平均数。
#include <stdio.h>
double harmean(double x, double y);
/*函数声明,调和平均数,double类型参数型x, y, 返回值 double类型*/
int main(void) {
double d1,d2;
printf("Enter tow float number:");
scanf("%lf %lf",&d1,&d2);
printf("The HarMEAN of %g and %g is %g.\n",d1,d2,harmean(d1,d2));
return 0;
}
double harmean(double x, double y){
return 2/(1/x + 1/y);
}
/*两个数的调和平均数基本算法*/
例5:
编写并测试一个函数 larger_of()
,该函数把两个 double
类型变量替换为较大的值,例如,larger_of(x, y)
会把 x 和 y 中较大的值重新赋给两个变量。
#include <stdio.h>
void larger_of(double *x, double *y);
/*函数需要修改主调函数的值,因此需要使用指针作为函数的参数。
* 且不需要返回值。
* */
int main(void) {
double d1,d2;
printf("Enter tow float number:");
scanf("%lf %lf",&d1,&d2);
printf("Data you input is %g and %g.\n",d1,d2);
larger_of(&d1,&d2);
printf("After function. Data is %g and %g.\n",d1,d2);
}
void larger_of(double *x, double *y){
if( *x > *y) *y = *x;
else *x = *y;
/* 也可以使用? : 进行判断和赋值。代码如下:*x > *y ? (*y = *x) : (*x = *y);
*/
}
/*void larger_of(double* x,double* y) {
if (*x>*y)
{
*y = *x;
}
else {
*x = *y;
}
}*/
例6:
编写并测试一个函数,该函数以 3 个 double
变量的地址作为参数,把最小值放入第一个变量,中间值放入第二个变量,最大值放入第三个变量。
#include <stdio.h>
void ordering(double *x, double *y, double *z);
/*ordering()函数的参数是三个指向double类型变量的指针。无返回值。
* */
int main(void) {
double d1,d2,d3;
printf("Enter three float number:");
scanf("%lf %lf %lf",&d1,&d2,&d3);
printf("Data you input is %g, %g and %g.\n",d1,d2,d3);
ordering(&d1,&d2,&d3);
printf("After function. data is %g, %g and %g.\n",d1,d2,d3);
}
void ordering(double *x, double *y, double *z){
double temp;
if(*x > *y) {
temp = *x;
*x = *y;
*y = temp;
}
if(*x > *z) {
temp = *x;
*x = *z;
*z = temp;
}
if(*y > *z) {
temp = *y;
*y = *z;
*z = temp;
}
}
/*ordering()函数的基本算法是:三个变量两两比较,符合条件就交换数据值。
* */
例7:
编写一个函数 get_char_pos()
,从标准输入中读取字符,直到遇到文件结尾。程序要报告每个字符是否是字母,如果是,还要报告该字母在字母表中的位置。例如,c 和 C 在字母表中的位置都是 3。get_char_pos()
中合并一个函数 position()
,以一个字符作为参数,如果该字符是一个字母则返回一个数值位置,否则返回 -1。
#include <stdio.h>
void get_char_pos(void);
/*函数功能:读取标准输入,对于字符输入,打印其字母表位置。*/
int position(char ch);
/* 函数功能:计算并返回字符在字母表中位置。*/
int main(void) {
get_char_pos();
}
void get_char_pos(void){
char ch;
printf("Enter the chars(ended by EOF ,not enter):\n");
while((ch = getchar()) != EOF){
/*以文件结尾为结束标志*/
if(ch == '\n') continue;
/*简单清除换行符的输入,其他特殊符号未处理*/
if(position(ch) != -1){
printf("The char %c's position in alphabet is %d.\n",ch,position(ch));
}else printf("%c is not a alphabet.\n",ch);
}
}
int position(char ch){
if(ch >='A' && ch <='Z')
return ch -'A' + 1;
if(ch >='a' && ch <='z')
return ch -'a' + 1;
return -1;
}
/*函数将参数传递的字符分别和'a' 'A' 比较判断其位置,非字符返回 -1。
* */
例8:(数的幂计算)
编写函数 power()
,该函数返回一个 double
类型数据的整数次幂。改进函数,使它能够计算负幂。另外,函数要处理 0 的任何次幂都是 0,任何数的 0 次幂都是 1(函数应该报告 0 的 0 次幂未定义,因此把该值处理为 1)。要使用一个循环,并在程序中测试该函数。
#include <stdio.h>
double power(double n, int p);
/* 计算 double 类型数据 n 的 p 次幂。返回值类型为 double。*/
int main(void) {
double x, xpow;
int exp;
printf("Enter a number and the integer power");
printf(" to which \n the number will be raised. Enter q");
printf(" to quit.\n");
while(scanf("%lf %d",&x,&exp) == 2)
{
xpow = power(x,exp);
printf("%.3g to the power %d is %.5g\n",x,exp,xpow);
printf("Enter the next pair of numbers or q to quit.\n");
}
printf("Hope you enjoy this power trip -- bye!\n");
return 0;
}
double power(double n, int p){
double pow = 1;
int i;
if(n == 0 && p ==0){
printf("The %g to the power %c is not define, return 1!\n",n , p);
return 1;
};/* 0 的 0 次幂单独标注,函数返回 */
if(n == 0) return 0;/* 0 的任何次幂等于 0 */
if(p == 0) return 1;/* 除 0 外的任何数的 0 次幂等于 1 */
if(p > 0){
for(i = 1; i<=p; i++)
pow *= n;
return pow;
/* 正整数次幂 */
}else{
for(i = 1; i<=-p; i++)
pow *= n;
return 1/pow;
/* 负整数次幂 */
}
}
#include <stdio.h>
double power(double n, int p);
/* 计算 double 类型数据n的p次幂。返回值类型为 double */
int main(void) {
double x, xpow;
int exp;
printf("Enter a number and the integer power");
printf(" to which \nthe number will be raised. Enter q");
printf(" to quit.\n");
while(scanf("%lf %d",&x,&exp) == 2)
{
xpow = power(x,exp);
printf("%.3g to the power %d is %.5g\n",x,exp,xpow);
printf("Enter the next pair of numbers or q to quit.\n");
}
printf("Hope you enjoy this power trip -- bye!\n");
return 0;
}
double power(double n, int p){
double pow = 1;
int i;
if(n == 0 && p ==0){
printf("The %g to the power %c is not define, return 1!\n",n , p);
return 1;
};/* 0 的 0 次幂单独标注,函数返回 */
if(n == 0) return 0;/* 0 的任何(0 除外)次幂等于 0 */
if(p == 0) return 1;/* 除 0 外的任何数的 0 次幂等于 1 */
if(p > 0){
return n*power(n, p-1);
/* 正p次幂的递归 */
}else
{
return power(n,p+1)/n;
/* 负p次幂的递归 */
}
}
例9:(进制转换)
编写一个 to_base_n()
函数,接受两个参数,且第二个参数在 2 ~ 10 范围内,然后以第二个参数中指定的进制打印第一个参数的数值。例如,to_base_n(129, 8)
显示结果 201,也就是 129 的八进制数。在一个完整的程序中测试该函数。
#include <stdio.h>
void to_base_n(unsigned long n, unsigned short t);
/* 进制转换,待转换数类型是正整数,因此使用无符号类型标识。*/
int main(void) {
unsigned long number;
unsigned short target;
printf("Enter the integer and N for notation(q to quit):");
while(scanf("%lu %hu",&number, &target) == 2){
if(target < 2 || target > 10){
printf("Please input N between 2 ~ 10!\n");
printf("Enter the integer and N for notation(q to quit):");
continue;
}
printf("Convert %lu to %hu notation is: ",number,target);
to_base_n(number, target);
putchar('\n');
printf("Enter the integer and N for notation(q to quit):");
}
return 0;
}
void to_base_n(unsigned long n, unsigned short t){
if(t < 2 || t > 10){
printf("The function noly convert 2 ~ 10\n");
return;
}/* 函数内部的参数判断。*/
int r;
r = n % t;
if(n >= 2) to_base_n(n/t, t);
printf("%d",r);
}
例10:(斐波那契数)
编写并测试 Fibonacci()
函数,该函数用循环代替递归计算斐波那契数。
#include <stdio.h>
void Fibonacci(int n);
/* 计算斐波那契数列的前 n 项。无返回值。*/
int main(void) {
int n;
printf("Enter the number of Fibonacci (q to quit):");
while(scanf("%d",&n) == 1){
if(n >= 2){
Fibonacci(n);
printf("Enter the number of Fibonacci (q to quit):");
}
}
return 0;
}
void Fibonacci(int n){
unsigned long f1,f2,temp;
/* 考虑斐波那契数列增长速度,使用无符号长整型,能够显示更多数据项。*/
f1 = 1;
f2 = 1;
for(int i = 0 ;i < n; i++){
printf("%lu ",f1);
temp = f1+f2;
f1 = f2;
f2 = temp;
}
printf("\n");
}
总结
函数就挺重要的,它就是一个小黑箱子,有自己的作用,需要它的时候一定要记得它的存在嗷~~