递增指针,精确序列 [英] Incrementing Pointers, Exact Sequence

查看:124
本文介绍了递增指针,精确序列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习C,我得到

I have just started to learn C, and I get that

*a = *b;
a++;
b++;

*a++ = *b++

是等价的,但是什么是实际发生时行

are equivalent, but is that what's actually happening when the line

*a++ = *b++

被称为?有人可以阐明如何编译器间preting第二行?我知道从右到左precedence等,但可有人precisely写编译器用来跨preT这行code的步骤?

is called? Can someone clarify how the compiler is interpreting the second line? I know about right-to-left precedence and such, but can someone precisely write the steps the compiler uses to interpret this line of code?

推荐答案

您说,您认为:

*a = *b; a++; b++;

等同于

*a++ = *b++;

不过那是假的,让你有一个错误的信念。让我们来纠正你的错误信念。

but that is false, so you have a false belief. Let's correct your false belief.

在第一种情况下,下面的事情一定会发生:

In the first case, the following things must happen:


  • VAR: *一个必须进行评估,以产生一个变量,称之为 VAR

  • VAL: * B 必须进行评估,以产生一个值,称之为 VAL

  • 分配: VAL 必须分配给 VAR

  • INCA: A 必须递增

  • 麻管局: B 必须递增

  • VAR: *a must be evaluated to produce a variable, call it var
  • VAL: *b must be evaluated to produce a value, call it val
  • ASSIGN: val must be assigned to var.
  • INCA: a must be incremented.
  • INCB: b must be incremented.

什么是编译器会如何订购这些约束?

What are the constraints on how the compiler may order those?


  • VAR和VAL必须分配之前发生的。

  • 分配必须INCA发生之前。

  • INCA前必须麻管局。发生

这里的规则是:一个语句的所有副作用在下一个语句开始之前完成。的那么有两种法律的排序。 VAR VAL ASSIGN INCA麻管局或VAL VAR ASSIGN INCA麻管局。

The rule here is that all the side effects of one statement have to be complete before the next statement starts. So there are two legal orderings. VAR VAL ASSIGN INCA INCB, or VAL VAR ASSIGN INCA INCB.

现在让我们考虑第二种情况。

Now let's consider the second case.

*a++ = *b++;

我们有相同的五个操作,但对他们的订货的约束是完全不同的,因为这些都是在同一个语句,所以对报表中的规则不适用。现在的约束条件是:

We have the same five operations, but the constraints on their ordering are completely different because these are all in the same statement, so the rule about statements does not apply. Now the constraints are:


  • VAR和VAL必须分配之前发生的。

  • VAR的评估必须使用的原始值 A

  • VAL的评估必须使用的原始值b

  • VAR and VAL must happen before ASSIGN.
  • the evaluation of VAR must use the original value of a
  • the evaluation of VAL must use the original value of b

请注意,我说的增量都需要发生后没的说。相反,我说的原始值必须使用只要原来的值时,增量可以发生在任何时间。

Note that I did not say that the increments are required to happen afterwards. Rather, I said that the original values must be used. As long as the original value is used, the increment can happen at any time.

因此​​,例如,这将是完全合法的,以产生此作为

So for example, it would be perfectly legal to generate this as

var = a;
a = a + 1; // increment a before assign
*var = *b;
b = b + 1; // increment b after assign

这也将是法律要做到这一点:

It would also be legal to do this:

val = *b;
b = b + 1; // increment b before assign
*a = val;
a = a + 1; // increment a after assign

这也将是合法的,因为你的建议做:首先做的任务,然后在这两个增量从左向右的顺序。而且这也将是法律先做作业,然后再从右到左的顺序。这两个增量

It would also be legal to do it as you suggest: do the assignment first, and then both increments in left-to right order. And it would also be legal to do the assignment first, and then both increments in right-to-left order.

一个C语言编译器被赋予广阔的纬度生成code是什么样子了这种前pression的。确保这是在你的头脑很清楚,因为大多数人都犯了这个错误:只是因为 ++ 变量来后,并不意味着增量后期发生的增量可早在编译器喜欢的只要编译器将确保原始值用于发生

A C compiler is given broad latitude to generate code however it likes for this kind of expression. Make sure this is very clear in your mind, because most people get this wrong: just because the ++ comes after the variable does not mean that the increment happens late. The increment can happen as early as the compiler likes as long as the compiler ensures that the original value is used.

这对C和C ++的规则。在C#中,语言规范要求赋值左侧的副作用发生的的赋值右侧的副作用,而且分配的副作用之前都发生。在C#中同一code会的需要的被作为生成:

That's the rule for C and C++. In C#, the language specification requires that the side effects of the left side of an assignment happen before the side effects of the right side of an assignment, and that both happen before the side effect of the assignment. That same code in C# would be required to be generated as:

var_a = a;
a = a + 1;
// must pointer check var_a here
var_b = b;
b = b + 1;
val = *var_b; // pointer checks var_b
*var_a = val;

指针检查是指C#要求在运行时验证 var_a 是一个有效的指针点;换句话说,即 * var_a 实际上是一个变量。如果不是,那么它必须抛出一个异常的 B 进行评估。

The "pointer check" is the point at which C# requires that the runtime verify that var_a is a valid pointer; in other words, that *var_a is actually a variable. If it is not then it must throw an exception before b is evaluated.

同样,C编译器的允许的做C#的方式,但不是的需要的到。

Again, a C compiler is permitted to do it the C# way, but not required to.

这篇关于递增指针,精确序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆