我用C ++教学生,最近遇到了一个涉及指针算法和数组名称的问题。我感到困惑的主要是声明
T min_value = *begin++;
Cplusplus告诉我++运算符的优先级高于* dereference运算符,所以我假设begin首先递增然后解除引用。此外,this站点确认当您将数组的名称传递给函数时,它将变为指向第一个元素的地址的指针,元素[0]。但是,当我在Visual Studio中运行下面的代码时,看起来min_value在开始时设置为1.5,这似乎与我认为的操作顺序相矛盾。
我认为应该是:
然而,我的实验似乎表明发生了不同的事情:
有人可以澄清一下吗?
// 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;
}
答案 0 :(得分:2)
优先级只是解析代码的规则。 ++
排在第一位,*
排在第二位。但是当代码执行时,你必须考虑操作符实际上做什么。
在您的情况下,会发生以下情况:
begin
的副本。min_value
。这就是后增量运算符的工作原理,以及在为自己的类型重载运算符时如何编写运算符:
T operator++(int)
{
T copy = *this;
++(*this);
return copy;
}
实际上,在内置后增量运算符的情况下,增量不一定必须是步骤2.只要可观察行为相同,它也可能在稍后发生。例如,没有什么能阻止编译器在返回副本后递增原始值。当然,你无法在自己的重载运算符中执行这样的操作。
答案 1 :(得分:1)
此表达式
T min_value = *begin++;
可以通过以下方式想象
auto temp = begin;
T min_value = *temp;
++begin;
根据C ++标准(5.2.6增量和减量)
1后缀++表达式的值其值 操作数即可。 [注意:获得的值是原始值的副本 -end note] ...对++表达式的值计算进行排序 在修改操作数对象之前。
一般情况下,函数定义是错误的,因为begin
和end
指定的范围可以为空,并且begin可以指向有效范围之外。在这种情况下,你既不会增加开始也不会取消引用它。
因此,以下列方式编写
更为正确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;
^^^
答案 2 :(得分:1)
您不应混淆运营商的返回值和优先级。
第一个是处理操作员返回的内容,第二个是处理发生的事情。
所以如果你有:
T min_value = *begin++;
以下是它的工作原理:
operator++
- 它递增指针,但返回原来的指针。operator*
- 取消引用先前返回的指针,返回它指向的T。operator=
将左侧存放到右侧,返回右侧。你没有使用最后一个返回值,但理论上你可以。
请注意,在#2中,您使用#1的返回,而不是再次访问指针。