C中的运算符优先级(指针算术)

时间:2019-01-11 20:23:11

标签: c pointers

int* p = malloc(sizeof(int)*5);
*p = 1, *(p+1) = 2, *(p+2) = 3, *(p+3) = 4, *(p+4) = 5;
for(int i = 0; i < 5; i++){
    //what exactly is going on in these lines?
    printf("%d %p\n", (*p++)++, p); 
    //printf("%d %p\n", (*++p)++, p);
    //printf("%d %p\n", ++(*p++), p);
    //printf("%d %p\n", ++(*++p), p);
} 

上面这些行中的运算符优先级是什么?

3 个答案:

答案 0 :(得分:3)

如果在上面的代码中将括号添加到所有可能的歧义表达式中,则会得到:

int p = malloc((sizeof (int)) * 5);
(((((*p) = 1), ((*(p+1)) = 2)), ((*(p+2)) = 3)), ((*(p+3)) = 4)), ((*(p+4)) = 5);
for(int i = 0; i < 5; i++){
    printf("%d %p\n", (*(p++))++, p); 
}

也就是说:

  • sizeof的优先级高于*
  • 一元*的优先级比=高,=的优先级比,高,并且,保持关联性
  • 后缀++的优先级高于一元*

您的代码中没有指针算术,因为没有指针。 int p声明一个int

这就是*p = 1甚至没有编译的原因,因此这段代码实际上没有执行任何操作。

如果您修复了该错误,该代码仍然无法执行任何操作,因为您的(*p++)++, p调用中的printf部分具有未定义的行为:正在修改p并从{{1}中读取},而无需插入顺序点。

答案 1 :(得分:1)

  

* p = 1,*(p + 1)= 2,*(p + 2)= 3,*(p + 3)= 4,*(p + 4)= 5;

等同于(在这种情况下,并不总是)

  

* p = 1; *(p + 1)= 2; *(p + 2)= 3; *(p + 3)= 4; *(p + 4)= 5;


有关

  

printf(“%d%p \ n”,(* p ++)++,p);

执行顺序或参数是不确定的,结果也是如此

P.S。接下来,您要编写代码,请检查是否可以正确编译(int ptr = malloc(sizeof(int)*5);必须为int * p = malloc(sizeof(int)*5);

答案 2 :(得分:1)

让我们画些图片。在前两行之后,您将拥有以下内容:

   +---+---+---+---+---+
   | 1 | 2 | 3 | 4 | 5 |
   +---+---+---+---+---+
     ^
     |
     |
     |
   +---+
p: |   |
   +---+

表达式(*p++)++被解析为(*(p++))++并按以下方式求值:

  p++    - evaluate to the current value of p (&p[0]); as a side effect, 
           update `p` to point to the next object in the sequence (&p[1])
 *p++    - dereference the result of `p++` (p[0])
(*p++)++ - evaluate to the current value of the thing `p` points to 
           (1), then increment the value of that thing.

对该表达式求值后,我们的状态现在为

   +---+---+---+---+---+
   | 2 | 2 | 3 | 4 | 5 |
   +---+---+---+---+---+
         ^
         |
     +---+
     |
   +---+
p: |   |
   +---+

表达式(*++p)++被解析为(*(++p))++并计算为:

  ++p     - evaluate to the current value of p plus 1 (&p[2]), which gives us
            the address of the next object in the sequence; 
            update p to point to the next object (&p[2])
 *++p     - dereference the result of ++p (p[2])
(*++p)++  - evaluate to the current value of thing following what p currently 
            points to (3), and as a side effect increment that thing.

对该表达式求值后,我们的状态现在为

   +---+---+---+---+---+
   | 2 | 2 | 4 | 4 | 5 |
   +---+---+---+---+---+
             ^
             |
     +-------+
     |
   +---+
p: |   |
   +---+

您应该能够计算出另外两个。但是...

声明

printf("%d %p\n", (*p++)++, p);

调用未定义的行为,因为你们都试图读取p并在没有中间序列点的情况下对其进行更新。为p打印的值可能会也可能不会反映来自p++++p的更新。不保证以任何特定顺序对函数参数进行求值。