0Pricing
C++ Academy · Урок

Границы и поддиапазоны

Безопасно извлекайте части span

«Границы и поддиапазоны» — бесплатный урок C++ Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C++ Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C++ Academy содержит 4 уроков всего.

Разбиение с помощью subspan

s.subspan(offset, count) возвращает представление части исходного диапазона без копирования — только с новым указателем и длиной.

#include <iostream>
#include <span>
int main() {
    int buf[] = {0, 1, 2, 3, 4};
    std::span<int> s(buf, 5);
    auto mid = s.subspan(1, 3);
    for (int x : mid) std::cout << x << " ";
    std::cout << "\n"; // 1 2 3
}

first и last

first(n) и last(n) возвращают представления первых или последних n элементов.

#include <iostream>
#include <span>
int main() {
    int buf[] = {10, 20, 30, 40};
    std::span<int> s(buf, 4);
    auto f = s.first(2);
    auto l = s.last(2);
    std::cout << f[0] << " " << l[1] << "\n"; // 10 40
}

Подпредставления используют общую память

Изменение подпредставления изменяет исходные данные, поскольку оба представления указывают на один и тот же буфер.

#include <iostream>
#include <span>
int main() {
    int buf[] = {1, 1, 1, 1};
    std::span<int> s(buf, 4);
    auto tail = s.last(2);
    tail[0] = 99;
    std::cout << buf[2] << "\n"; // 99
}

size_bytes

size_bytes() возвращает общий размер элементов представления в байтах; это полезно для низкоуровневого ввода-вывода.

#include <iostream>
#include <span>
int main() {
    int buf[] = {1, 2, 3};
    std::span<int> s(buf, 3);
    std::cout << s.size_bytes() << "\n"; // 3 * sizeof(int)
}

За границы отвечаете Вы

operator[] у представления span не проверяет границы. Чтение s[s.size()] является неопределённым поведением.

Проверяйте границы перед разбиением

Вызов subspan со смещением или количеством элементов, превышающими размер представления, приводит к неопределённому поведению; сначала проверьте значение с помощью size().

#include <iostream>
#include <span>
int main() {
    int buf[] = {1, 2, 3};
    std::span<int> s(buf, 3);
    size_t off = 1, cnt = 2;
    if (off + cnt <= s.size()) {
        auto sub = s.subspan(off, cnt);
        std::cout << sub.size() << "\n";
    }
}

Пустое представление после разбиения

Разбиение может дать пустое представление span, например first(0); обрабатывайте его как любой пустой диапазон.

#include <iostream>
#include <span>
int main() {
    int buf[] = {1, 2};
    std::span<int> s(buf, 2);
    auto e = s.first(0);
    std::cout << e.empty() << "\n"; // 1
}

Цепочка разбиений

Подпредставления можно разбивать дальше, поскольку каждое из них является лишь ещё одним представлением исходного буфера.

#include <iostream>
#include <span>
int main() {
    int buf[] = {0, 1, 2, 3, 4, 5};
    std::span<int> s(buf, 6);
    auto inner = s.subspan(1, 4).first(2);
    std::cout << inner[0] << " " << inner[1] << "\n"; // 1 2
}

Обработка блоками

Частое применение subspan — перебор большого буфера окнами фиксированного размера для потоковой обработки или пакетной обработки.

#include <iostream>
#include <span>
int main() {
    int buf[] = {1, 2, 3, 4, 5, 6};
    std::span<int> s(buf, 6);
    for (size_t i = 0; i < s.size(); i += 2) {
        auto chunk = s.subspan(i, 2);
        std::cout << "[" << chunk[0] << "," << chunk[1] << "] ";
    }
    std::cout << "\n";
}

Проверка статического размера

Для представления со статическим размером компилятор может проверить некоторые размеры срезов во время компиляции и обнаружить ошибки раньше.

Срок действия по-прежнему важен

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

Быстрая проверка

Проверьте, насколько хорошо Вы поняли подпредставления и границы.

Итоги

Вы изучили границы и подпредставления:

  • subspan, first и last создают срезы без выделения памяти.
  • Подпредставления используют общую память, поэтому изменения влияют на исходные данные.
  • operator[] и разбиение не проверяют границы; сначала выполняйте проверку.
  • Все подпредставления используют срок действия источника.

Часто задаваемые вопросы

Урок «Границы и поддиапазоны» бесплатный?

Да — полный текст урока «Границы и поддиапазоны» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C++ Academy, подпишись на CoddyKit PRO. Курс C++ Academy содержит 4 уроков всего.

Чему я научусь в уроке «Границы и поддиапазоны»?

Безопасно извлекайте части span Ты практикуешь C++ Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать C++ Academy?

Предыдущий опыт не требуется. C++ Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Границы и поддиапазоны»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке C++ Academy?

Да. Каждый урок C++ Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Массив фиксированного размера std::array
  2. Основы std::span
  3. Передача span в функции
  4. Границы и поддиапазоны
← Назад к C++ Academy