for (i = 0; i < t; i++)
{
values.clear();
scanf("%d %d %d", &values[0], &values[1], &values[2]);
printf("%d %d %d\n", values[0], values[1], values[2]);
sort(values.begin(), values.end());
printf("%d %d %d\n", values[0], values[1], values[2]);
printf("Case %d: %d\n", i + 1, values[1]);
}
Run Code Online (Sandbox Code Playgroud)
我有那个小片段.我输入"1200 1500 1800"它应该给我中间值 - 1500.但是,它输出1200,最小值.
我所做的是使用STL的sort()来对矢量进行排序,然后打印值[1],这是中间值.
但是,sort()似乎根本不起作用,之前和之后的打印矢量是相同的.
我用以下内容声明我的向量:
vector<int> values (3);
Run Code Online (Sandbox Code Playgroud)
我尝试用它vector<int> values;然后push_back(0)三次声明它.
我想知道为什么它不能以第一种方式工作.
您的程序具有未定义的行为.
要修复它,只需删除此行:
values.clear();
Run Code Online (Sandbox Code Playgroud)
事实上,上述行的作用是擦除向量中的所有元素.然后,这一行:
scanf("%d %d %d", &values[0], &values[1], &values[2]);
^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
将尝试访问不存在的元素.与operator []关联容器不同,operator []对于向量不会创建任何新元素.因此,表达式values[0],values[1]和values[2]都是尝试访问不存在的元素.
根据C++ 11标准的表101:
表达:
a[n]返回类型:参考;
const_reference为了恒定a操作语义:
*(a.begin() + n)
这意味着通过这样做:
values[0]
Run Code Online (Sandbox Code Playgroud)
你实际上是这样做的:
*(values.begin() + 0)
Run Code Online (Sandbox Code Playgroud)
对values.begin()此处的调用将迭代器返回到数组中的第一个元素.由于向量中没有元素(第23.2.1/6节),因此调用values.begin()等同于对以下内容的调用values.end():
begin()返回一个迭代器,引用容器中的第一个元素.end()返回一个迭代器,它是容器的过去值.如果容器是空的,那么begin() == end();
因此,values[0]在您的情况下实际上相当于:
*(values.end() + 0)
Run Code Online (Sandbox Code Playgroud)
这反过来相当于:
*(values.end())
Run Code Online (Sandbox Code Playgroud)
换句话说,您正在取消引用指向容器中最后一个元素之外的位置的迭代器.这是未定义的行为,当然也适用于values[1]和values[2].
values.clear();
Run Code Online (Sandbox Code Playgroud)
这将清除,values以便它不再包含任何元素.尝试访问任何元素将导致未定义的行为,并且std::sort将简单地对空的数字序列进行排序.
a.clear()where a是序列容器的定义是:
销毁所有元素
a.使引用元素的所有引用,指针和迭代器a无效并且可能使过去的迭代器无效.
post:a.empty()返回true