指针算术表达式算作指令吗?
Do pointer arithmetic expressions count as instructions?
我编写了一个程序来翻转数组中相邻的元素。例如
1, 2, 1, 2
变为 2, 1, 2, 1
我写的代码是:
#include <iostream>
template <class T>
void swap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
template <class T>
void oReverse(T* p, int size){
for(T* e = p + size; p < e; p+=1){
swap(*p, *p++);
}
}
int main(){
int arr[] = {1,2,1,2,1,2};
oReverse(arr, 6);
for(int i = 0; i < 6; i++){
std::cout << arr[i] << " ";
}
return 0;
}
oReverse()
函数处理指针魔法。
我无法理解的是:为什么 swap(*p, *p++)
将 p 递增 1。
起初我在for循环里写了p+=2,但是效果不好,但是用p++就可以了。
我以为程序会交换 p 和 p++,然后将 p 递增 2,然后一次又一次地交换 p 和 p++。
希望我把问题解释清楚了。
首先,*p++
递增 p
在 值被获取之后。所以而不是
swap(*p, *p++);
您想这样做:
swap(*p, *++p);
但这也行不通。该标准没有定义函数参数的计算顺序。所以而不是
swap(*p, *++p);
写
swap(*p, *(p+1));
p++;
这样你就安全了。它们的行为不等价,因为求值顺序is unspecified。但他们的预期行为是等价的。
对于“预期行为”,我指的是不知道标准未定义评估顺序的人通常会期望的行为。
编辑:
在 C++17 之前未指定计算顺序,但从 开始,但是仍然不要那样做。 “聪明”的构造往往会引起问题。
我编写了一个程序来翻转数组中相邻的元素。例如
1, 2, 1, 2
变为 2, 1, 2, 1
我写的代码是:
#include <iostream>
template <class T>
void swap(T& a, T& b){
T temp = a;
a = b;
b = temp;
}
template <class T>
void oReverse(T* p, int size){
for(T* e = p + size; p < e; p+=1){
swap(*p, *p++);
}
}
int main(){
int arr[] = {1,2,1,2,1,2};
oReverse(arr, 6);
for(int i = 0; i < 6; i++){
std::cout << arr[i] << " ";
}
return 0;
}
oReverse()
函数处理指针魔法。
我无法理解的是:为什么 swap(*p, *p++)
将 p 递增 1。
起初我在for循环里写了p+=2,但是效果不好,但是用p++就可以了。
我以为程序会交换 p 和 p++,然后将 p 递增 2,然后一次又一次地交换 p 和 p++。
希望我把问题解释清楚了。
首先,*p++
递增 p
在 值被获取之后。所以而不是
swap(*p, *p++);
您想这样做:
swap(*p, *++p);
但这也行不通。该标准没有定义函数参数的计算顺序。所以而不是
swap(*p, *++p);
写
swap(*p, *(p+1));
p++;
这样你就安全了。它们的行为不等价,因为求值顺序is unspecified。但他们的预期行为是等价的。
对于“预期行为”,我指的是不知道标准未定义评估顺序的人通常会期望的行为。
编辑:
在 C++17 之前未指定计算顺序,但从