坑人的运算符

一、运算符优先级

前两天我在园子的首页看到一篇篇随笔,随笔地址已经找不到了(着实有点抱歉),不过其中的一个代码片段还是记得一二,大概如下:

            Thread t = null;
            string message = "I‘m ..." + t == null ? "And ..." : "";
            Console.WriteLine(message);

代码很少,但我想有不少人会招,最关键的问题就是运算符的优先级了。这里是 C#参考 运算符,根据这份优先级顺序,我总结出以下规律: 

最高:.(点) ()  []  i++  i-- 

其次:单目运算符(i++ 高于 ++i)

然后:先算乘除余、后算加减、最后位移、比大小(大于小于 高于 相等和不等)

接下来:Not And Or ( 即 ! , && , || )

最后:三目 、赋值 和 Lambda

这份优先级顺序已经包含了大部分运算符,只要不是遇到很变态的问题,我想应该可以搞定。

二、编译器的贪心原则

该话题源于《Java深入解析——透析Java本质的36个话题》。(虽然源于Java话题,但同样适用于C#、已验证)

三个加号该如何运算呢? 代码片段如下:

            int i = 10;
            int j = 20;
            int k = i +++ j; // 代码未格式化,但可以正常编译运行
            Console.WriteLine(k); // 输出结果是多少呢? 是 30 还是 31?

我们先不看答案,先把代码格式化一下、看看结果:  

int k = i++ + j; // 格式化后的结果,为何不格式化成 i + ++j; 呢? 答案是:编译器的贪心原则

贪心原则:编译器在分析符号的时候会尽可能多的结合有效的符号。  

因为“+” 和 “++”都是有效的符号,但是“+++”不是有效的符号,因此,将表达式解析为了:i++ + j。

再举个例子:a--b,本意为a - 负b。但是编译器解析为了 a-- b,最终编译不通过。所以代码应该这样写:a - -b;

三、 i++你真的理解了吗?

这个例子我第一次看到、是在一份笔试试卷上,如果你能说出下面这个代码片段的正确答案,那这部分就没有必要看了,如果不能也许你走入了一个“误区”。

            int i = 0;
            i = i++;
            Console.WriteLine(i); // 1 or 0?

我在记忆 i++和++i 的时候,不是记忆“先加”还是“后加”的,而是直接记住“运算结果”。

i++的运算结果:表达式的值等于 i    ,i的值自加1.

++i的运算结果:表达式的值等于 i+1,i的值自加1.

也就是说:

i = i++; // 右侧表达式的结果等于i本身,然后执行赋值运算符赋值,最后得到的i的结果还是 i本身.

四、零除以零等于什么?


有人也许会说:“小学生都知道啊,0不能做除数”,如果是这样那恭喜你,答对了。但是只能得6分(满分10分)。为啥呢?看代码吧!

        static void Main(string[] args)
        {
            float x = 0;
            float result = x / x;
            Console.WriteLine(result); // 输出结果:非数字

            Console.Read();
        }

此话题只是个引子,更多信息请参见:Single.NaN

坑人的运算符,确实很坑人啊。

时间: 2024-10-03 13:28:05

坑人的运算符的相关文章

java中的三元运算符详解

最近在带领实习生中遇到很多新手问与三元运算符有关的java题目,多数为代码结果题,少数为应用题.鉴于很多资料上对于java三元运算的讲解过于简单,网上的资料与题目也不是很完善,对于结果答案分析不一,故在此总结,当然仅为个人观点,水平有限,不足之处,还请大家多多指出,互相交流学习. 什么是java三元运算符呢?无疑其操作元有三个,第一个是条件表达式,剩余两个为值,条件表达式为真时运算取第一个值,为假时取第二个值. 其示例代码如下:boolean a = 20 < 45 ? true : false

Mysql运算符与函数(胖胖老师)

use test;create table `employee`(    emp_no int unsigned,    emp_name varchar(30),    emp_sex varchar(3),    emp_age tinyint unsigned,    sal double,    history datetime);insert into employee values(1, '张三', '男', 18, 5000, '2012-04-23'),(2, '李四', '男'

MySQL数据库中的算术运算符

MySQL数据库中的算数运算符 MySQL数据库中的算术运算符 一.运算符的概述: 运算符在MySQL数据库中也是很重要的知识体,在执行sql语句的时候这个运算符对操作数据帮助很大.其中运算符的运用可以帮助你减省大量的时间,操作起来也比较灵活. 二.运算符 运算符主要包括"算数运算符"."比较运算符"."罗运算符"."位运算符"四大类,下面我们就一次学习一下. 1.算术运算符 算术运算符在sql语句的时候经常使用,例如对表的字

重载&gt;&gt;运算符

#include <iostream>   #include <stdio.h>   using namespace std;   class Input   {       public:          //实际重载是右移运算符          Input & operator >> (int &a)          {              scanf("%d",&a);              fflush

JS中的运算符&amp;JS中的分支结构

一.JS中的运算符 1.算术运算(单目运算符) + 加.- 减.* 乘./ 除.% 取余.++ 自增.-- 自减 >>> +:有两种作用,连接字符串/加法运算.当+两边全为数字时,进行加法运算: 当+两边有任意一边为字符串时,起连接字符串的作用,连接之后的结果为字符串 除+外,其余符号运算时,会先尝试将左右变量用Number函数转为数字 >>> /: 结果会保留小数点 >>> ++: 自增运算符,将变量在原有基础上+1: --: 自减运算符,将变量在原

java基础语言 运算符

/* ++,--运算符的使用: 单独使用: 放在操作数的前面和后面效果一样.(这种用法是我们比较常见的) 参与运算使用: 放在操作数的前面,先自增或者自减,然后再参与运算. 放在操作数的后面,先参与运算,再自增或者自减. 作用:就是对变量进行自增1或者自减1. */ public class Text3 { public static void main(String[] args) { //定义两个变量 int x = 3; int y = 4; //单独使用 //x++; //y--; ++

集合和三元运算符

一.三元运算符 如下判断可以使用三元运算更方便的实现: a = 1b = 2 if a > 1: c = aelse: c = b 和下面是一样的: a = 1b = 2#下面这个c = a if a>1 else b 如下两种方法也是一样的:方式一: s=[]nums = list(range(1,11))for i in nums: if i%2==0: s.append(i)print(s)方式二:ss = [i for i in nums if i%2==0]print(ss)#这两种

2_C语言中的数据类型 (八)运算符

1          运算符表达式和语句 1.1       基本运算符 1.1.1          = 数据对象:泛指数据在内存的存储区域 左值:表示可以被更改的数据对象 右值:能赋给左值的量 1.1.2          + 加 1.1.3          – 减 1.1.4          * 乘 1.1.5          / 除 1.1.6          % 取余数 1.1.7          += 加等于 1.1.8          -= 减等于 1.1.9     

(17)Powershell中的重定向运算符

默认情况下,Powershell 把输出发送到屏幕显示.但是,Powershell也可以将输出重定向至一个文本文件,或将错误输出重定向至常规输出流. 重定向运算符有什么用 ? 重定向运算符意味着我们可以将命令的输出信息输出到指定的文件,完全满足脚本中的log的要求,即可以利用重定向打印脚本或命令执行的详细信息. Powershell 中有以下重定向运算符. 运算符 说明 示例 > 将输出发送到指定文件. PS D:\> Get-Process > process.txt >>