C语言学习笔记(二六)

C语言学习第二十六天,今天学习函数。

4.2 返回非整数的函数
之前讨论的函数都是不返回任何值(void)或只返回int类型的函数。我们通过函数atof(s)来说明函数返回非整型值的方法。该函数把字符串s转换为相应的双精度浮点数。atof函数是atoi函数的扩展,atof函数需要处理可选的符号和小数点,并要考虑可能缺少整数部分或小数部分的情况。标准库中包含类似功能的atof函数,在头文件<stdlib.h>中声明。
首先,由于atof函数的返回值类型不是int,因此该函数必须声明返回值的类型。返回值的类型名应放在函数名字之前,如下所示:

    #include <ctype.h>

    /* atof函数: 把字符串s转换为相应的双精度浮点数 */
    double atof(char s[]) {
        double val, power;
        int i, sign;

        for (i = 0; isspace(s[i]); i++) /* 跳过空白符 */
            ;
        sign = (s[i] == '-') ? -1 : 1;
        if (s[i]  == '+' || s[i] == '-')
            i++;
        for (val = 0.0; isdigit(s[i]); i++)
            val = 10.0 * val +(s[i] - '0');
        if(s[i] == '.')
            i++;
        for (power = 1.0; isdigit(s[i]); i++) {
            val = 10.0 * val + (s[i] - '0');
            power *= 10.0;
        }
        return sign * val / power;
    }

其次,调用函数必须知道atof函数返回的是非整型值,这一点也是很重要的。为了达到该目的,一种方法是调用函数中显示声明atof函数。下面所示的基本计算器程序(仅适用于支票薄计算)中有类似的声明。该程序在每行中读取一个数(数的前面可能有正负号),并对它们求和,在每次输入完成后把这些数的累计总和打印出来:

    #include <stdio.h>

    #define MAXLINE 100

    /* 简单计算器程序 */
    main() {
        double sum, atof(char []);
        char line[MAXLINE];
        int getline1(char line[], int max);

        sum = 0;
        while (getline1(line, MAXLINE) > 0)
            printf("\t%g\n", sum += atof(line));
        return 0;
    }

其中,声明语句

    double sum, atof(char []);

表明sum是一个double类型的变量,atof函数带有一个char[]类型的参数,且返回一个double类型的值。
函数atof的声明与定义必须一致。如果atof函数与调用它的主函数main放在同一源文件中,并且类型不一致,编译器就会检测到该错误。但是,如果atof函数是单独编译的(这种可能性更大),这种不匹配的错误就无法检测出来,atof函数讲返回double类型的值,而main函数却将返回值按照int类型处理,最后的结果值毫无意义。
如果没有函数原型,则函数将在第一次出现的表达式中被隐式声明,例如:

    sum += atof(line)

如果先前没有声明过的一个名字出现在某个表达式中,并且其后紧跟一个左圆括号,那么上下文就会认为该名字是一个函数的名字,该函数的返回值将被假定为int类型,但上下文并不对其参数作任何假设。如果函数带有参数,则要声明它们;如果没有参数,则使用void进行声明。
在正确进行声明的函数atof基础上,我们可以利用它编写出函数atoi(将字符串转换为int类型)    :

    /* atoi函数:利用atof函数把字符串s转换为整数 */
    int atoi(char s[]) {
        double atof (char s[]);

        return (int) atof(s);
    }

在下列形式的return语句中:

    return(表达式) ;

其中,表达式的值在返回之前将被转换为函数的类型。因为函数atoi的返回值为int类型, 所以,return语句中的atof函数的double类型值将被自动转换为int类型值。但是,这种操作可能会丢失信息,某些编译器可能会对此给出警告信息。在该函数中,由于采用了类型转换的方法显式声明了所要执行的转换操作,因此可以防止有关的警告信息。

练习4-2 对atof函数进行扩充,使它可以处理形如 123.45e-6 的科学表示法,其中,浮点数后面可能会紧跟一个e或E以及一个指数(可能有正负号)。
/* atof函数: 把字符串s转换为相应的双精度浮点数 */
double atof(char s[]) {
    double val, power;
    int i, sign, powerSign, powerNum;

    for (i = 0; isspace(s[i]); i++) /* 跳过空白符 */
        ;
    sign = (s[i] == '-') ? -1 : 1;
    if (s[i]  == '+' || s[i] == '-')
        i++;
    for (val = 0.0; isdigit(s[i]); i++)
        val = 10.0 * val +(s[i] - '0');
    if(s[i] == '.')
        i++;
    for (power = 1.0; isdigit(s[i]); i++) {
        val = 10.0 * val + (s[i] - '0');
        power *= 10.0;
    }

    val = sign * val / power;

    if(s[i] == 'e' || s[i] == 'E')
        i++;

    powerSign = '+';
    if(s[i] == '+' || s[i] == '-') {
        powerSign = s[i++];
    }
    for (powerNum=0;isdigit(s[i]); i++)
        powerNum = 10.0 * powerNum +(s[i] - '0');
    for (i = 0; i < powerNum; i++) {
        if (powerSign == '-' ) {
            val /= 10;
        } else {
            val *= 10;
        }
    }
    return val;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值