今天本来还是在听for循环,在语法上和php还是非常像的,开始心不在焉了,看谭大爷的教材上有一个小算法题,就写一下。题目是这样的 : 1 + 1/2 + 1/3 + ... + 1/100 = ? 好歹也写了两三年的php了,这个还不是小菜一碟。然后就写了如下代码:
# include <stdio.h>
int main(void)
{
int i;
int sum = 0;
for(i = 1; i <= 100; ++i)
{
sum += 1/i;
}
printf("sum = %d \n", sum);
return 0;
}
/*
输出结果为:
==========================
sum = 1
==========================
怎么会这样呢?(我是文雅的人,就不说卧槽)
*/
哦,原来是数据类型错了,相比之下,php倒是很省事。就把上面的sum的数据类型换成了float,%d也换成了%f,按照浮点型输出。如下:
# include <stdio.h>
int main(void)
{
int i;
float sum = 0; //将sum改为浮点型
for(i = 1; i <= 100; ++i)
{
sum += 1/i;
}
printf("sum = %f \n", sum); //将输出改为%f,按照浮点型输出
return 0;
}
/*
输出结果
===================================
sum = 1.000000
===================================
怎么会这样呢?不是应该正常输出么?这不科学呀!
*/
在前几天写运算符笔记的时候,说到除法时有一个要点:
除法/的运算结果和运算对象的数据类型有关,两个数都是int,则商就是int,若商有小数,则截取小数部分;被除数和除数中只要有一个或两个是浮点型数据,则商也是浮点型,不截取小数部分。(这个很重要)
原来是酱紫,找到原因了。然后就把第10行给稍微修改了一下,改成:
sum += 1.0 / i; //这样就完美了。输出 sum = 5.187378
两个int类型相除,结果只会保留小数点前面的整数,都是0,当然结果也就一直是1了。
今天的课也正好讲到了这些内容。
强制类型转换
格式:
(数据类型)(表达式) 表达式那里可用括号也可不用括号,为了和其他语言方便记忆,全部括起来。
功能:
把表达式的值强制转化成前面所执行的数据类型
例如:
(int)(4.2 + 2.2) 最终值是6
(float)(5) 最终值是 5.000000
浮点数存储所带来的问题
自增自减都定义成浮点型,这是不对的
float和double都不能保证可以精确的存储一个小数,举例:
/*
float 和 double 类型无法准确的记录一个小数
*/
# include <stdio.h>
int main(void)
{
float f = 99.9;
printf("%f \n",f);
return 0;
}
/*
运行的结果是
=====================================
99.900002
=====================================
*/
举例:
有一个浮点型变量x,如何判断x的值是否是零
错误的写法
if( 0 == x )
yes
else
no
正确的写法
if( |x-0.000001| <= 0.000001 )
是
else
不是
浮点数存储的都是一个近似值,所以不能直接判断它是不是零,最直接的方法就是判断它和某一个很小的数字之间相差是否非常非常小,如果相差非常非常小,就说明可以当零去看待了
为什么循环更新的变量不能定义成浮点型?
还是刚才说到的,因为浮点数是一个近似值,如果拿近似值进行比较,很有可能因为近似值多出一点点或者少一点点,而产生判断错误,比如:
for( i =1 ; i <= 10; i++) 当i第九次循环,由于取到一个近似值10.000001,拿这个值和10去比较,第十次循环就泡汤了。所以:更新的变量一定不能使用浮点型。
学PHP的小蚂蚁 博客 http://my.oschina.net/woshixiaomayi/blog