请帮助我理解以下表达式:
(见一本书)
*((int *)marks + i++) = i+1
大量的增量和符号引用令人困惑!
答案 0 :(得分:5)
我希望这本书有一个不好的例子,因为它的行为是未定义的。
(int *)marks
将marks
(无论可能是什么)解释为指向int
的指针,然后我们将i++
的结果添加到该i+1
。取消引用此指针,并将i
分配给相应的对象。
此表达式没有已定义的行为,因为它在两个不同的子表达式中读取和修改{{1}}。
答案 1 :(得分:5)
烧掉这本书。
由于没有序列点,语句的行为是未定义。一个更简单的理解案例是i++ = i
,它也是未定义的。
答案 2 :(得分:0)
注意:正如其他人所说,i++
表达式是未定义的行为。在g ++中,i++
操作将按如下方式执行:
// Pointer to some data.
void* marks = ???;
// Typecast to an integer pointer
int* marksIntPointer = (int*)marks;
// Move the position in memory. I am assuming that 'marks' is an array.
int* marksIntPointerOffset = marksIntPointer + i;
// Undefined behaviour, could take place here or before, depending on the compiler (as others have said).
i++;
// Set the value of the desired memory.
*marksIntPointerOffset = i+1;
答案 3 :(得分:0)
上述表达式产生 未定义的行为 。
C996.5§2陈述:
1)在前一个和下一个序列点之间,一个对象应具有其存储的值 通过表达式的评估最多修改一次。
2)此外,只读取先前值以确定要存储的值。
1)在单个表达式中存储和修改变量的值非常简单:
i = ++i;
i++ = i;
++i = 7;
以及在单个表达式中多次修改同一变量的值:
j = ++i + ++i;
2) 只读以确定要存储的值 可能有点棘手。这意味着即使以下(就像前面的例子一样)也会调用未定义的行为:
j = (i + 1) + i++;
a[i++] = i;
*(ptr + i++) = i;
以及:
*((int *)marks + i++) = i+1
答案 4 :(得分:0)
正如其他人所说,行为未定义;通过删除++
运算符,以下代码将被很好地定义(但仍然像罪一样丑陋):
*((int *)marks + i) = i+1
以下是它如何分解:
marks -- take the expression marks
(int *)marks -- cast it as a pointer to int
(int *)marks + i -- offset i integer elements from that address
*((int *)marks + i) -- deference the result to get an array element
*((int *)marks + i) = i+1 -- assign the result of i+1 to that element
这主要是将marks
视为int
的数组,并将i+1
的结果分配给i
元素:
int *mp = (int *) marks;
mp[i] = i+1
原始表达试图
mp[i++] = i+1
调用未定义的行为。由于未指定评估i++
和i+1
的顺序;编译器可以按任何顺序自由评估它们。由于i++
有副作用(更新i
的值),这意味着您将根据平台,优化设置甚至周围的代码获得不同的结果。语言标准明确地保留行为 undefined ,以便编译器不需要以任何特定方式处理此代码。您将获得一个结果,但不保证从编译器到编译器(甚至从运行到运行)都是一致的。
答案 5 :(得分:-2)
(int *)marks
将标记转换为int指针
+ i++
在标记处添加i(查找指向的地址)然后将i递增1
*(...) = i+1
设置我们的指针指向i + 1的单元格的VALUE(注意我之前已经增加的事实,因此在指令开始时它将大于2。
我希望这是一个不应该编写代码的例子:)
答案 6 :(得分:-2)
让我们看看。
*((int *)marks + i ++)= i + 1
-marks被强制转换为指向int
的指针
-i增加1
- 使用指针运算
使指针(int *)标记前进值(i + 1)
- 这个指针现在被解除引用,所以......
-...它指向的内存位置现在用i + 1