C语言剖解(05)
当我把整型数据讲完的时候,差不多已经耗去了将近两个小时的时间。这其实验证了一个道理:看似简单的一些东西,如果究其细节的话,还是有很多东西可以挖掘的。但我必须有所克制,并有所重点的讲给学生,我希望我能交给学生的是,他们既能理解这些内容,又能稍微深层的去解释一些内容。
当整型数据讲完的时候,我问学生是否听懂了,学生说懂了。好,懂了,说明第三章的课我已经顺利的完成了三分之一,接下来我开始讲浮点型数据。
浮点型数据不能过深的讲解,那只会扰乱学生,使其对浮点型数据产生惧怕,以至于,后面不敢使用浮点型数据,但浮点型数据有时一门语言中不可缺少的语言,因此,思前想后,我先整体归纳为四句话:
1、 浮点型数据有单精度和双精度,很明显,双精度所占的字节数是单精度所占字节数的一倍。
2、 浮点数表述数据类型,存在误差。
3、 我们定义一个浮点数的时候,编译器是默认为双精度的。
4、 浮点数的小数位数的。
归纳完这些,我看着学生认真的记下,颇为满意。为了证明第一点,我引入了如下运算符,为了向学生着重强调,我写了如下代码。
int i =sizeof(int);
printf("%d\n",i);
写完代码我问学生:“打印出的内容是多少?”
“4”,确实有一部分学生知道。
“sizeof是干什么用的?”
“求数据类型大小的”
“sizeof是什么?”
“函数。”
“什么?再说一遍”
“函数。”
“哟~,你还真敢胡说呀。把书翻到第365页,看一下附录C,sizeof是什么?”
“哦,运算符!”
“对,明白了吧!”
我想,学生以后不会再说sizeof是一个函数了吧,于是我继续写代码
int main(void)
{
int i =sizeof(int);
int ui =sizeof(unsigned int);
int j =sizeof(char);
int k =sizeof(float);
int l =sizeof(double);
printf(
"sizeof(unsignedint) = %d,sizeof(int)=%d\n, \
sizeof(char)=%d,sizeof(float)=%d\n, \
sizeof(double)=%d\n", i, ui, j, k, l);
}
写完代码,我会先让学生说出每个值,当然,有说错的,然后我给出运行结果。
其打印结果如下:
sizeof(unsigned int) = 4,sizeof(int)=4
,sizeof(char)=1,sizeof(float)=4
,sizeof(double)=8
Press any key to continue
这样,我就将明确了第一个问题。显然,用举例子加提问的方法,是最能让学生知道答案的。为了让学生更好的理解浮点数是近似表示的,我继续写代码如下:
double df = 5.13;
然后,我问学生:
“df的值是多少?”
“5.13”
“多少?”
“5.13”
“再说一遍,是多少?”学生开始在我的再三追问下,不敢说话了,
我于是运行程序,并把鼠标移到了df上:5.1299999999999999。
“因此,我说实型数据是近似表示的,明白没?至于为什么,大家有兴趣没?”
“有”
“很好,下去道网上搜索一下浮点的具体存储方法,我这里不讲!”
大家被逗乐了。我又顺势写下如下代码:
float df = 5.13;
“我继续问,现在值是多少?”
很多学生不敢吭声,知道一说就有问题。但也有学生说道:
“5.1299999999999999”
“我呸,我上面刚强调过,双精度字节数是单精度的字节数的两倍。”说完,我有接着说 “谭浩强那本书是不是没带?要么就是一直合着没打开!”
学生匆忙翻开书翻到了第46页,上面如是写:float小数有效位数为6~~7位;
“现在大家说,是多少?”
“5.1299999”
“是么?那你们仔细看是多少。”
“我再次运行程序,并把鼠标设置在df上,结果为:5.130000”
“为啥?”
“为啥?问老师呢?能不能把你高贵的眼睛放到书上扫一下,把眼睛放到47页,把开头的一段话给我念一遍”
“由于浮点型变量是由有限的存储单元组成的,因此提供的又有效数字总是有限地,在有效位意外的数字将被舍去。”
“明白了吧。”
“明白了。”
“那么怎么证明在定义以及使用一个浮点数进行运算的时候,编译器默认为双精度的呢?”
还是上次的代码,我重新换回double,然后编译。生成的编译结果如下:
--------------------Configuration:cl_09 - Win32 Debug--------------------
Compiling...
cl09.c
Linking...
cl_09.exe - 0 error(s), 0 warning(s)
“有没有告警?”
“没有!”
“对,很明显,没有告警。”
“那你看这个有没有告警?”我便说边把double改为float,编译结果如下:
--------------------Configuration: cl_09 - Win32Debug--------------------
Compiling...
cl09.c
E:\lesson\cl_09\cl09.c(4) : warning C4305: 'initializing': truncation from 'const double ' to 'float '
Linking...
cl_09.exe - 0 error(s), 1 warning(s)
“有!”
“对,编译器并不认为这是一个错误,但会给出一条告警,告警内容说明,将double类型的数据转换为float将会截取一部分。”
“那么如果我并不在乎这个告警,确实我们不需要在乎这个告警因为我们确实想要一个float类型的数据,那该怎么办呢?”
很少有人回答,因为很多学生对老师的依赖很强,他们确实下去很少看书,看来,我的多布置一下作业,想办法逼着学生往后看。我有些哀叹之余,书写如下代码,而这在书上有讲:floatdf=5.12f;这样我再编译,告警消失了。
“看到没,一旦我们确实需要这样一个内容,我们可以在后面添加一个f;”
“哦”
“同理,我们的整型数据也可以这样做,至于怎么添加,我不多说,大家看一下书,同样,关于浮点数的计算,我并不讲解,大家下去看书,还有,就是本次讲课结束,大家开始做课后作业了,从第三章做到第六章做完,我下次课会先收作业。好,下课!”