@@ -316,17 +316,41 @@ C++ 在类型系统上做了大量的安全加固,很多改进直接瞄准了
316316
317317int main (void)
318318{
319- double a = 0.1;
320- double b = 0.2;
321- double c = 0.3;
322-
323- printf("a + b == c? %s\n", (a + b == c) ? "yes" : "no");
324- printf("a + b = %.20f\n", a + b);
325- printf("c = %.20f\n", c);
319+ double a_double = 0.1;
320+ double b_double = 0.2;
321+ double c_double = 0.3;
322+ float a_float = 0.1f;
323+ float b_float = 0.2f;
324+ float c_float = 0.3f;
325+ float e_float = 0.3f;
326+ float f_float = 0.4f;
327+ float g_float = 0.7f;
328+
329+ printf("a_double + b_double == c_double? %s\n", (a_double + b_double == c_double) ? "yes" : "no");
330+ printf("a_float + b_float == c_float? %s\n", (a_float + b_float == c_float) ? "yes" : "no");
331+ printf("e_float + f_float == g_float? %s\n", (e_float + f_float == g_float) ? "yes" : "no");
332+ printf("a_double + b_double = %.20f\n", 0.1 + 0.2);
333+ printf("a_float + b_float = %.20f\n", 0.1f + 0.2f);
334+ printf("e_float + f_float = %.20f\n", 0.3f + 0.4f);
335+ printf("c_double = %.20f\n", c_double);
336+ printf("c_float = %.20f\n", c_float);
337+ printf("g_float = %.20f\n", g_float);
326338 return 0;
327339}
328340```
329341
342+ ```终端输出
343+ a_double + b_double == c_double? no
344+ a_float + b_float == c_float? yes
345+ e_float + f_float == g_float? no
346+ a_double + b_double = 0.30000000000000004441 //0.1 + 0.2
347+ a_float + b_float = 0.30000001192092895508 //0.1f + 0.2f
348+ e_float + f_float = 0.70000004768371582031 //0.3f + 0.4f
349+ c_double = 0.29999999999999998890 //0.3
350+ c_float = 0.30000001192092895508 //0.3f
351+ g_float = 0.69999998807907104492 //0.7f
352+ ```
353+
330354修改代码使用 epsilon 比较来得到正确的结果。
331355
332356### 练习 2:隐式转换陷阱
@@ -345,6 +369,30 @@ if (target < sizeof(values) / sizeof(values[0])) {
345369
346370提示:` sizeof ` 返回的是什么类型?
347371
372+
373+ ### 练习 2 参考答案
374+
375+ ``` c
376+ int values[] = {1, 2, 3, 4, 5};
377+ int target = -1;
378+
379+ // bug 就在下面这行
380+ if (target < (int)sizeof(values) / (int)sizeof(values[ 0] )) {
381+ printf("target is in range\n");
382+ }
383+ ```
384+ 或者
385+
386+ ``` c
387+ int values[] = {1, 2, 3, 4, 5};
388+ int target = -1;
389+
390+ // bug 就在下面这行
391+ if (target < (int)(sizeof(values) / sizeof(values[ 0] ))) {
392+ printf("target is in range\n");
393+ }
394+ ```
395+
348396### 练习 3:const 实战
349397
350398写一个函数,接收一个字符串,统计其中某个字符出现的次数。函数签名中正确使用 ` const ` :
@@ -357,6 +405,23 @@ if (target < sizeof(values) / sizeof(values[0])) {
357405size_t count_char (const char* str, char ch);
358406```
359407
408+ ### 练习 3 参考答案
409+
410+ ```c
411+ size_t count_char(const char* str, char ch) {
412+ if (str == NULL) { // 警惕空指针
413+ return 0;
414+ }
415+ size_t count = 0;
416+ for (;*str;str++) {
417+ if (*str == ch) {
418+ count++;
419+ }
420+ }
421+ return count;
422+ }
423+ ```
424+
360425## 参考资源
361426
362427- [ cppreference: C 语言隐式转换] ( https://en.cppreference.com/w/c/language/conversion )
0 commit comments