hankc 发表于 2019-3-23 18:20:30

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

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

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

int main()
{
unsigned long long sum = 0;
unsigned long long temp;
unsigned long long weight;
int i;

for (i = 0; i < 64; i++)
{
    temp = pow(2, i);
    sum = sum + temp;
}

weight = sum / 25000;

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

return 0;
}

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


然后舍去 临时变量就会出现 溢出?
for (i = 0; i < 64; i++)
{
    sum = sum + pow(2, i);
}


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

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

for (i = 0; i < 64; i++)
{
    sum = sum + pow(2, i);
}

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

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



/* ---------------------------------------------------------------------- 后记 ----------------------------------------------------------------------*/
基于上述问题 和 答案 pow 函数是返回 double 的 又做了一次测试
printf("short: %ld\n", sizeof(short));
printf("unsigned short: %ld\n", sizeof(unsigned short));
printf("int: %ld\n", sizeof(int));
printf("unsigned int: %ld\n", sizeof(unsigned int));
printf("long: %ld\n", sizeof(long));
printf("unsigned long: %ld\n", sizeof(unsigned long));
printf("long long: %ld\n", sizeof(long long));
printf("unsigned long long: %ld\n", sizeof(unsigned long long));
printf("float: %ld\n", sizeof(float));
printf("double: %ld\n", sizeof(double));

输出
short: 2
unsigned short: 2
int: 4
unsigned int: 4
long: 8
unsigned long: 8
long long: 8
unsigned long long: 8
float: 4
double: 8

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


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

// 2
sum += (unsigned long long) pow(2, i);

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

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

jackz007 发表于 2019-3-23 19:04:04

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

      power() 返回 double 型结果,楼主把下面这一句:
         sum = sum + pow(2 , i);
      改成:
         sum = sum + (unsigned long long) pow(2 , i);
      试试看是否有效果

hankc 发表于 2019-3-23 20:53:34

jackz007 发表于 2019-3-23 19:04
power() 返回 double 型结果,楼主把下面这一句:

      改成:


问题是解决了,更大的问题,,,想知道中间的类型转换,没找到打印变量数据类型的函数

jackz007 发表于 2019-3-23 20:55:15

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

      “没找到打印变量数据类型的函数” 是什么意思?

hankc 发表于 2019-3-23 20:58:43

jackz007 发表于 2019-3-23 20:55
“没找到打印变量数据类型的函数” 是什么意思?

类似于
Python type()
JavaScript typeof
这样的 函数 或者关键字

jackz007 发表于 2019-3-23 21:03:30

       Python 和 JavaScript 不需要事先定义变量,所以需要这个函数,C / C++ 的变量必须要先定义再使用,每个变量都有明确的类型,不同类型变量之间不允许操作和赋值,这一点,程序员必须始终了然于心,所以,就不需要这样的一个函数了。

hankc 发表于 2019-3-23 21:03:55

jackz007 发表于 2019-3-23 20:55
“没找到打印变量数据类型的函数” 是什么意思?

我先往后学吧,感觉这些问题会在对c有更多了解的时候解决。。
问题好像太小白

Croper 发表于 2019-3-23 21:43:23

楼主说的应该是运行时类型识别(RTTI)吧,
在C语言里暂时没有找到合适的方法,但是在C++里,可以使用typeid关键字获取变量的类型。
页: [1]
查看完整版本: [求助]关于 c 语言 for循环的 疑惑