关于C/C++ 表达式求值顺序 未定义
表达式的副作用
运算符的优先级与结合性规定了表达式中相邻两个运算符的运算次序,但对于双目
运算的操作数,C++没有规定他们的计算次序。例如,对于表达式:
exp1 + exp2;
先计算 exp1 还是 exp2?不同的编译器有不同的做法。
在数学上,对于双目运算符,不论先计算哪一个操作数,要求最终计算结果一样。
在 C++中,在计算一个操作数时,该计算会改变(影响)另一个操作数,从而导致因操
作数的不同计算次序产生不同的最终计算结果。对于因操作数计算的次序不同产生不同
结果的表达式为带副作用的表达式。在计算时会影响其他操作数的值,引起副作用的运
算符为带副作用的运算符。如++、– –以及各种赋值运算符为带副作用的运算符。例如:
x=1,(x+2)*(++x)
先计算 x+2 表达式的值为 6。
若先计算++x,由于修改了 x+2 中 x 的值,计算结果为8。
在 C++中规定,先计算逻辑与(&&)和逻辑或(||)的第一个操作数,再计算第二
个操作数,以便进行短路求值。条件(?:)、逗号(,)运算符也规定了操作数的计算次序,
除此以外,其他运算符没有规定操作数的计算次序,计算次序由具体的编译器决定。因
此在含这些运算符的表达式中,避免在操作数中引入带副作用的运算符。
表达式求值顺序不同于运算结合性和优先级。下面是一个经典例子,被 ISO C99/ C++98 /03 三大标准明确提到:他的结果是不确定(unspecified) 的。
i = ++i + 1; // The behavior is unspecified
在介绍概念之前,我们先解释一下它的结果。这个表达式( expression )包含3个子表达式( subexpression ):
e1 = ++i
e2 = e1 + 1
i = e2
这三个子表达式都没有顺序点( sequence point ),而 ++ i 和 i = e3 都是有副作用( side effect )的表达式。由于没有顺序点,语言不保证这两个副作用的顺序。
更加可怕的是,如果i 是一个内建类型,并在下一个顺序点之前被改写超过一次,那么结果是未定义(undefined)的!比如本例中如果有:
int i = 0x1000fffe;
i = ++i + 1; // The result is undefined!!
你也许会认为他的结果是加1 或者加2,其实更糟糕 —— 结果可能是 0x1001ffff 。他的高字节接受了一个副作用的内容,而低字节则接受了另一个副作用的内容! 如果i 是指针,那么将很容易造
相关文档:
什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽视,这时也是线程池该出场的机会了。如果线程创建和销毁时间相比任务执行时间可以忽略不计,则没有必要使用线程池了。
下面是 ......
学东西,往往实例才是最让人感兴趣的,老是学基础理论,不动手,感觉没有成就感,呵呵。
下面先来一个实例。我们通过创建两个线程来实现对一个数的递加。
或许这个实例没有实际运用的价值,但是稍微改动一下,我们就可以用到其他地方去拉。
下面是我们的代码:
/*thread_example.c : c multiple thread programmi ......
多继承:
C++中的类可以直接实现多继承 如:class D:public A,public B,public C{……};
Java中不能直接实现这样的多继承,但是可以用接口(interface)来间接实现 如:
public class A{ ……}
public interface C{
public void c1();
public void c2();
}
public class C exten ......
昨天晚上在看C/C++对数据库的操作,猛然间觉得十分亲切,因为其中很多函数都和PHP中对MySQL操作相同,这是才想起PHP是C演化而来的。经过一番捣腾,终于完成了一个简单的程序,但是仍然存在着一个严重的问题,就是从数据库中得到的结果在屏幕上显示的是乱码,很让人烦。还望高手们赐教!
1.在机器上装上MySQL ,假设安装在 C ......