Что такое половина открытого диапазона и конечное значение

Что означают эти термины в С++?

1. вне значения end

2. полуоткрытый диапазон - [begin, off_the_end)

Я наткнулся на них, читая о циклах.

Ответы

Ответ 1

Полуоткрытый диапазон - это тот, который включает первый элемент, но исключает последний.

Диапазон [1,5] полуоткрыт и состоит из значений 1, 2, 3 и 4.

"off the end" или "past the end" относится к элементу сразу после окончания последовательности и является особенным в том, что итераторам разрешено указывать на него (но вы можете не смотреть на фактическое значение, потому что его не существует)

Например, в следующем коде:

char arr[] = {'a', 'b', 'c', 'd'};

char* first = arr
char* last = arr + 4;

first теперь указывает на первый элемент массива, а last указывает один за концом массива. Нам разрешено указывать один конец конца массива (но не два), но нам не разрешено пытаться получить доступ к элементу в этой позиции:

// legal, because first points to a member of the array
char firstChar = *first;
// illegal because last points *past* the end of the array
char lastChar = *last;

Наши два указателя first и last вместе определяют диапазон всех элементов между ними.

Если это полуоткрытый диапазон, то он содержит элемент, на который указывает first, и все элементы между ними, но не элемент, на который указывает last (что хорошо, потому что он не фактически указывают на действительный элемент)

В С++ все стандартные библиотечные алгоритмы работают на таких полуоткрытых диапазонах. Например, если я хочу скопировать весь массив в другое место dest, я делаю это:

std::copy(first, last, dest)

Простой для цикла обычно следует аналогичному шаблону:

for (int i = 0; i < 4; ++i) {
    // do something with arr[i]
}

Этот цикл идет от 0 до 4, но исключает конечное значение, поэтому диапазон охватываемых индексов полуоткрыт, в частности [0, 4)

Ответ 2

Это не С++ конкретные термины, они являются общими условиями математики.

[] и() означает, включен ли диапазон/исключая конечную точку:

  • [включает конечную точку
  • (исключает конечную точку
  • [] = 'Закрыто', включает обе конечные точки
  • () = 'Открыть', исключает обе конечные точки
  • [) и (] являются "полуоткрытыми" и включают только одну конечную точку

Большинство С++ for-loops охватывают половину открытого диапазона (вы включаете первый элемент: например, for int i=0;, но исключаете конечный элемент: i < foo, not i ≤ foo)

Ответ 3

Как поясняется в других ответах, полуоткрытый диапазон также является математическим термином и использованием этого термина в контексте программирования, подразумевается, что начальная точка включена и конечная точка исключена.

Что это означает в контексте программирования на C/С++? Скажем, вы собираетесь печатать элементы целочисленного массива. Говоря о языке C, потому что у вас нет каких-либо знаний во время выполнения для размера массива, у вас есть два выбора. Либо вы должны указать размер массива, и, таким образом, подпись функции будет следующей:

void printArray(int * array, int size);

или вы должны использовать полуоткрытый диапазон, что означает, что вы должны указать как начальный, так и конечный указатель (и функция будет обрабатывать, включая начало, исключая конец), дополнительно к самого массива. И подпись будет следующей:

void printArray(int * array, int * begin, int * end);

Чтобы проиллюстрировать, вот пример обеспечения размера массива:

#include <stdio.h>

void printArray(int * array, int size)
{
    printf("Array: ");

    for(int i = 0; i < size; i++)
        printf("%2d ", array[i]);

    printf("\n");
}

int main()
{
    int array[5] = { 1, 2, 3, 4, 5 };

    printArray(array, 5);

    return 0;
}

В приведенном выше примере мы передали два параметра функции printArray, поскольку это очевидно в сигнатуре функции, указатель на первый элемент массива (или сам массив) и размер массива.

Однако, как я уже писал выше, мы также можем использовать диапазон полуоткрытия в сигнатуре функции, который можно увидеть ниже:

#include <stdio.h>

void printArray(int * array, int * begin, int * end)
{
    printf("Array: ");

    for(int * index = begin; index != end; index++)
        printf("%2d ", *index);

    printf("\n");
}

int main()
{
    int array[5] = { 1, 2, 3, 4, 5 };

    printArray(array, array, array+5);

    return 0;
}

Оба кода выдадут тот же результат, что и ниже:

Array:  1  2  3  4  5

Как вы можете видеть, функция printArray печатает функцию для диапазона [begin, end). index, который на самом деле является указателем на элементы целочисленного массива, начинается с begin и включает в себя begin, а for-loop заканчивается, когда index равен указателю end исключая обработку end. Это я назвал полуоткрытым диапазоном.

Полуоткрытый диапазон - это соглашение С++.