该语句的优先级是什么?
In which precedence is this statement evaluated?
++*P--;
这是一道考试题,如果 P
指向数组中任何元素的指针,请解释这条语句的真正作用。
我什至写了一个简单的代码来评估它:
int i;
int* array = calloc(10, sizeof(int));
for (i = 0; i < 10; i++) {
array[i] = i;
printf("%d,", array[i]);
}
int* P = array + 5;
printf("\n %p", P);
printf("\n %d", *P);
++*P--;
printf("\n %p", P);
printf("\n %d \n", *P);
for (i = 0; i < 10; i++) {
printf("%d,", array[i]);
}
但输出结果更让我困惑:
0,1,2,3,4,5,6,7,8,9,
0x100105534
5
0x100105530
4
0,1,2,3,4,6,6,7,8,9,
看起来它首先取消引用 P
,然后增加它的值,然后减少指针 P
的值,但为什么呢?
根据 K&R table 2-1 来自 p53(见下图)
++、-- 和 *(取消引用)从右到左具有相同的优先级和结合性。
所以第一步应该是减少P
的值,然后取消引用,然后增加取消引用的值,我错了吗?
你是正确的,优先级是
++(*(P--))
但请注意,减量是一个后缀操作:即使首先更改为 P
,表达式的其余部分仍使用 P
的旧值。因此,在您的示例中,首先 P
递减为 array+4
,但 P--
的值为 array+5
,因此 array[5]
递增。
你可以想象这个表情
++*P--
以下方式
int *tmp = p;
--p;
int value = *tmp;
++value;
这是一个演示程序
#include <stdio.h>
int main( void )
{
char s[] = "Hello World";
char *p = s + 6;
std::printf( "%c\n", ++*p-- );
std::printf( "%s\n", s );
p = s + 6;
char *tmp = p--;
char value = *tmp;
++value;
std::printf( "%c\n", value );
std::printf( "%s\n", s );
}
程序输出为
X
Hello Xorld
Y
Hello Xorld
输出字符串的不同之处在于,表达式++*p--
更改了字符串本身,而表达式++value;
更改了一个单独的对象。但是道理是一样的。
后缀表达式p--
的优先级最高,但其值为p
递减前的值
表达式 ++*p--
中的一元运算符 ++ 和 * 从右到左分组。因此,首先将运算符 * 应用于表达式,然后再应用运算符 ++。
++*P--;
这是一道考试题,如果 P
指向数组中任何元素的指针,请解释这条语句的真正作用。
我什至写了一个简单的代码来评估它:
int i;
int* array = calloc(10, sizeof(int));
for (i = 0; i < 10; i++) {
array[i] = i;
printf("%d,", array[i]);
}
int* P = array + 5;
printf("\n %p", P);
printf("\n %d", *P);
++*P--;
printf("\n %p", P);
printf("\n %d \n", *P);
for (i = 0; i < 10; i++) {
printf("%d,", array[i]);
}
但输出结果更让我困惑:
0,1,2,3,4,5,6,7,8,9,
0x100105534
5
0x100105530
4
0,1,2,3,4,6,6,7,8,9,
看起来它首先取消引用 P
,然后增加它的值,然后减少指针 P
的值,但为什么呢?
根据 K&R table 2-1 来自 p53(见下图)
++、-- 和 *(取消引用)从右到左具有相同的优先级和结合性。
所以第一步应该是减少P
的值,然后取消引用,然后增加取消引用的值,我错了吗?
你是正确的,优先级是
++(*(P--))
但请注意,减量是一个后缀操作:即使首先更改为 P
,表达式的其余部分仍使用 P
的旧值。因此,在您的示例中,首先 P
递减为 array+4
,但 P--
的值为 array+5
,因此 array[5]
递增。
你可以想象这个表情
++*P--
以下方式
int *tmp = p;
--p;
int value = *tmp;
++value;
这是一个演示程序
#include <stdio.h>
int main( void )
{
char s[] = "Hello World";
char *p = s + 6;
std::printf( "%c\n", ++*p-- );
std::printf( "%s\n", s );
p = s + 6;
char *tmp = p--;
char value = *tmp;
++value;
std::printf( "%c\n", value );
std::printf( "%s\n", s );
}
程序输出为
X
Hello Xorld
Y
Hello Xorld
输出字符串的不同之处在于,表达式++*p--
更改了字符串本身,而表达式++value;
更改了一个单独的对象。但是道理是一样的。
后缀表达式p--
的优先级最高,但其值为p
递减前的值
表达式 ++*p--
中的一元运算符 ++ 和 * 从右到左分组。因此,首先将运算符 * 应用于表达式,然后再应用运算符 ++。