`
hqs7636
  • 浏览: 221055 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

操作符与表达式 2.014

阅读更多
6/24、25更新

6/7更新(版本差异在8.1中)

6/5更新,6/4 更新(12--结尾),原名d语言操作符,现改名为 操作符与表达式,因为它们密切相关。
根据表达式一章作了一些更新,  $这个符号的作用还是没搞清楚,看得头大!

$ 这个符号是指数组的 length 属性,只能用在 [ ] 中 (oldrev贡献)
// 下面这些表达式是等价的:   6/5更新
bar[ ]
bar[0 .. 4]
bar[0 .. length]
bar[0 .. $]
bar[0 .. bar.length]


特征符:
Identifier             标识符
	StringLiteral          单个字符串文字
	CharacterLiteral       字符文字
	IntegerLiteral         整数文字
	FloatLiteral           浮点数文字
	Keyword                关键字

	/     除取整   15除以2商的整数部分7       DivideByZero 异常  
	/=    除取整赋值
	.    全局作用域运算符 对象操作符,在模块作用域级别查找名称
             技巧1:
              int x;
              int foo(int x)
              {
              if (y)          
                 return x; // 返回的是 foo.x,而非全局的 x
              else
                 return .x; // 返回的是全局的 x
              }

	..    数组分割符,参见 $
	...   函数多参数      //参见参数可变型函数

	&     按位与   或   返回操作数地址  ?  And表达式 & Cmp表达式
	&=    按位与赋值
	&&    逻辑与       AndAnd表达式 && Or表达式
	|     按位或         Or表达式 | Xor表达式
	|=    按位或赋值
	||    逻辑或          OrOr表达式 || AndAnd表达式
	-     减 或 位反

	-=    //
	--    //
	+     //
	+=    //
	++    x=m++ 表示将m的值赋给x后, m加1。 
                  x=++m 表示m先加1后, 再将新值赋给x。


	<         //
	<=        //
	<<     左移
	<<=    左移赋值
	<>     //
	<>=    3   小于,等于或大于  ??
	>      //
	>=     //
	>>=     右移赋值
	>>>=    右移赋值,左边空出的位以0填充
	>>      右移
	>>>     无符号右移(逻辑右移)
	!       逻辑非     //各类型的比较方式不同,参考 表达式 一节
                或者用于 显示模板实例化

	!=      不相等     bool
	!<>      4       未定义或等于
                              ( “未定义”的意思是有操作数为 NAN 。)
	!<>=     5       未定义
	!<               未定义、大于或等于
	!<=      6       未定义、或大于
	!>               未定义、小于或等于
	!>=      7       未定义、或小于

	(
	)
	[
	]
	{
	}
	?    三目运算符 如: <表达式1>?<表达式2>:<表达式3>;
	,    将多个表达式串在一起, ","运算符的左边总不返回,右边表达式的值
                 才是整个表达式的值。例如:
                 x=50; 
                 y=(x=x-5, x/5);  等同于 y=(x-5)/5 ,最后y=9

	;      8
	:      参见 ? 符

        $      指数组的 length 属性,只能用在 [] 中 (oldrev贡献)
         // 下面这些表达式是等价的: 6/5更新
            bar[ ]
            bar[0 .. 4]
            bar[0 .. length]
            bar[0 .. $]
            bar[0 .. bar.length] 


	=
	==     相等  bool  
          class C;
          C c;
          if (c == null) // error
             ...
          if (c is null) // ok


	*      对"&"运算符的一个补充, 它返回位于这个地址内的变量值
	*=     取地址内的变量值 赋值
	%      取模。15除以2的余数部分1(d支持浮点数,和c不同)    DivideByZero 异常
	%=     取模赋值



	^      按位 异或          Xor表达式 ^ And表达式
	^=     按位 异或 赋值
	~      非(取反) ??      或用于连接数组,最后生成一个动态数组
	~=

         is      比较同一性   bool    不能被重载
         ! is    比较非同一性 
           in      检测一个元素是否在关联数组中   null,或指向该元素的指针。


       参见"一元表达式" 和 "基本表达式"





问题: main()
{
char m, n; /*定义字符型变量*/
m='c'; /*给m赋小写字母'c'*/
n=m+'A'-'a'; /*问题1: 将c中的小写字母变成大写字母'B'后赋给n*/
...
}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。


表达式


C 和 C++ 程序员会发现 D 中的表达式很熟悉,另外还有一些有意思的扩充。
表达式用来计算多个值并返回一个特定类型的值。随后,所得的值可以被用于赋值、测试或
被忽略。表达式也可能有副作用。

8.1 求值顺序

  1.030
The following binary expressions are evaluated in strictly left-to-right order:

CommaExpression, OrOrExpression, AndAndExpression 

The following binary expressions are evaluated in an implementation-defined order:

AssignExpression, OrExpression, XorExpression, AndExpression, 
CmpExpression, ShiftExpression, AddExpression, CatExpression, 
MulExpression, function parameters 



  2.014
The following binary expressions are evaluated in strictly left-to-right order:

OrExpression, XorExpression, AndExpression, CmpExpression, 
ShiftExpression, AddExpression, CatExpression, MulExpression,
CommaExpression, OrOrExpression, AndAndExpression 

The following binary expressions are evaluated in an implementation-defined order:

AssignExpression, function parameters 



除非特别说明,否则,实际的实现是以任意顺序自由计算表达式的各部分。当它不是特定的
的时候,依赖于求值顺序就是个错误。例如,下面的就是非法的:
i = i++;
c = a + (a = b);
func(++i, ++i);
如果编译器能够确定表达式的值是依赖于求值顺序的话,它将报告一个错误(但这不是必须
的)。检测这种错误的能力是实现的质量方面的问题。


8.2 表达式

表达式:
赋值表达式
赋值表达式 , 表达式

先计算“,”左面的操作数,然后计算右面的操作数。表达式的类型是右面的操作数的类型,
表达式的结果是右面的操作数的结果。


8.3 赋值表达式

赋值表达式:
条件表达式
条件表达式 = 赋值表达式
条件表达式 += 赋值表达式
条件表达式 -= 赋值表达式
条件表达式 *= 赋值表达式
条件表达式 /= 赋值表达式
条件表达式 %= 赋值表达式
条件表达式 &= 赋值表达式
条件表达式 |= 赋值表达式
条件表达式 ^= 赋值表达式
条件表达式 ~= 赋值表达式
条件表达式 <<= 赋值表达式
条件表达式 >>= 赋值表达式
条件表达式 >>>= 赋值表达式

右面操作数的类型会被隐式地转换为左面操作数的类型,并赋给左面的操作数。结果的操作
数的类型是左值得类型,结果的值是赋值后左值的值。

左面的操作数必须是左值。

8.3.1 赋值运算符表达式

赋值运算符表达式,如:
a op= b

在语义上等价于:
a = a op b

差别是操作数 a 只计算一次。


4、条件表达式
OrOr表达式
OrOr表达式 ? 表达式 : 条件表达式


5、OrOr 表达式
AndAnd表达式
OrOr表达式 || AndAnd表达式


6、AndAnd 表达式
Or表达式
AndAnd表达式 && Or表达式


7、Bitwise(按位)表达式
操作数必须是正数类型。否则,应用会做默认的正数提升

7.1 Or 表达式
Xor表达式
Or表达式 | Xor表达式
执行‘或’运算。

7.2 Xor 表达式
And表达式
Xor表达式 ^ And表达式
执行‘异或’运算。

7.3 And 表达式
Cmp表达式
And表达式 & Cmp表达式
执行‘与’运算。

8、 比较表达式
And表达式:
    相等表达式
    同一表达式
    关系表达式
    In表达式

9、 相等表达式
移位表达式
移位表达式 == 移位表达式
移位表达式 != 移位表达式
移位表达式 is 移位表达式
移位表达式 !is 移位表达式

对于复数,
相等定义为等价于:
x.re == y.re && x.im == y.im

不相等定义为等价于:
x.re != y.re || x.im != y.im

对于类和结构对象,
  (a == b) 被写成 a.opEquals(b),
而 (a != b) 被写成 !a.opEquals(b)


For class objects, the == and != operators compare the contents of the objects. Therefore,
comparing against null is invalid, as null has no contents. Use the is and !is operators
instead.
对于类对象,相等 用 == 和 != 操作符比较, null 用 is 和 !is 代替。
class C;
C c;
if (c == null) // error
...
if (c is null) // ok
对于数组(静态和动态),相等被定义为数组长度相等,并且对应的元素都相等。


10、 同一表达式 is
移位表达式 is 移位表达式
移位表达式 !is 移位表达式
is 用于比较同一性。如果要比较非同一性,使用 e1 !is e2。结果的类型是布尔型。在比较之前,操作数会通过常用的转换,转型为它们的一个公共类型。
同一运算符 is 不能被重载。

5/16:添加以下
11 关系表达式
移位表达式
移位表达式 < 移位表达式
移位表达式 <= 移位表达式
移位表达式 > 移位表达式
移位表达式 >= 移位表达式
移位表达式 !<>= 移位表达式
移位表达式 !<> 移位表达式
移位表达式 <> 移位表达式
移位表达式 <>= 移位表达式
移位表达式 !> 移位表达式
移位表达式 !>= 移位表达式
移位表达式 !< 移位表达式
移位表达式 !<= 移位表达式
首先,会对 操作数应用 整数 提升。返回 bool。
对于类对象来说,Object.cmp() 的结果构成了左操作数,0 构成了右操作数。
关系表达式 (o1 op o2) 的结果是:
(o1.opCmp(o2) op 0)
如果对象为 null,进行比较就是错误。

对于(静态和动态)数组来说,关系 op 的结果是操作符应用到数组中第一个不相等的元素的结果。如果两个数组相等,但是长度不同,较短的数组“小于”较长的数组。(???)

11.1 整数比较
如果两个操作数都是整数类型,就会进行整数比较。
运算符    关  系
  <       小于
  >       大于
  <=    小于等于
  >=    大于等于
  ==      相等
  !=     不相等
如果 <、<=、> 或 >= 表达式中操作数必须同是有符号数,或同是无符号数,否则会被视为错误。(可以使用类型转换)

11.2 浮点数比较
如果有浮点数,则执行浮点数比较。
任何有实用价值的浮点操作都必须支持 NAN 值。尤其 关系 运算符要支持 NAN 操作数。浮
点数的关系运算的 结果 可以是小于、大于、等于或未定义(未定义的意思是有操作数为
NAN )。
这意味着有 14 可能的比较条件:
运算符  大于  小于  等于  未定义      异  常          关     系
 ==               T               否              相等
 !=     T    T         T          否             未定义、小于或大于
 >      T                         是              大于
 >=     T         T               是              大于等于
 <           T                    是              小于
 <=          T    T               是              小于等于
!<>=                   T          否              未定义
 <>     T    T                    是              小于或大于
 <>=    T    T    T               是             小于,等于或大于
 !<=    T              T          否             未定义或大于
 !<     T         T    T          否             未定义、大于或等于
 !>=          T        T          否             未定义或小于
 !>           T   T    T          否             未定义、小于或等于
 !<>          T   T               否             未定义或等于
注解:
1. For floating point comparison operators, (a !op b) is not the same as !(a op b).
2. “未定义”的意思是有操作数为 NAN 。
3. “异常”的意思是如果有操作数是 NAN ,则产生 Invalid 异常 。它并不是个抛出的
异常。Invalid 异常 可以使用位于 std.c.fenv 里的函数来进行检查。

11.3 类比较
对于类对象,关系运算符会比较这些对象的内容。 因此,如果跟 null 进行比较就是无效
的,因为 null 没有内容。
class C;
C c;
if (c < null) // 出错
...


12 In 表达式
In表达式:
移位表达式 in 移位表达式
可以检测一个元素是否在关联数组中:
int foo[char[]];
...
if ("hello" in foo)
...

in 表达式同关系表达式 <, <= 等有相同的优先级。 In表达式 的返回值是 null,如果元素不在数组中的话;如果它在数组中,则它是一个指向该元素的指针。

13 移位表达式
求和表达式
关系表达式 << 求和表达式
关系表达式 >> 求和表达式
关系表达式 >>> 求和表达式

操作数必须是整数类型,并且会使用常用的整数提升。结果的类型是左操作数提升后的类
型。结果的值是左操作数移动右操作数指定的位得到的值。
<< 是左移。>> 是有符号右移(译注:也叫算术右移)。>>> 是无符号右移(译注:也叫逻
辑右移)。

如果要移动的位数超过了左操作数的位数,会被认为是非法的:
int c;
c << 33; // 错误

14 求和表达式
求和表达式:
求积表达式
求和表达式 + 求积表达式
求和表达式 - 求积表达式
连接表达式

如果操作数是整数类型,会应用整数提升,然后会通过常用的算术转换提升为它们的公共类
型。
如果有操作数为浮点类型,另一个操作数会被隐式地转换为浮点类型,然后会通过常用的算
术转换提升为它们的公共类型。

如果运算符是 + 或 -,第一个操作数是指针,并且第二个操作数是整数类型,结果的类型就
是第一个操作数的类型,结果的值是指针加上(或减去)第二个操作数乘以指针所指类型的
大小得到的值。

如果第二个操作数是一个指针,而第一个操作数是一个整数,并且操作符是 +,则会按照上
面所说的方式进行指针运算,只不过操作数的顺序反过来。

浮点操作数的求和表达式不是可结合的。

15 连接表达式
求和表达式 ~ 求积表达式

连接表达式 用于连接数组,最后生成一个动态数组。这些数组必须具有相同元素类型。如
果有个操作数是一个数组,而另一个是那个数组元素类型的操作数,则该数会被转换成一个
包含它的长度为 1 的数组,然后完成连接操作。

16 求积表达式

一元表达式
求积表达式 * 一元表达式
求积表达式 / 一元表达式
求积表达式 % 一元表达式

操作数必须是算术类型先会执行整数提升,然后会通过常用的算术转换提升为它们的公共类
型。

于整数操作数来说,*、/ 和 % 对应于乘、除和取模运算。对于乘运算,会忽略溢出,结果
会简单地截取为整数类型。如果除或者取模运算的右操作数为 0 ,会抛出一个
DivideByZero 异常。

对于 % 操作符的整型操作数,如果操作数为正,则结果符号为正;否则结果符号由具体实
现定义。

对于浮点操作数来说,各种运算同对应的 IEEE 754 浮点运算相同。
浮点数的积表达式不是可结合的。









分享到:
评论

相关推荐

    python从入门到精通地址.txt

    006Pyhon之常用操作符 P8. 007了不起的分支和循环1 P9. 008了不起的分支和循环2 P10. 009了不起的分支和循环3 P11. 010列表:一个打了激素的数组1 P12. 011列表:一个打了激素的数组2 P13. 012列表:一个打了...

    计算机2级C语言考点.pdf

    2. **逻辑短路**: - C语言中的逻辑运算符`&&`和`||`有短路特性。在`&&`表达式中,如果第一个表达式为假,则不会评估第二个表达式;在`||`表达式中,如果第一个表达式为真,则不会评估第二个表达式。 3. **强制...

    实例014——根据指定字符分割字符串.zip

    2. Java: 在Java中,我们使用`split()`方法,它位于`java.lang.String`类中。同样,我们需要提供分隔符作为参数: ```java String str = "你好,世界!欢迎学习"; String[] splitStr = str.split(","); for (String ...

    c语言试题(20210926043229).pdf

    2. **C语言关键字**: - 关键字是C语言预定义的保留词汇,用于特定的语法结构,例如`switch`, `typedef`, `continue`等,如选项B所示。 - `default`、`register`和`enum`是C语言的关键字,而`external`不是,如...

    PHP开发实战1200例(第1卷).(清华出版.潘凯华.刘中华).part2

    全书压缩打包成2部分,这是第2部分。 注:本系列图书的第I、II卷再版时均相应改名为《xxx开发实例大全》(基础卷)及(提高卷),但内容基本无变化,需要的童鞋可自由匹配查找。 内容简介  《PHP开发实战1200例》分为...

    Python学习资料学习课件python基础源码.zip

    006Pyhon之常用操作符 007了不起的分支和循环 008了不起的分支和循环2 009了不起的分支和循环3 010列表:一个打了激素的数组 011列表:一个打了激素的数组2 012列表:一个打了激素的数组3 013元组:戴上了枷锁的列表...

    Visual C++程序开发范例宝典(PDF扫描版).part2

     cc实例240 控件作为字段.c操作符和内容进行查询   cc实例241 巧妙获取年龄   cc实例242 格式化金额   cc实例243 如何随机显示记录   9.3 查询前若干名数据   cc实例244 查询前10名数据   cc实例...

Global site tag (gtag.js) - Google Analytics