Search code examples
c++arraysalgorithmiteratorpointer-arithmetic

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


I was looking for a way to find a given int in my array and i found this solution

#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;

now i tested and it works but im wondering why there is this != data + arraySize after the find()? Would appreciate an explanation


Solution

  • Since data is an array (not a pointer) arraySize = sizeof(data) / sizeof(*data) calculates the number of elements in that array.

    data + arraySize converts data to a pointer before adding arraySize, so the result is equal to &data[arraySize] which is a pointer to a (non-existent) int that is one-past-the-end of the array data.

    That is a valid pointer in C++. It is special in that it cannot be dereferenced (dereferencing causes undefined behaviour) but can (among some other things) be tested for equality to other pointers (of the same type) in C++.

    std::find(), like a lot of other standard algorithms in the C++ standard, accepts a pair of iterators representing a range, the first identifying the beginning of the range and the second iterator representing one-past-the-end of that range. An iterator in the standard library is (more or less) a generalised pointer.

    So, in the call std::find(data, data + arraySize, target), data is converted to a pointer (equal to &array[0]) and data + arraySize (as I described above) is equal to &data[arraySize] (a pointer past the end). To std::find(), the pair of arguments &data[0] and &data[arraySize] means it examines all elements of the array data searching for target.

    If target is found, std::find() returns an iterator that refers to the corresponding element of array. Otherwise it returns the end iterator (i.e. &data[arraySize] in your code).

    The overall expression std::find(data, data + arraySize, target) != data + arraySize is then true if data contains target, and false otherwise.

    In modern C++ (since C++11) the same expression may be rewritten as std::find(std::begin(data), std::end(data), target) != std::end(data). Bear in mind that end iterators in the C++ standard library are references to one-past-the-end of the range.