c++中指针的递增和解引用顺序
Order of incrementing and dereferencing pointer in C++
我指导学生学习c++,最近遇到了一个涉及数组名称的指针算术问题。我最困惑的是语句
T min_value = *begin++;
Cplusplus告诉我++操作符比*解引用操作符具有更高的优先级,因此我假设首先对begin进行加1操作,然后再对其解引用。此外,本站点还确认,当将数组的名称传递给函数时,它会被转换为指向第一个元素element[0]地址的指针。然而,当我在Visual Studio中运行下面的代码时,看起来min_value在开始时被设置为1.5,这似乎与我认为的操作顺序相矛盾。
我认为应该是:
- 增加指向[1]元素(数组中的第二个元素)的begin指针
- 取消对指针值的引用
- 设置min_value等于数组中的第二个元素。
然而,我的实验似乎表明发生了一些不同的事情:
- 解引用指针值 设置min_value等于数组的第一个元素
- 指向下一个元素的增量指针
// Problem #3: Please write the implementation of min() function and max() function..
#include <iostream>
using namespace std;
template<typename T>
T min(T* begin, T* end)
{
T min_value = *begin++;
while(begin != end) // You can use for-loop too.
{
if( *begin < min_value)
min_value = *begin;
begin++;
}
return min_value;
}
template<typename T>
T max(T* begin, T* end)
{
T max_value = *begin++;
while(begin != end)
{
if( *begin > max_value)
max_value = *begin;
begin++;
}
return max_value;
}
int main()
{
double arr[] = { 1.5, 4.5, 3.5, 2.5, 5.5 };
int values[] = { 1, 2, 3, 4, -1, 5 };
cout << "min of arr[] is : " << min(arr, arr + 5) << endl;
cout << "min of values[] is : " << min(values, values + 6) << endl;
cout << "max of arr[] is : " << max(arr, arr + 5) << endl;
cout << "max of values[] is : " << max(values, values + 6) << endl;
}
优先级只是如何解析代码的规则。第一是++
,第二是*
。但是在执行代码时,必须考虑操作符的实际作用。
在你的例子中,会发生以下情况:
- 复制
begin
文件 - 原值递增
- 副本返回。
- 副本被解引用
- 副本分配给
min_value
这就是后自增操作符的工作方式,当您为自己的类型重载操作符时,也是这样编写操作符的:
T operator++(int)
{
T copy = *this;
++(*this);
return copy;
}
实际上,在内置自增后操作符的情况下,递增不一定是第2步。只要可观察到的行为是相同的,它也可能在稍后发生。例如,没有什么可以阻止编译器在返回副本后对原始值进行加1。当然,您不能在自己的重载操作符中执行这样的操作。
这个表达式
T min_value = *begin++;
可以这样想象
auto temp = begin;
T min_value = *temp;
++begin;
根据c++标准(5.2.6自增和自减)
1后缀++表达式的值 its的值操作数。[注:获取的值为原始值的副本。-结束提示]…对++表达式的值计算进行排序
在一般情况下,函数定义是错误的,因为begin
和end
指定的范围可以为空,并且begin可以指向超出有效范围。在这种情况下,既不能增加也不能取消对begin的引用。
所以更正确的写法是
template <typename T>
T * min( T* begin, T* end )
{
T *min_value = begin;
if ( begin != end )
{
while( ++begin != end )
{
if( *begin < *min_value ) min_value = begin;
}
}
return min_value;
}
在这种情况下,函数的调用看起来像
cout << "min of arr[] is : " << *min(arr, arr + 5) << endl;
^^^
不要混淆操作符的返回值和优先级。
第一个语句处理操作符返回的内容,第二个语句处理发生的时间。
所以如果你有:
T min_value = *begin++;
下面是它的工作原理:
-
operator++
-它增加指针,但返回原来的指针。 -
operator*
-对先前返回的指针解引用,返回它指向的T。 -
operator=
将左侧存储到右侧,返回右侧。
不使用最后一个返回值,但理论上可以。
请注意,在#2中使用了#1的返回值,而不是再次访问指针。
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 何时在引用或唯一指针上使用移动语义
- 如何在c++中使用引用实现类似python的行为
- 编译C++时未定义的引用
- Ctypes wstring通过引用传递
- c++r值引用应用于函数指针
- 理解c++中的引用
- C++取消引用指针.为什么会发生变化
- 将代码声明放入字中(引用操作符和解引用操作符混淆)
- 指向根的二叉树指针需要被引用和解引用.为什么
- 指针引用和解引用
- c++中指针的递增和解引用顺序
- 理解引用和解引用操作符
- 使用指针和解引用指针按引用传递
- 直接访问变量(而不是使用指针和解引用)会得到不同的值吗?
- 将映射结构强制转换为void指针和解引用
- c++的引用和解引用
- 同一指令中的引用和解引用