鱼C论坛

 找回密码
 立即注册
查看: 1293|回复: 7

[已解决][求助]关于 c 语言 for循环的 疑惑

[复制链接]
发表于 2019-3-23 18:20:30 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 hankc 于 2019-3-24 11:03 编辑

正常代码:
  1. #include <stdio.h>
  2. #include <math.h>

  3. int main()
  4. {
  5.   unsigned long long sum = 0;
  6.   unsigned long long temp;
  7.   unsigned long long weight;
  8.   int i;

  9.   for (i = 0; i < 64; i++)
  10.   {
  11.     temp = pow(2, i);
  12.     sum = sum + temp;
  13.   }

  14.   weight = sum / 25000;

  15.   printf("舍罕王应该给予达依尔%llu粒麦子!\n", sum);
  16.   printf("如果每25000粒麦子为1kg,那么应该给%llu公斤麦子!\n", weight);

  17.   return 0;
  18. }
复制代码


输出:
  1. gcc -lm p1.c -o p1 && ./p1
  2. 舍罕王应该给予达依尔18446744073709551615粒麦子!
  3. 如果每25000粒麦子为1kg,那么应该给737869762948382公斤麦子!
复制代码



然后舍去 临时变量就会出现 溢出?
  1.   for (i = 0; i < 64; i++)
  2.   {
  3.     sum = sum + pow(2, i);
  4.   }
复制代码


输出:
  1. gcc -lm p1.c -o p1 && ./p1
  2. 舍罕王应该给予达依尔0粒麦子!
  3. 如果每25000粒麦子为1kg,那么应该给0公斤麦子!
复制代码


这两段代码不是等价的吗?
  1.   for (i = 0; i < 64; i++)
  2.   {
  3.     temp = pow(2, i);
  4.     sum = sum + temp;
  5.   }

  6.   for (i = 0; i < 64; i++)
  7.   {
  8.     sum = sum + pow(2, i);
  9.   }
复制代码


至少在 63的循环内是等价的
  1.   for (i = 0; i < 63; i++)
  2.   {
  3.     temp = pow(2, i);
  4.     sum = sum + temp;
  5.   }
  6. // 输出:
  7. // gcc -lm p1.c -o p1 && ./p1
  8. // 舍罕王应该给予达依尔9223372036854775808粒麦子!
  9. // 如果每25000粒麦子为1kg,那么应该给368934881474191公斤麦子!

  10. for (i = 0; i < 63; i++)
  11.   {
  12.     sum = sum + pow(2, i);
  13.   }
  14. // 输出:
  15. // gcc -lm p1.c -o p1 && ./p1
  16. // 舍罕王应该给予达依尔9223372036854775808粒麦子!
  17. // 如果每25000粒麦子为1kg,那么应该给368934881474191公斤麦子!

复制代码


/* ---------------------------------------------------------------------- 后记 ----------------------------------------------------------------------*/
基于上述问题 和 答案 pow 函数是返回 double 的 又做了一次测试
  1.   printf("short: %ld\n", sizeof(short));
  2.   printf("unsigned short: %ld\n", sizeof(unsigned short));
  3.   printf("int: %ld\n", sizeof(int));
  4.   printf("unsigned int: %ld\n", sizeof(unsigned int));
  5.   printf("long: %ld\n", sizeof(long));
  6.   printf("unsigned long: %ld\n", sizeof(unsigned long));
  7.   printf("long long: %ld\n", sizeof(long long));
  8.   printf("unsigned long long: %ld\n", sizeof(unsigned long long));
  9.   printf("float: %ld\n", sizeof(float));
  10.   printf("double: %ld\n", sizeof(double));
复制代码


输出
  1. short: 2
  2. unsigned short: 2
  3. int: 4
  4. unsigned int: 4
  5. long: 8
  6. unsigned long: 8
  7. long long: 8
  8. unsigned long long: 8
  9. float: 4
  10. double: 8
复制代码


结果 unsigned long long 和 double 的 内存空间大小是一样的


  1. // 1
  2. temp = pow(2, i);
  3. sum += temp;

  4. // 2
  5. sum += (unsigned long long) pow(2, i);
复制代码


从 1和2两个运算 来看 这就很神奇了, `=` 赋值,看起来并没有隐式转换,

`+` 运算,才是导致 `sum` 的数据类型发生转换的元凶。

最佳答案
2019-3-23 19:04:04
本帖最后由 jackz007 于 2019-3-23 19:11 编辑

      power() 返回 double 型结果,楼主把下面这一句:
  1.          sum = sum + pow(2 , i)  ;
复制代码

      改成:
  1.          sum = sum + (unsigned long long) pow(2 , i)  ;
复制代码

      试试看是否有效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-3-23 19:04:04 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2019-3-23 19:11 编辑

      power() 返回 double 型结果,楼主把下面这一句:
  1.          sum = sum + pow(2 , i)  ;
复制代码

      改成:
  1.          sum = sum + (unsigned long long) pow(2 , i)  ;
复制代码

      试试看是否有效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-23 20:53:34 | 显示全部楼层
jackz007 发表于 2019-3-23 19:04
power() 返回 double 型结果,楼主把下面这一句:

      改成:

问题是解决了,更大的问题,,,想知道中间的类型转换,没找到打印变量数据类型的函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-23 20:55:15 | 显示全部楼层
hankc 发表于 2019-3-23 20:53
问题是解决了,更大的问题,,,想知道中间的类型转换,没找到打印变量数据类型的函数

      “没找到打印变量数据类型的函数” 是什么意思?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-23 20:58:43 | 显示全部楼层
jackz007 发表于 2019-3-23 20:55
“没找到打印变量数据类型的函数” 是什么意思?

类似于
Python type()
JavaScript typeof
这样的 函数 或者关键字
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-23 21:03:30 | 显示全部楼层
       Python 和 JavaScript 不需要事先定义变量,所以需要这个函数,C / C++ 的变量必须要先定义再使用,每个变量都有明确的类型,不同类型变量之间不允许操作和赋值,这一点,程序员必须始终了然于心,所以,就不需要这样的一个函数了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-3-23 21:03:55 | 显示全部楼层
jackz007 发表于 2019-3-23 20:55
“没找到打印变量数据类型的函数” 是什么意思?

我先往后学吧,感觉这些问题会在对c有更多了解的时候解决。。
问题好像太小白
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-3-23 21:43:23 | 显示全部楼层
楼主说的应该是运行时类型识别(RTTI)吧,
在C语言里暂时没有找到合适的方法,但是在C++里,可以使用typeid关键字获取变量的类型。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-27 19:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表