C++ 中的“!= data + arraySize”是什么意思?[关闭]

What does the "!= data + arraySize" mean in C++? [closed]

提问人:Pryhas 提问时间:11/17/2023 最后编辑:Vlad from MoscowPryhas 更新时间:11/17/2023 访问量:128

问:


想改进这个问题吗?更新问题,使其仅通过编辑这篇文章来关注一个问题。

5天前关闭。

我一直在寻找一种方法来在我的数组中找到给定的 int,我找到了这个解决方案

#include <algorithm>
#include <iostream>
using namespace std;

int main() {
  int data[] = {23, 45, 56, 12, 34, 56};
  int target = 56;

  int arraySize = sizeof(data) / sizeof(*data);

  bool isPresent = std::find(data, data + arraySize, target) != data + arraySize;

  if (isPresent) {
    cout << "The element is present";
  } else {
    cout << "The element is not present";
  }
  return 0;

现在我测试了它并且可以工作,但我想知道为什么在 find() 之后有这个 != data + arraySize? 希望得到解释

C++ 数组 算法 迭代器 指针算术

评论

2赞 463035818_is_not_an_ai 11/17/2023
你已经在这里使用它了。你知道这里是什么意思吗?std::find(data, data + arraySize, target)
3赞 Ted Lyngmo 11/17/2023
int arraySize = sizeof(data) / sizeof(*data);会更好,因为 - 然后会成为哪个是正确的类型auto arraySize = std::size(data);autostd::size_t
5赞 James Kanze 11/17/2023
@TedLyngmo 如果你要使用 ,你不妨走完整的路线,使用 和 ,然后完全摆脱。std::sizestd::beginstd::endarraySize
2赞 Ted Lyngmo 11/17/2023
@sp2danny 在某些情况下,它们可能是负数,但永远不会是负数,因此没有理由将(无论它具有的任何基础无符号类型)转换为 .这实际上可能是有害的。sizeof(anything)std::size_tint
1赞 Eljay 11/17/2023
@sp2danny • 无符号索引是为了确保,从理论上讲,一个容器可以跨越所有内存。否则,我们将任意将容器限制在内存的一半。因此,最好针对 0.00000000000001% 用例优化界面,并使 99.9999999999999% 用例尴尬。因为为不常见的用例提供特殊容器只是代码膨胀。记住瓦萨!

答:

5赞 Vlad from Moscow 11/17/2023 #1

指向数组的可访问元素的指针范围,声明为data

int data[] = {23, 45, 56, 12, 34, 56};

是。[data, data + arraySize)

如果在数组中找不到目标值,则算法会在数组的最后一个元素 .否则,该算法将返回指向数组中找到的元素的指针。data + arraySize

注意该表达式或指向数组数据的第一个元素。表达式指向数组的第二个元素。这是一个指向数组元素的表达式。datadata + 0data + 1data + ii-th

这一行将更具可读性

bool isPresent = std::find(data, data + arraySize, target) != data + arraySize;

如果像这样重写它

#include <iterator>

//...
bool isPresent = std::find( std::begin( data ), std::end( data ), target ) != std::end( data );

评论

0赞 James Kanze 11/17/2023
+1 用于替代重写。一些像我这样的老C++程序员可能会发现原版非常可读,但是早在有and之前,我(和许多其他人)就已经有了我们自己的这些函数版本,以使事情更清楚。std::beginstd::end
0赞 Aconcagua 11/17/2023
不知何故,我觉得缺乏对实际作用的解释——这可能是问题作者实际上没有理解的内容(除了仍然是一个很好的答案 -> +1)。array + number
2赞 Peter 11/17/2023 #2

由于是一个数组(不是指针),计算该数组中的元素数。dataarraySize = sizeof(data) / sizeof(*data)

data + arraySize在添加 之前转换为指针,因此结果等于 等于 which 是指向数组末尾的一端(不存在)的指针。dataarraySize&data[arraySize]intdata

这是 C++ 中的有效指针。它的特殊之处在于它不能被取消引用(取消引用会导致未定义的行为),但可以(除其他一些外)测试与 C++ 中其他指针(相同类型)的相等性。

std::find()与 C++ 标准中的许多其他标准算法一样,它接受一对表示范围的迭代器,第一个迭代器标识范围的开头,第二个迭代器表示该范围的末尾。标准库中的迭代器(或多或少)是一个通用指针。

因此,在调用中,被转换为指针(等于 ),并且(如上所述)等于(超过末尾的指针)。To ,这对参数表示它检查数组的所有元素,搜索 。std::find(data, data + arraySize, target)data&array[0]data + arraySize&data[arraySize]std::find()&data[0]&data[arraySize]datatarget

如果找到,则返回引用 的相应元素的迭代器。否则,它将返回结束迭代器(即 在您的代码中)。targetstd::find()array&data[arraySize]

总表达式为 if contains ,否则。std::find(data, data + arraySize, target) != data + arraySizetruedatatargetfalse

在现代 C++ 中(从 C++11 开始),相同的表达式可以重写为 .请记住,C++ 标准库中的迭代器是对范围末尾的引用。std::find(std::begin(data), std::end(data), target) != std::end(data)end

评论

0赞 Pryhas 11/18/2023
非常感谢,现在我完全理解了:D