作为新生的,不用背负任何历史包袱的全新语言,仓颉充分吸收了过去数十年来众多编程语言之长,原生智能化、天生全场景、高性能、强安全。作为华为鸿蒙系统的平台语言,仓颉拥有良好的发展潜力和前景,极有可能成为第一款形成世界级影响的国产编程语言。青少年现在学习仓颉,就是在投资未来 !

版权声明

作者:重庆大学 陈波

本文可以在互联网上自由转载,但必须注明出处(作者:海洋饼干叔叔)并包含指向本页面的链接。本文不可以以纸质出版为目的进行改编、摘抄。

2.2 变量(续)

  在计算问题中,除了整数变量,必然还有小数变量。为了探讨整数及小数变量的应用,我们考虑一个稍稍复杂一点的计算问题:买3个苹果,每个3.6元,付给老板20元,应该找回多少钱?新建一个仓颉项目,并按照图2-3修改主程序文件main.cj。

image-20241004213944825

图2-3 Apples项目的主程序文件(含编译错误的版本)

  编译运行上述程序,编译器报告了下述错误(有删节,[ ]内的注解为作者所加):

1
2
3
4
5
6
7
8
9
10
11
12
13
D:\CJLearn\CH2\Apples>cjpm run
error: invalid binary operator '*' on type 'Int32' and 'Float32'
[错误: Int32和Float32之间非法的二元操作符*]
==> D:\CJLearn\CH2\Apples\src\main.cj:7:28: [错误文件的路径:行:列]
7 | var amount:Float32 = n * price [行 | 内容]
| ^ [^标示错误的具体位置]

error: cannot convert an integer literal to type 'Float32'
[错误:不能把一个整数字面量转换为Float32类型]
==> D:\CJLearn\CH2\Apples\src\main.cj:8:25: [错误文件的路径:行:列]
8 | var money:Float32 = 20 [行 | 内容]
| ^ [^标示错误的具体位置]
2 errors generated, 2 errors printed.

  此外,图2-3中第7行和第8行代码被标记了红色波浪线,以表明代码的错误位置。为便于讨论,我们一边解释程序一边修正错误:

▶第5行:定义类型为Int32的整数变量n,并赋初值3,表示苹果的个数。

▶第6行:定义类型为Float32的浮点数变量price,并赋初值3.6,表示苹果的单价。浮点数即俗称的小数,Float32是由32个二进制比特位组成的浮点数类型▲。注意,对于第6行的赋值操作符而言,等号右边的3.6是浮点数,左边的变量price也是浮点数,两者类型一致。

▶第7行:定义类型为Float32的浮点数变量amount,并赋初值为n与price的乘积,表示金额。这行代码有错,编译器报告的错误是Int32和Float32之间的*号操作符非法(见错误信息第2行)。对于初学者而言,这个错误信息十分费解。编译器毕竟只是运行在冰冷机器上的软件,做不到像人类那样循循善诱。这个错误的实质是n是Int32类型的整数,price是Float32类型的浮点数(小数),不允许直接将两者相乘。

  我们需要先将Int32类型的整数n转换成Float32类型的浮点数,然后再与price相乘。修改后的第7行代码如下:

1
var amount:Float32 = Float32(n) * price

  上行中的Float32(n)并不是将变量n的类型由Int32转换成Float32,它仅仅是产生一个值尽可能与n相近的类型为Float32的临时副本以供计算之用。变量n的类型,根据定义,永远是Int32。

  将一个变量转换为指定类型的语法形式为:目标类型名(变量名)。

▶第8行:定义类型为Float32的浮点数变量money,并赋值为20,表示付给老板的钱数。这行代码有错,编译器报告的错误是不能把一个整数字面量(literal)▲转换成Float32类型(见错误信息第8行)。字面量是指程序中显式给出的值。本行中等号右边的20即为一个整数类型的字面量,它与等号左边变量money的类型不一致,从而导致错误。

  将整数字面量20修改为浮点数字面量20.0可以修正该错误。虽然20与20.0在数学上等值,但从程序角度而言,两者的类型不同,前者是整数,后者是浮点数。

1
var money:Float32 = 20.0

▶第9 ~ 10行:使用println()函数打印输出计算结果。请读者留意第10行的插值项${money-amount},与其它字符串插值项不同,该插值项花括号内不是一个平凡的变量名,而是一个表达式。在字符串插值过程中,money和amount之差被计算出来,并用于替换字符串中的插值项。

  Apples项目经修改后的正确程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
//Project - Apples
package Apples

main(): Int64 {
var n:Int32 = 3
var price:Float32 = 3.6
var amount:Float32 = Float32(n) * price
var money:Float32 = 20.0
println("${n}个苹果,每个${price}元,一共${amount}元。")
println("付给老板${money}元,应找回${money-amount}元。")
return 0
}

上述程序的执行结果为:

1
2
3个苹果,每个3.600000元,一共10.799999元。
付给老板20.000000元,应找回9.200001元。

  理论上,3乘以3.6的结果应为10.8元,但执行结果却显示为10.799999元。这说明,浮点数在计算机里的存储和计算,是有轻微误差的。相关原因我们稍后再讨论。

  代码第9行打印输出了执行结果第1行,并补充输出了一个换行符,使得输出焦点来到执行结果的第2行。然后代码第10行打印输出了执行结果的第2行,也补充输出了一个换行符,从而形成了执行结果第3行的空行。

海洋饼干叔叔的仓颉语言学习笔记将持续更新… 敬请期待。


欢迎支持海洋饼干叔叔系列程序设计教材,案例、配套资源丰富,实践性强,高等教育出版社出版。

高校教学同行如果需要样书,或者索取教学支持资源, 请联系公众号或者海洋饼干叔叔本人。

《Python编程基础及应用》 《Python编程基础及应用实验教程》 《C++编程基础及应用》
book1 实验书图片 Cpp小尺寸