十五分钟搞定--C Primer Plus第9章函数(入门)

首先声明一下,这只是对我自己当下学习的简单记录,一步一个脚印(参考书籍《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");
}

 

总结

函数就挺重要的,它就是一个小黑箱子,有自己的作用,需要它的时候一定要记得它的存在嗷~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值