С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.65/34: Рейтинг темы: голосов - 34, средняя оценка - 4.65
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
1

Как определить индекс элемента в range-based for цикле?

17.01.2017, 06:07. Показов 6483. Ответов 27
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вопрос, вот есть у меня простейший Range-based цикл
C++
1
2
int arr[3] = { 9, 7, 1 };
for (auto i: arr) std::cout << "i" << "\n";
Программа выведет на экран содержимое массива:
9
7
1

А если я хочу вывести на экран более подробную информацию:

массив[0] = 9
массив[1] = 7
массив[2] = 1

Как мне обойтись без введения дополнительной переменной-счетчика?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.01.2017, 06:07
Ответы с готовыми решениями:

Как это работает? (range-based for loop)
Объясните, пожалуйста, эту конструкцию: char buf = { 'a', 'b', 'c', 'd' }; for (auto it : buf)...

Range-based for
Почему не работает данный цикл с динамически выделенным массивом? Подозреваю, что из-за...

Range-based for
Пример кода: int my_array = {1, 2, 3, 4, 5}; for(int &amp;x : my_array) { x *= 2; } Возникли...

Range-based for
Дана конструкция вида for(auto a:some_func()). Гарантирует ли стандарт что some_func будет вызвано...

27
Модератор
Эксперт CЭксперт С++
5286 / 2373 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
17.01.2017, 06:24 2
Цитата Сообщение от MikeNew Посмотреть сообщение
Вопрос, вот есть у меня простейший Range-based цикл
C++
1
2
int arr[3] = { 9, 7, 1 };
for (auto i: arr) std::cout << "i" << "\n";
Программа выведет на экран содержимое массива:
9
7
1
MikeNew, Ваш код выведет на экран трижды букву i:
i
i
i
0
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 06:28  [ТС] 3
В первом сообщении ошибка, исправленный код:
C++
1
2
int arr[3] = { 9, 7, 1 };
for (auto i: arr) std::cout << i << "\n";
0
Модератор
Эксперт CЭксперт С++
5286 / 2373 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
17.01.2017, 07:12 4
MikeNew, вот:
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
#include <iterator>
 
int main()
{
    int arr[] = { 9, 7, 1 };
    for ( const auto & i : arr )
        std::cout << "array[" << &i - &(*std::begin(arr)) << "] =  " << i << "\n";
}
1
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 07:23  [ТС] 5
gru74ik, Громоздко и неуниверсально (не сработало со сложным пользовательским типом), но все равно спасибо.
0
Модератор
Эксперт CЭксперт С++
5286 / 2373 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
17.01.2017, 09:26 6
MikeNew, для простого сишного массива даже так можно:
C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
    int arr[] = { 15, 22, 37, 48, 50, 60, 79 };
    for ( const auto & i : arr )
        std::cout << "array[" << &i - &*arr << "] =  " << i << "\n";
}
Цитата Сообщение от MikeNew Посмотреть сообщение
не сработало со сложным пользовательским типом
Изначально об этом речи не шло. Так задачу не ставят вообще-то. С вислоухими трёххвостыми паукозмеями с Альфа-Центавра этот код тоже работать не будет. И что теперь?
И вообще, код покажите. Что значит "не сработало"? Может у Вас там банально оператор вывода не перегружен, а Вы "не сработало"...
1
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 09:50  [ТС] 7
gru74ik, ну вектор там, код из чужого примера, просто мной дополненный:

C++
1
2
3
4
5
std::vector<VkExtensionProperties> extensions(extensionCount);
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
std::cout << "\n" << "Полное число доступных расширений Вулкана: " << extensionCount << "\n\n";
for (const auto& extension : extensions) 
  std::cout << "  Доступное расширение Вулкана: " << extension.extensionName << "\n";
Добавлено через 6 минут
gru74ik, дополнение, VkExtensionProperties - просто структура:

C++
1
2
3
4
typedef struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
} VkExtensionProperties;
0
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 09:53 8
MikeNew, А в чем собственно состоит задача то?
0
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 10:03  [ТС] 9
Bretbas задача состоит в том, чтобы знать ссылку на счетчик range-based цикла без ввода дополнительной переменной счетчика.

То есть задачу можно решить, введя свою переменую-счетчик:

C++
1
2
3
4
5
6
int arr[3] = { 9, 7, 1 };
int n = 0;
for (auto i: arr) {
  std::cout << "Массив [" << n << "] =" << i << "\n";
  n++;
}
но если хочется обойтись без такой переменной сокращения кода, то хотелось бы знать как и чтобы решение было универсальным, для всех типов. Ведь есть же где-то эта переменная-счетчик которой пользуется сам цикл.
0
Модератор
Эксперт CЭксперт С++
5286 / 2373 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
17.01.2017, 10:12 10
Лучший ответ Сообщение было отмечено MikeNew как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <vector>
#include <string>
 
struct VkExtensionProperties
{
    std::string extensionName;
    size_t specVersion;
};
 
int main()
{
    const size_t extensionCount = 4;
 
    std::vector<VkExtensionProperties> extensions(extensionCount);
 
    for (auto& elem : extensions)
    {
        std::cout << "Enter extension name: ";
        std::cin >> elem.extensionName;
        std::cout << "Enter spec version: ";
        std::cin >> elem.specVersion;
        std::cout << "\n";
    }
 
    for (const auto& elem : extensions)
      std::cout << "  Available Vulcan extension: " << elem.extensionName << "\n";
 
}
Миниатюры
Как определить индекс элемента в range-based for цикле?  
1
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 10:14 11
MikeNew,
Цитата Сообщение от MikeNew Посмотреть сообщение
Ведь есть же где-то эта переменная-счетчик которой пользуется сам цикл
Нет такой. range-based циклы подобны проходу по итераторам. Тоесть код:
C++
1
for (auto i: arr)
тоже самое, что и
C++
1
for( auto it = arr.begin(); it !=arr.end(); it++ )
только единственное отличие, это то что итератор разыменованный предоставляется в range-based циклах
0
Модератор
Эксперт CЭксперт С++
5286 / 2373 / 342
Регистрация: 20.02.2013
Сообщений: 5,773
Записей в блоге: 20
17.01.2017, 10:18 12
MikeNew, всё работает:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
 
struct VkExtensionProperties
{
    std::string extensionName;
    size_t specVersion;
};
 
int main()
{
    const size_t extensionCount = 4;
 
    std::vector<VkExtensionProperties> extensions( extensionCount );
 
    for ( auto& elem : extensions )
    {
        std::cout << "Enter extension name: ";
        std::cin >> elem.extensionName;
        std::cout << "Enter spec version: ";
        std::cin >> elem.specVersion;
        std::cout << "\n";
    }
 
    for ( const auto& elem : extensions )
        std::cout
            << "Available Vulcan extension: "
            << "array["
            << &elem - &( *std::begin( extensions ) )
            << "] =  "
            << elem.extensionName
            << "\n";
 
}
Миниатюры
Как определить индекс элемента в range-based for цикле?  
1
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 10:22 13
MikeNew, видите, как товарищ gru74ik получает счетчик без лишних переменных, как Вы хотели?
C++
1
&elem - &( *std::begin( extensions ) )
За счет итераторов! Так как based-range циклы основаны на переборе итераторов, как я Вам указал выше.
1
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 10:34  [ТС] 14
gru74ik, теперь все ок, большое спасибо.
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
17.01.2017, 10:36 15
MikeNew, на сколько я понимаю, смысл range-based цикла в том и состоит, что он абстрагируется от индексов и прочих деталей реализации конкретного контейнера. Если же тебе нужны именно эти детали, то тогда надо использовать обычный цикл for, так как он лучше выражает твои намерения.
1
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 10:36 16
MikeNew, Удачи
0
8 / 8 / 0
Регистрация: 16.07.2013
Сообщений: 149
17.01.2017, 10:39  [ТС] 17
Bretbas, нет, оно, конечно, работает, но я хотел не так, похоже своя переменная-счетчик будет во всех смыслах экономней.

Добавлено через 2 минуты
likehood, а если мне одновременно нужны и счетчик, который в обычном цикле и преимущества range-base цикла? Не вижу смысла от такого абстрагирования. Одна потеря преимущества обычного цикла.
0
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 10:43 18
likehood,
Цитата Сообщение от likehood Посмотреть сообщение
то тогда надо использовать обычный цикл for
обычный цикл for вводит понятие индекса.
C++
1
for( auto i = 0; i < arr.size(); i++)
А так как автор темы не хочет вводить понятие индекса(тоесть вводить лишние переменные), то нужно знать, что у каждого контейнера имеется возможность проходить его через итераторы - специальный объект, для прохода по контейнеру. Он работает как счетчик, но имеет немного другую реализацию. Насколько мне известно итератор хранит указатель на элемент контейнера, а это все же немного другое
0
Любитель чаепитий
3744 / 1800 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
17.01.2017, 10:44 19
Цитата Сообщение от MikeNew Посмотреть сообщение
если мне одновременно нужны и счетчик, который в обычном цикле и преимущества range-base цикла?
А какие преимущества, кроме краткости, у range-based for?
0
Каждому свое
533 / 219 / 81
Регистрация: 05.08.2013
Сообщений: 1,614
17.01.2017, 10:49 20
GbaLog-,
Цитата Сообщение от GbaLog- Посмотреть сообщение
А какие преимущества, кроме краткости, у range-based for?
сразу разыменованный итератор например. Не?
0
17.01.2017, 10:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2017, 10:49
Помогаю со студенческими работами здесь

A range-based for statement
я вот чё то не понимаю - когда вызываем оператор delete для указателя на массив, он каким то...

range-based for не работает
#include &lt;iostream&gt; #include &lt;vector&gt; int main() { std::vector&lt;int&gt; v(30); for (auto z : v)...

загадки range-based
если поставить auto &amp;it - будет тоже самое - почему?// initializer_list::begin/end #include...

Непонятки с range-based for!
Доброе время суток! Запутался с range-based циклами! Вообщем код inline string...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru