C语言KR圣经笔记 4.2返回非整数的函数

4.2 返回非整数的函数

到目前为止,我们给出的函数样例,不是不返回值(void)就是返回 int。如果函数必须要返回其他类型呢?许多的数值函数如 sqrt,sin 和 cos 返回 double;其他特定的函数返回其他类型的值。为了说明该如何处理这种情况,我们来编写并使用函数 atof(s),它将字符串 s 转换成对应的双精度浮点数。 atof 是 我们在第二章和第三章所展示的 atoi 函数的扩展。它能处理可选的正负号和小数点,以及可能缺失的整数或小数部分。我们即将给出的版本不是一个高质量的输入转换例程,因为我们不想占用更多篇幅。标准库中包含了一个 atof,在头文件 <stdlib.h>中声明。

首先,因为不返回int,故atof 必须声明它的返回值。返回类型放在函数名称的前面:

#include <ctype.h>/* atof: 将字符串s转换成double */
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 返回非int值。保证这一点的一种办法是在调用者函数内显式声明 atof。这种方法展示在下面这个简单的计算器中(勉强够用来做账单结算)。计算器每行读取一个可能带符号的数,将它们加起来,并在每次输入后打印当前的和。

#include <stdio.h>#define MAXLINE 100/* 简单的计算器 */
main()
{double sum, atof(char []);char line[MAXLINE];int getline(char line[], int max);sum = 0;while (getline(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,且对其参数不做任何假定。更进一步,如果函数声明没有包括参数,例如

double atof();

此时同样也不会对 atof 的参数做任何假定;所有参数校验都会被关闭。对空参数列表的这种特殊处理,是为了让新编译器能够编译旧的C程序。但新写的程序如果还这么做,会是非常糟糕的。如果函数有参数,就要声明出来;如果没有参数,使用void。

有了正确声明的atof,我们就能用它来写atoi(把字符串转换成int):

/* atoi: 使用atof将字符串s转换成整数 */
int atoi(char s[])
{double atof(char s[]);return (int) atof(s);
}

注意其中的声明结构和 return 语句。

return 表达式;

在返回发生之前,其中表达式的值会被转换成函数的类型。因此,当出现在这个 return 里面时,atof 的值 ,一个 double,会自动被转换成 int,因为 atoi 函数返回一个 int。然而,这个操作会潜在地丢失信息,因此一些编译器会给出警告。强制类型转换显式地告知编译器,这个操作是有意的,从而抑制了告警。

练习 4-2:扩展 atof,使之能处理科学计数形式

123.45e-6

其中的浮点数后面可以跟着 e 或 E,以及可选的带符号的幂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/190896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【个人记录】NGINX反向代理支持同端口HTTP与HTTPS协议访问

监听4000端口&#xff0c;反向代理127.0.0.1:9090的Web网页 NGINX配置如下 server {listen 4000 ssl http2 ; server_name www.http.com,www.https.com; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forw…

Vue3【Set Up】语法糖 + TS快速上手

文章目录 script setup基本语法顶层的绑定会被暴露给模板响应式监听与计算使用组件父子组件传参&#xff08;变化较大&#xff09;父 -> 子 defineProps()子 -> 父 defineEmits()子组件暴露给父组件内部属性 defineExpose() defineOptions() 【很少用】 script setup &l…

人工智能时代:AIGC的横空出世

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 什么是AIGC?二. AIGC的主要特征2.1 文本生成2.2 图像生成2.3 语音生成2.4 视…

蓝桥杯第198题 人物相关性分析 C++ 模拟 字符串 双指针

题目 思路和解题方法 程序首先定义了一个函数check&#xff0c;用于判断一个字符是否为字母。接下来&#xff0c;程序读取输入的整数k和一行字符串str。定义了两个空的向量a和b&#xff0c;用于存储满足条件的子串的起始位置。使用for循环遍历字符串str的每个字符&#xff0c;检…

string的模拟

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;能手撕模拟string类 > 毒鸡汤&#xff1a;时间…

MySQL-视图

一、&#xff1f;看一个需求 emp表的列信息很多&#xff0c;有些信息是个人重要信息(比如 sal,comm,mgr,hiredate),如果我们希望某个用户只能查询emp表的(empno、ename,job和deptno)信息,有什么办法? 》视图 二、基本概念 视图 视图是一个虚拟表&#xff0c;其内容由查…

complex rsa

复数rsa&#xff0c;没遇到过这种类型的题&#xff0c;可以记录一下相关知识 先来看一段 from gmpy2 import invert,lcm,is_prime import sys sys.setrecursionlimit(2047)f (3781223486422146909054116838073773962793625267340680342971864932558735632642532480951976591…

IDEA常用快捷键

快捷键功能tab接受选择–选择的名称将覆盖带插入符号右侧的其它名称–而如果按shift或者enter&#xff0c;光标右边的内容会保留Ctrlshift空格智能匹配–查找当前上下文的方法和变量Ctrld对比文件–选中需要对比的文件shift滚动水平滚动Ctrlaltl格式化Ctrlk提交Ctrlaltz回滚类C…

Linux基础项目开发1:量产工具——UI系统(五)

前言&#xff1a; 前面我们已经把显示系统、输入系统、文字系统搭建好了&#xff0c;现在我们就要给它实现按钮操作了&#xff0c;也就是搭建UI系统&#xff0c;下面让我们一起实现UI系统的搭建吧 目录 一、按钮数据结构抽象 ui.h 二、按键编程 1.button.c 2.disp_manager…

YUM 问题解决步骤

YUM 问题解决步骤 当使用 yum 进行安装软件包或者更新时&#xff0c;如果遇到卡在加载插件阶段或其他相关问题&#xff0c;如下 [rootVM-12-2-centos ~]# sudo yum update Loaded plugins: fastestmirror, langpacks Repository epel is listed more than once in the config…

linux shell编程

Linux shell编程 一、常用功能1. 比较图片差异2. 截屏2.1 起X情况下&#xff08;X window起桌面&#xff09;2.2 没有起X或没有X系统环境下 3. 自动输入密码 一、常用功能 1. 比较图片差异 if compare -metric AE p1.png p2.png null: 2>&1 | grep -v "0$";…

查找算法及哈希表

1 二分查找 1.1 重要概念 拟解决的问题&#xff1a;判断某个区间是否包含某个元素&#xff0c;无法确定区间中包含重复元素的具体位置&#xff1b;使用条件&#xff1a;查找的区间必须符合单调性&#xff1b;本质&#xff1a;采用分治思想&#xff0c;将某个单调区间一分为二…

12.2_黑马Redis实战篇附近商铺用户签到UV统计

实战篇11 实战篇12 要先用test的方式把商铺的数据导入到idea当中&#xff0c;才可以进行查询噢。 代码&#xff1a; 实战篇13 thinking&#xff1a;插件mavenhelper&#xff1f; 方便处理pom文件。 实战篇15 实战篇16 thinking&#xff1a;XX.format(DateTimeFormatter.ofP…

【网络安全技术】实体认证技术Kerberos

一、什么是Kerberos Kerberos解决的是客户端与服务器通信场景中&#xff0c;确保客户端服务器双方的身份可信&#xff0c;并提供对称密钥的分发来加密传输。是一个应用层的协议。 二、一个简单的模型 1.看这个基础的模型&#xff0c;客户端要和服务器通信&#xff0c;他先将自…

《堆》的模拟实现

目录 前言&#xff1a; 模拟实现《堆》&#xff1a; 1.自定义数据类型 2.初始化“堆” 3.销毁“堆” 4.进“堆” 关于AdjustUp() 5.删除堆顶元素 关于AdjustDown() 6.判断“堆”是否为空 7.求“堆”中的数据个数 8.求“堆”顶元素 总结&#xff1a; 前言&#xf…

「LeetCode Hot 100 题」详解

前言 前言&#xff1a;LeetCode Hot 100 题详解 文章目录 前言1. 两数之和2. 字母异位词分组3. 最长连续序列4. 移动零 1. 两数之和 原题链接&#xff1a;两数之和 知识点&#xff1a;哈希表 题解 class Solution {public int[] twoSum(int[] nums, int target) {Map<Inte…

mysql原理--重新认识MySQL

1.MySQL请求处理 1.1.查询缓存 MySQL 服务器程序处理查询请求时&#xff0c;会把刚刚处理过的查询请求和结果缓存起来&#xff0c;如果下一次有一模一样的请求过来&#xff0c;直接从缓存中查找结果就好了&#xff0c;就不用再傻呵呵的去底层的表中查找了。这个查询缓存可以在不…

DOM 事件的传播机制

前端面试大全DOM 事件的传播机制 &#x1f31f;经典真题 &#x1f31f;事件与事件流 事件流 事件冒泡流 事件捕获流 标准 DOM 事件流 &#x1f31f;事件委托 &#x1f31f;真题解答 &#x1f31f;总结 &#x1f31f;经典真题 谈一谈事件委托以及冒泡原理 &#x1f3…

SmartSoftHelp8数据库连接字符串强优化,高并发配置

1.设置数据库是否异步连接 2.数据库连接是否复用 3.最大链接数 4.最小连接数 5.等待时间 6.生命周期 下载地址&#xff1a; 百度网盘 请输入提取码

24、蜂鸣器

蜂鸣器介绍 蜂鸣器是一种将电信号转换为声音信号的器件&#xff0c;常用来产生设备的按键音、报警音等提示信号 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器 有源蜂鸣器&#xff1a;内部自带振荡源&#xff0c;将正负极接上直流电压即可持续发声&#xff0c;频率固定 无源蜂…