在Objective-C中,事实上与所有的程序设计语言一样,在两个数相加时使用加号(+),在两个数相减时使用减号(-),在两个数相乘时使用乘号(*),在两个数相除时使用除号(/)。这些运算符称为二元算术运算符,因为它们运算两个值或项。

运算符的优先级

你已经看到如何在Objective-C中执行简单的运算,例如,加法。下面的程序进一步说明了减法、乘法和除法运算。在程序中执行的最后两个运算引入了一个概念,即一个运算符比另一个运算符有更高的优先级。事实上,Objective-C中的每一个运算符都有与之相关的优先级。

优先级用于确定包含多个运算符的表达式如何求值:优先级较高的运算符首先求值。如果表达式包含优先级相同的运算符,可按照从左到右或从右到左的方向来求值,具体按哪个方向求值取决于运算符。这就是通常所说的运算符结合性。

代码清单4-2

//说明各种算术运算符的用法

#import <Foundation/Foundation.h>

int main (int argc, char *argv[])

{

@autoreleasepool {

int  a = 100;

int  b = 2;

int  c = 25;

int  d = 4;

int  result;

result = a - b;     //减法

NSLog (@"a - b = %i", result);

result = b * c;     //乘法

NSLog (@"b * c = %i", result);

result = a / c;     //除法

NSLog (@"a / c = %i", result);

result = a + b * c; //优先级

NSLog (@"a + b * c = %i", result);

NSLog (@"a * b + c * d = %i", a * b + c * d);

}

return 0;

}

代码清单4-2 输出

a - b = 98

b * c = 50

a / c = 4

a + b * c = 150

a * b + c * d = 300

在声明整型变量a、b、c、d及result之后,程序将a减b的结果指派给result,然后用恰当的NSLog调用来显示它的值。

下一条语句

result = b * c;

将b的值和c的值相乘并将其结果存储到result中。然后用NSLog调用来显示这个乘法的结果。到目前为止,你应该很熟悉该过程了。

之后的程序语句引入了除法运算符——斜杠(/)。100除以25得到4,可用NSLog语句在a除以c之后立即显示。

在某些计算机系统中,尝试用一个整数除以0将导致程序异常终止或出现异常。即使程序没有异常终止,执行这样的除法所得的结果也毫无意义。在第6章“选择结构”中,将看到如何在执行除法运算之前检验除数是否为0。如果除数为0,可采用适当的操作来避免除法运算。

表达式

a + b * c

不会产生结果2550(即102×25);相反,相应的NSLog语句显示的结果为150。这是因为Objective-C与其他大多数程序设计语言一样,对于表达式中多重运算或项的顺序有自己的规则。通常情况下,表达式的计算按从左到右的顺序执行。然而,为乘法和除法运算指定的优先级比加法和减法的优先级要高。因此,Objective-C认为表达式

a + b * c

等价于

a + (b * c)

(如果采用基本的代数规则,那么该表达式的计算方式是相同的。)

如果要改变表达式中项的计算顺序,可使用圆括号。事实上,前面列出的表达式是相当合法的Objective-C表达式。这样,可用表达式

result = a + (b * c);

替换代码清单4-2中的表达式,也可以获得同样的结果。然而,如果用表达式

result = (a + b) * c;

来替换,则赋给result的值将是2550,因为要首先将a的值(100)和b的值(2)相加,然后将结果与c的值(25)相乘。圆括号也可以嵌套,在这种情况下,表达式的计算要从最里面的一对圆括号依次向外进行。只要确保结束圆括号和开始圆括号的数目相等即可。

从代码清单4-2中的最后一条语句可发现,对NSLog指定表达式作为参数时,无须将该表达式的结果先指派给一个变量,这种做法是完全合法的。表达式

a * b + c * d

可根据以上述规则,按照

(a * b) + (c * d)

(100 * 2) + (25 * 4)

来计算。

求出的结果300将传递给NSLog函数。

整数运算和一元负号运算符

代码清单4-3巩固了前面讨论的内容,并引入了整数运算的概念。

代码清单4-3

//更多的算术表达式

#import <Foundation/Foundation.h>

int main (int argc, char *argv[])

{

@autoreleasepool {

int  a = 25;

int  b = 2;

float c = 25.0;

float d = 2.0;

NSLog (@"6 + a / 5 * b = %i", 6 + a / 5 * b);

NSLog (@"a / b * b = %i", a / b * b);

NSLog (@"c / d * d = %f", c / d * d);

NSLog (@"-a = %i", -a);

}

return 0;

}

代码清单4-3 输出

6 + a / 5 * b = 16

a / b * b = 24

c / d * d = 25.000000

-a = -25

前3条语句中,在int和a、b及result的声明之间插入了额外的空格,以便对齐每个变量的声明,使用这种方法书写语句可使程序更容易阅读。还可以注意到,在迄今出现的每个程序中,每个运算符前后都有空格。这种做法同样不是必需的,仅仅是出于美观上的考虑。一般来说,在允许单个空格的任何位置都可以插入额外的空格。如果能使程序更容易阅读,输入空格键的操作还是值得做的。

在代码清单4-3中,第一个NSLog调用中的表达式巩固了运算符优先级的概念。该表达式的计算按以下顺序执行:

(1)因为除法的优先级比加法高,所以先将a的值(25)除以5。该运算将给出中间结果5。

(2)因为乘法的优先级也高于加法,所以随后中间结果(5)将乘以2(即b的值),并获得新的中间结果(10)。

(3)最后计算6加10,并得出最终结果(16)。

第二条NSLog语句引入了一种新误解。你希望a除以b,再乘以b的操作返回a(已经设置为25)。但此操作并不会产生这一结果,在输出显示器上显示的是24。难道计算机在某个地方迷失了方向?如果这样就太不幸了。其实该问题的实际情况是,这个表达式是采用整数运算来求值的。

如果回头看一下变量a和b的声明,你会想起它们都是作为int类型声明的。当包含两个整数的表达式求值时,Objective-C系统都将使用整数运算来执行这个操作。在这种情况下,数字的所有小数部分将丢失。因此,计算a除以b,即25除以2时,得到的中间结果是12,而不是期望的12.5。这个中间结果乘以2,就得到最终结果24。这样,就解释了出现“丢失”数字的情况。

在代码清单4-3的倒数第二个NSLog语句中看到,如果用浮点值代替整数来执行同样的运算,就会获得期望的结果。

决定使用float变量还是int变量应该基于变量的使用目的。如果无须使用任何小数位,就可以使用整型变量。这将使程序更加高效,换言之,它可以在大多数计算机上更快速地执行。另一方面,如果需要精确到小数位,那就很清楚应该选择什么。此时,唯一需要回答的问题是使用float还是double。对此问题的回答取决于使用数据所需的精度以及它们的量级。

在最后一条NSLog语句中,使用了一元负号运算符对变量a的值取负。这个一元运算符是用于单个值的运算符,而二元运算符作用于两个值。负号实际上扮演了一个双重角色;作为二元运算符,它执行两个数相减的操作;作为一元(或单目)运算符,它对一个值取负。

与其他算术运算符相比,一元负号运算符具有更高的优先级,但一元正号运算符(+)除外,一元正号运算符和算术运算符的优先级相同。因此,表达式

c = -a * b;

将执行-a乘以b。

本文节选自《Objective-C程序设计(第4版)》

电子工业出版社出版

[美]Stephen G. Kochan(斯蒂芬·G·科昌)著

林冀 范俊 朱奕欣 译

Objective-C的算术表达式 .相关推荐

  1. C++算术运算符与算术表达式

    C++中的算术运算符包括基本的算术运算符和自增.自减运算符.由算术运算符.操作数和括号构成的表达式称为算术表达式.

  2. 算术表达式求解背景_1.8 C++算术运算符与表达式

    点击上方"C语言入门到精通",选择置顶 第一时间关注程序猿身边的故事 作者 闫小林 白天搬砖,晚上做梦.我有故事,你有酒么? 基本的算术运算符 在上一节大概介绍了算术运算符有哪些, ...

  3. c语言作业算术表达式求值,算术表达式求值演示(C语言版)

    //头文件预处理命令 #include #include //----------函数结果状态代码----------------- #define TRUE 1 #define FALSE 0 #d ...

  4. 利用树求解算术表达式的值

    利用树求解算术表达式的值 #include <stdio.h> #include <string.h> #include <malloc.h> //#include ...

  5. SDUT-2132_数据结构实验之栈与队列二:一般算术表达式转换成后缀式

    数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 对于一个基于二元运 ...

  6. 数据结构实验之栈与队列二:一般算术表达式转换成后缀式

    Description 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. Input 输入一个算术表达式,以'#'字符作为结束标志. Output 输出该表达式转换所得到的后缀式. ...

  7. boost::proto模块实现简单的算术表达式求值器的测试程序

    boost::proto模块实现简单的算术表达式求值器的测试程序 实现功能 C++实现代码 实现功能 boost::proto模块实现简单的算术表达式求值器的测试程序 C++实现代码 #include ...

  8. boost::proto模块实现构建算术表达式的简单示例 带有占位符的评估器的测试程序

    boost::proto模块实现构建算术表达式的简单示例带有占位符的评估器的测试程序 实现功能 C++实现代码 实现功能 boost::proto模块实现构建算术表达式的简单示例带有占位符的评估器的测 ...

  9. html算术计算,js实现计算器 提供算术表达式求值

    //html 计算器 @import "calculator.css"; //CSS /* CSS Document */ body { /*   padding-right:40 ...

  10. 算术表达式的实现,支持加减乘除,括号运算,表达式转二叉树

    基本思路 首先,用户输入的待求表达式,也就是中缀表达式,对于人来说,这个很好理解,但是对于计算机,后缀表达式求值更加容易.如果看成一棵二叉树,其实中缀表达式就是对一个二叉树的中序遍历,后缀表达式(也叫 ...

最新文章

  1. 小朋友你是否有很多问号?疫情期间不打游戏却在背ABC,百度翻译日活同比增长40%...
  2. sentinel 阿里 原理_限流降级神器:哨兵(sentinel)原理分析
  3. 数字图像处理的三个层次
  4. 前端性能优化:使用媒体查询加载指定大小的背景图片
  5. 乐享计算机会计学院,EMBA
  6. Reveal使用心法
  7. hibernate_和ORM的关系
  8. oppo的sd卡在哪里打开_oppo的sd卡在哪里打开
  9. 锁 唤醒_Java笔记|等待唤醒机制
  10. 沈阳java基础培训,辽宁沈阳java培训学费大概多少
  11. 苹果iPhone发布13周年:累计销量近20亿部
  12. tts语音合成小玩具
  13. mybatis使用collection查询集合属性规则
  14. 四年的自学,通过这些学习工具拿到了大厂offer,分享给大家
  15. 第五章:Django连接mysql数据库
  16. android切换域名,android通过gradle切换域名,替换app的String资源(修改app名称,图标)
  17. Unity3D游戏开发初探—2.初步了解3D模型基础
  18. 可视化人工智能区块链操作系统奥泰AOT在硅谷立项
  19. ArcGIS在线应用介绍(4)辽宁省地理信息共享平台(公众版)
  20. Maven如何配置阿里镜像及安装全步骤

热门文章

  1. linux otl mysql_Linux下用OTL操作MySql(包含自己封装的类库及演示样例代码下载)...
  2. 英语四级和计算机二级考试时间安排,计算机二级考试时间一年几次呢
  3. python二维数组第一列_Python遍历numpy数组的实例 python中如何提取一组数据中的第一列数据...
  4. Windows 10开机后,键盘上的Num Lock灯默认是熄灭的
  5. 树莓派 pico pio 可编程io
  6. SaaS销售迎来破局 渠道分销重回主场
  7. 微信小程序获取地理位置
  8. Electron 使用 regedit 控制注册表(实现win文件右键菜单)
  9. 小米手机miui12系统连接数据线usb共享网络方法
  10. android谷歌地图获取地址信息,java - 如何通过触摸Android谷歌地图上的屏幕获取地址信息 - SO中文参考 - www.soinside.com...