【问题标题】:What place does post increment and post decrement operators have in the rules of operator precedence in c language后自增和后减运算符在c语言中运算符优先级规则中的位置
【发布时间】:2017-05-10 01:09:07
【问题描述】:

根据此link 中的信息,后自增和自减运算符位于首位。而这个link 说“举个例子:

foo = *p++;

这里 p 作为表达式的副作用而递增,但 foo 采用 *(p++) 而不是 (*p)++ 的值,因为一元运算符从右到左绑定"。

但是在这样做之后,这些链接中提到的信息几乎没有发生任何事情。

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 1;
    int *iptr;
    iptr = &i;
    int num = *iptr++;//1) In this expression the value of 'i' is assigned to num. And an attempt of post incrementing the address stored in *iptr is done as side effect.
    printf("Num value: %d\n",num);

    printf("Pointer: %d\n",*iptr);//2) The address of *iptr is not incremented. If it was then the value of 'i' would not be printed instead it would print the incremented address itself.

    printf("Post increment: %d\n",*iptr++);//3) The address of *iptr will be post incremented (which didn't happen in case of num). But for now the value of 'i' will be printed.

    printf("After increment: %d\n",*iptr);//4) Now the incremented address stored in *iptr will be displayed as there is no value assigned to that address.
    return 0;
}

在上面的实验中,只有在语句终止符之后才能看到后置增量的效果。但是,如果在赋值运算符的右操作数上完成后递增,即使在语句终止符之后也看不到任何效果。例如 int num = *iptr++; (如上述实验所述)。那么在运算符优先级规则中,后自增和自减运算符到底处于什么位置。

【问题讨论】:

  • 你怎么知道没有看到效果?这对你有什么作用?看到或没有看到的效果与运算符优先级有什么关系?
  • 在 (1) 中增加的是 iptr,而不是 *iptr

标签: c operators operator-precedence


【解决方案1】:

您的代码的问题在于它具有未定义的行为:当您将指针指向单个局部变量时,取消引用递增的指针会产生未定义的行为。

为指向数组的指针明确定义了取消引用递增的指针。

int array[] = {1, 2, 3};
int *iptr = &array[0];
int num = *iptr++;

另外,使用%d 和解引用运算符打印iptr 是不正确的:您需要在将iptr 转换为void* 之后使用%p 打印它,而无需取消引用:

printf("Pointer: %p\n", (void*)iptr);
// No asterisk here -----------^

现在一切正常 (demo)。

【讨论】:

  • 不同意“将指针指向单个局部变量,增加指针会产生未定义的地址。”确实,递增的指针不应被取消引用,但指针本身根据“过去”规则是有效的,并且“指向不是数组元素的对象的指针与指向第一个元素的指针的行为相同长度为 1 的数组”C11 §6.5.6 7-8
  • @chux 你是对的,“过去”规则允许 OP 将指针递增一次。不过,第二个增量应该是 UB。我对 UB 声明进行了编辑以更加保守。谢谢!
  • BTW 早期祝贺 1/2 百万。
  • @chux 非常感谢!
  • 非常感谢您的所有努力。
猜你喜欢
  • 1970-01-01
  • 2011-08-29
  • 2021-10-25
  • 2013-10-02
  • 2013-06-18
  • 2018-08-22
  • 1970-01-01
  • 2021-03-08
  • 1970-01-01
相关资源
最近更新 更多