废柴日记之圣诞特辑:正数?还是正整数?


=================================================
废柴日记之圣诞特辑:正数?还是正整数?
=================================================

废柴日记之圣诞特辑:正数?还是正整数?


前言:其实,我每天都还好。

「Merry Christmas」

废柴日记之圣诞特辑:正数?还是正整数?

圣诞快乐啊各位。
虽然这篇博客的发布时间应该是25日的晚上,但博主还是在这里祝福大家在这一天与很棒的人度过了一段很棒的时光。博主的圣诞节过的也是十分的充实——吃饭睡觉当杠精,一天下来没给我累坏了。
同时也在这里祝某个圣诞节玩的很开心然后跑来跟博主"分享快乐"的靓仔开房必没身份证。
废柴日记之圣诞特辑:正数?还是正整数?
闲聊到此结束,进入正题。


正数?还是正整数?

博主在收拾行李的时候发现了一本从学长那边白嫖回来压箱底的书——《抛弃C程序设计中的谬误与恶习》。光是这个书名听起来就很吸引人,让博主我觉得此书非同小可。书中前言部分写到:

  • 许多虔诚的学习者内心的潜意识里会以为教科书不会有什么错误,他们一向跪在教科书上学习,遇到错误时只是不断地检讨自己;

  • 教科书同样可能有错,这种“水源”的污染才是最严重的污染;

这不比博燃?开读!

在本书的第4章中有这么一个问题:

从键盘输入一个小于1000的正数,要求输出它的平方根(若平方根不是整数,则输出其整数部分)。
要求在输入数据后先对其检查是否小于1000的正数。若不是则要求重新输入。

而书中的 样本代码(通常是一些不够完美的代码,甚至有语法错误) 是这样的:

#include <stdio.h>
#include <math.h>
#define M 1000

int main()
{
    int i,k;
    printf("请输入一个小于%d的整数i: ",M);
    scanf("%d",&i);
    while(i>M){
        printf("输入的数据不符合要求,请重新输入一个小于%d的整数i: ",M);
        scanf("%d",&i);
        k=sqrt(i);
    }
    printf("%d的平方根的整数部分为%d\n",i,k);
    return 0;
}

作者在对 样本代码 的解析中提到了两点:

  1. k=sqrt(i);的位置。
    k=sqrt(i);所处的位置使得无论输入的i是否符合小于1000的正数的条件程序都会计算一次i的平方根,十分的不合理;
  2. printf("请输入一个小于%d的整数i: ",M);的表述。
    按照这个表述来说,程序是允许使用者输入一个非正数的数字(比如-1),这会使得程序存在很大的隐患;

紧接着作者给出了自己认为的对于这道题来说正确的代码

#include <stdio.h>
#include <math.h>
#define M 1000

int main(void)
{
    int n,sqrt_n=0;
    int i,k;
    printf("请输入一个小于%d的正整数: ",M);
    while(scanf("%d",&n),n<=0||n>M)
        printf("输入的数据不符合要求,请重新输入一个小于%d的整数: ",M);
    int n_=n;
    int odd=1;
    while(n_>=odd){
        n_-=odd;
        sqrt_n++;
        odd+=2;
    }
    printf("%d的平方根的整数部分为%d\n",n,sqrt_n);
    return 0;
}

他的代码看似没有问题(他的求平方根的方法我很喜欢,很独特),但是仔细阅读之后会发现他的代码所解决的问题变成了:

从键盘输入一个小于1000的正整数,要求输出它的平方根(若平方根不是整数,则输出其整数部分)。

而原问题是:

从键盘输入一个小于1000的正数,要求输出它的平方根(若平方根不是整数,则输出其整数部分)。

这样来说作者的代码所解决的只是原问题的子问题,并没有完全解决原问题。更进一步讲是有曲解题意的说法。
正数分为正整数正分数正分数同样也是可以开方的: 1.44 = 1.2 \sqrt{1.44}=1.2 1.44 ​=1.2。那么想要完全解决这个问题,就需要考虑如何处理正分数

博主想到的是用C语言的强制数据类型转换来解决,但具体还需要哪些细节,懒狗表示并没有想,因为博主很害怕涉及到浮点数的运算的。众所周知,在C语言中我们通常使用floatdouble存储一个浮点数,而这俩兄弟是会丢精度的。例如sqrt(4.0)是有可能得到1.999999的答案的。

不过说到这里,我就想起了那群不争气的笨蛋:这都快2022年了还有人不知道float==float的写法是不对的吧?

在这里着重声明:
在C语言中,浮点数是无法作相等判断的。
我们通常是规定一个精度,当两个浮点数之间的差距小于这个精度时,我们可以认为它们是"相等"的。

记住了!要考的!


博主写这篇博客,并不是想表明自己比 《抛弃C程序设计中的谬误与恶习》 的作者厉害,我只是想表达出作者想要我们这些学习者所表现出的品质——不要一味的相信你所听到/看到的,对事物要怀有敬畏之心,也要保留自我的看法。
真理永远掌握在少数人手里,但你为什么觉得你不是少数人呢?

不尬吹,作者大大太厉害了,这两天翻阅下来,学到了很多东西,也发现了自己的一些错误认知。有兴趣的朋友可以看一下,很推荐的。


后话

感谢阅读,希望能对你产生一点用处。

以*词取自《银魂》第137集:
(就算是咸鱼也要有梦想啊,至少要保留着"圣诞老人会来送礼物"的梦想啊)

废柴日记之圣诞特辑:正数?还是正整数?

"雪橇也好二轮拖车也好,不都是一样的嘛"
"不是用什么送,重要的是送什么"
"可是啊,现在的我负债累累,还在酒吧招揽客人"
"这样肮脏的自己根本没有去实现孩子们梦想的资格了"
"你在说什么啊"
"你不是一直在努力"
"最终不是明白了自己还是只能适合做圣诞老人的嘛"
"现在你也很清楚自己想做什么"
"这样不是很好么"
"你现在也一定是从心底想要当圣诞老人的吧"

吾日三省吾身:日更否?刷题否?快乐否?
更新了,但不是日更;已刷;平静
路漫漫其修远兮,吾将上下而求索

废柴日记之圣诞特辑:正数?还是正整数?

上一篇:odoo13学习---15 CMS网站开发


下一篇:图书管理增删改查&父子调用&前后端