写课程作业那会对着编译器发呆,到处搜c语言sqrt什么意思,照着网上片段复制粘贴,跑出来一堆莫名其妙的数字,调试面板上的返回值乱跳,半天找不出来到底哪一步出了状况。以为只是个直接拿来就能用的简单函数,随便丢个数字进去就能拿到平方根,实际敲代码才发现,好多细碎的限制没留意,程序直接就不对。

随便写个main函数,直接调用sqrt,编译阶段不会报红色错误,运行的时候结果全是乱的。当时敲完代码,盯着屏幕反复比对示例代码,变量定义看着没毛病,括号里面数字也填对,可输出出来的数值完全和预想对不上。折腾好久才搞明白,这个函数归属于math.h头文件,不把这个头文件写进代码顶部,部分编译器不会直接报错,但运算出来的结果会发生错乱,不是得不到正确平方根,就是出来一堆毫无意义的乱码数值。

参数类型也很磨人。

拿整型数字直接塞给sqrt的时候,编译器有的时候会默许代码跑通,可运算过程会发生隐性的类型转换。定义一个int类型变量存9,直接放到sqrt括号里面,看似求3,部分编译环境处理之后,得到的返回结果会出现小数偏移,打印出来可能是2点九九九多,不是干干净净的整数3。返回值本身是double类型,要是拿int变量去接收运算结果,小数部分直接被截断丢掉,后续再拿这个变量参与别的算术运算,一连串计算全部跟着跑偏。之前做一道数学计算题,就是这里出的问题,后面整段输出全部出错,来回排查大半晚上,才定位到是接收返回值的变量类型写的不对。

还有不能传负数这件事。课本上面寥寥一笔带过,写练习的时候随手传入负的数字,程序不会直接崩溃终止,但返回出来是一个特殊的非有效数值,打印输出会显示nan。最开始碰到nan的时候完全摸不着头脑,不知道这串字母代表什么,来回改动别的代码块,改来改去完全碰不到问题根源,压根没往传入负数这个方向去想。实际写项目的时候,要是数据是别的变量传过来,不是手写固定数字,就很容易出现这种情况,上游计算得出负数,丢进sqrt,后续全部数据都变成无效。

同学写代码就懒得处理头文件,他的编译工具碰巧不需要显式引入math.h也能跑,拿到正确结果,转头就和我说不用写头文件也没关系。照搬他那套写法放到我本地环境,代码直接失效,同一个函数,不同编译工具表现出来的行为并不统一,不能凭着某一台机器跑通,就当成通用写法。链接阶段部分环境还得加上数学库参数,不然就算头文件写完整,编译依旧过不去,初学阶段很容易卡在这一步,找遍代码文本,看不出任何语法写错的地方。

调用完之后拿到的double结果,如果需要转成整数,不能直接强制转换完事。得自己额外做判断,确认计算出来的平方根平方之后,和原始输入数值能够匹配上,避免浮点精度带来的偏差。很多判断完全平方数的练习题,就是栽在浮点精度这个点,sqrt算出来近似值,强转整数之后,逻辑判断条件就会出现误判。

敲完那套平方根的练习题,关掉编辑器,键盘还留着手按过的温度。脑子里只剩下刚才调试时不停刷新输出窗口的画面。