将此主题视为以下主题的续篇:
上一部分
未定义的行为和序列点
让我们重新审视这个有趣而复杂的表达(斜体短语取自上述主题*smile*):
i += ++i;
Run Code Online (Sandbox Code Playgroud)
我们说这会调用undefined-behavior.我假定说这个的时候,我们隐含假设型的i是内置的类型之一.
如果什么类型的i是用户定义类型?比如它的类型是Index在本文后面定义的(见下文).它还会调用未定义的行为吗?
如果是,为什么?它不等同于写作i.operator+=(i.operator++());甚至语法上更简单 i.add(i.inc());吗?或者,他们是否也调用未定义的行为?
如果不是,为什么不呢?毕竟,对象在连续的序列点之间i被修改两次.请回想一下经验法则:表达式只能在连续的"序列点"之间修改一个对象的值.如果 i += ++i是表达式,那么它必须调用未定义的行为.如果是,那么它的等价物i.operator+=(i.operator++());也 i.add(i.inc());必须调用undefined-behavior似乎是不真实的!(据我所知)
或者,i += ++i不是一个开头的表达?如果是这样,那么它是什么以及表达式的定义是什么?
如果它是一个表达式,并在同一时间,其行为也是定义良好的,那么就意味着与表达相关序列点的数量在某种程度上取决于该类型的参与表达操作数.我是否正确(甚至部分)?
顺便问一下,这个表达怎么样?
//Consider two cases:
//1. If a is an array of a built-in type
//2. If a is user-defined type which overloads the …Run Code Online (Sandbox Code Playgroud) 我们可以写一个if声明
if (a == 5, b == 6, ... , thisMustBeTrue)
Run Code Online (Sandbox Code Playgroud)
只有最后一个条件才能进入if身体.
为什么允许?
免责声明: 这不是一个真实的例子.这只是这些语言如何运作的理论问题.
在发布和预增量运算符方面,C/C++,C#和Java之间究竟有什么区别?
这是我用VC++ 10,Java 1.6和C#4获得的
int a = 2;
int b = a++ + a++;
int c = ++a + a++ + a++;
+-----+------+------+----+
| C | C++ | Java | C# |
+-----+-----+------+------+----+
| a | 7 | 7 | 7 | 7 |
+-----+-----+------+------+----+
| b | 4 | 4 | 5 | 5 |
+-----+-----+------+------+----+
| c | 15 | 15 | 16 | 16 |
+-----+-----+------+------+----+
Run Code Online (Sandbox Code Playgroud) 可能重复:
为什么+++++ b在C中不起作用?
我从David Simon的"嵌入式软件入门"第113页得到了这个.
我在下面看到这句话:
iHoursTemp = iHoursTemp + iZoneNew ---iZoneOld;
Run Code Online (Sandbox Code Playgroud)
你能真的在这条线上有三个减号吗?三重减号是什么意思?
我相信这是一个C编程声明.
在浏览某个项目的代码时,我遇到了以下声明:
++x %= 10;
Run Code Online (Sandbox Code Playgroud)
这个陈述是用C++很好地定义的,还是属于同一类别
a[i] = i++
Run Code Online (Sandbox Code Playgroud)
?
我在测试中被问到以下问题(我不想自己编写.测试问它.我知道它的代码还不错)关于评估++*ptr ++
int Ar[ ] = { 6 , 3 , 8 , 10 , 4 , 6 , 7} ;
int *Ptr = Ar ;
cout<<++*Ptr++ ;
Run Code Online (Sandbox Code Playgroud)
但是,我怀疑这是未定义的行为,因为它可以是(++*ptr)++或两者++(*ptr++).是吗?我不太熟悉文档,所以我找不到任何东西.
以下测试程序
#include <map>
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
map<int,int> a;
a[1]=a.size();
for(map<int,int>::const_iterator it=a.begin(); it!=a.end(); ++it)
cout << "first " << (*it).first << " second " << (*it).second << endl;
}
Run Code Online (Sandbox Code Playgroud)
在g++ 4.8.1(Ubuntu 12.04 LTS)上编译时导致不同的输出:
g++ xxx.cpp
./a.out
first 1 second 1
Run Code Online (Sandbox Code Playgroud)
在Visual Studio 2012(Windows 7)上(标准Win32控制台应用程序项目):
ConsoleApplication1.exe
first 1 second 0
Run Code Online (Sandbox Code Playgroud)
哪个编译器是对的?难道我做错了什么?
运行以下代码:
// In Java, output #####
public static void main(String[] args) {
int i = 1;
if(i == (i = 2)) {
System.out.println("@@@@@");
} else {
System.out.println("#####");
}
}
Run Code Online (Sandbox Code Playgroud)
但:
// In C, output @@@@@?I did test on Clion(GCC 7.3) and Visual Studio 2017
int main(int argc, char *argv[]) {
int i = 1;
if(i == (i = 2)) {
printf("@@@@@");
} else {
printf("#####");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
提出这个问题的动机来自以下代码:
// The code is from the JDK 11 - java.util.concurrent.atomic.AtomicInteger …Run Code Online (Sandbox Code Playgroud) 我有一个行代码,
int a = 10;
a = ++a * ( ++a + 5);
Run Code Online (Sandbox Code Playgroud)
我的预期产量是12 * (11 + 5) = 192,但我得到187.我知道内部的增量运算符()首先要解决,然后为什么首先解决外部的增量运算符?
我正在读这个问题:
并且,特别是C++ 11的答案,我理解评估的"排序"的想法.但是 - 写作时是否有足够的顺序:
f(x++), g(x++); ?
也就是说,我保证f()获得原始值x并g()获得一次递增x?
挑剔的注意事项:
operator++()已定义的行为(即使我们已经重写它),这样做f()和g(),没有异常将被抛出,等-这个问题是不是有关.operator,()没有超载.c++ ×8
c ×3
java ×3
c# ×1
c++-faq ×1
c++11 ×1
comma ×1
evaluation ×1
expression ×1
g++ ×1
if-statement ×1
side-effects ×1