23.09.2017, 17:34 [+3 UTC]
в нашей команде: 2 128 чел. | участники онлайн: 5 (рекорд: 21)

:: РЕГИСТРАЦИЯ

:: консультации

:: задать вопрос

:: все разделы

:: правила

:: новости

:: участники

:: доска почёта

:: форум

:: блоги

:: поиск

:: статистика

:: наш журнал

:: наши встречи

:: наша галерея

:: отзывы о нас

:: поддержка

:: руководство

Версия системы:
7.41 (25.02.2017)

Общие новости:
23.02.2017, 09:51

Форум:
23.09.2017, 13:24

Последний вопрос:
23.09.2017, 14:31

Последний ответ:
23.09.2017, 08:43

Последняя рассылка:
23.09.2017, 13:45

Писем в очереди:
0

Мы в соцсетях:

Наша кнопка:

RFpro.ru - здесь вам помогут!

Отзывы о нас:
05.02.2010, 02:13 »
Дёмин Илья Юрьевич
Спасииибо, ты мне оч помог!!! [вопрос № 176439, ответ № 259147]
17.04.2010, 20:31 »
Anjali
Спасибо за подробный ответ! [вопрос № 177902, ответ № 260880]
27.04.2016, 23:16 »
Посетитель - 399158
Спасибо большое. Все понятно объяснили [вопрос № 189213, ответ № 273732]

РАЗДЕЛ • С / С++

Создание программ на языках C и C++.

[администратор рассылки: Андрей Кузнецов aka Dr_Andrew (Старший модератор)]

Лучшие эксперты в этом разделе

Лысков Игорь Витальевич
Статус: Старший модератор
Рейтинг: 238
solowey
Статус: 6-й класс
Рейтинг: 81
Хватов Сергей
Статус: Академик
Рейтинг: 70

Перейти к консультации №:
 

Консультация онлайн # 191233
Раздел: • С / С++
Автор вопроса: pNod (1-й класс)
Отправлена: 20.07.2017, 15:47
Поступило ответов: 1

Уважаемые эксперты! Пожалуйста, ответьте на вопрос: почему не будет работать цикл для диапазона внутри приведенной ниже функции для обработки массива неизвестного размера вместо того, что там сейчас?

//функция displayArray - отображает элементы массива
//integerArray длиной sizeOfloatArray
void displayArray (int integerArray[], int sizeOfloatArray)
{
for (int i = 0; i < sizeOfloatArray; i++)
{
cout << i << ": " << integerArray [i] << endl;
}
}


Ведь размер массива будет передан в функцию...

Состояние: Консультация закрыта

Здравствуйте, pNod!

С помощью дополнительных вопросов выяснилось, что вас интересует цикл, перебирающий коллекцию:

for(auto &element: collection) {...}

На самом деле это всего лишь syntax sugar (русского термина не знаю) для классического перебора:
for auto (pointer = collection->begin();pointer!=collection->end();pointer++){auto &element = *pointer;...}

Есть особый случай: такой цикл можно применять для массивов, но только если их размер известен компилятору. Можно даже в inline функции использовать (хотя это уже трюкачество). Вот пример с кое-какими комментариями:
#include <iostream>

// SZ в функции не встречается, но он всё равно необходим!
template<typename T, size_t SZ>
void pr_arr(const T (&a)[SZ]) {
    for (const T &p: a)
        std::cout << p << ::std::endl;
}
int main () {
    static const int ia[] = {1,6,7,2,8,5,9};
    static const double fa[] = {.1,.6,.7,.2,.8,.5,.9};
    pr_arr("Hello, world!");
    pr_arr(ia);
    pr_arr(fa);

    int n=10; // const int n=10 исправит проблему, но это, вероятно, уже оптимизация так работает  smile  
    int a[n]; // такое уже допустимо
    for (auto &b: a) b = 3;
    //pr_arr(a); // а это не пройдёт компиляцию: размер массива компилятору неизвестен

    return 0;
}



Консультировал: Хватов Сергей (Академик)
Дата отправки: 21.07.2017, 15:17

5
нет комментария
-----
Дата оценки: 25.07.2017, 11:23

Рейтинг ответа:

0

[подробно]

Сообщение
модераторам

Отправлять сообщения
модераторам могут
только участники портала.
ВОЙТИ НА ПОРТАЛ »
регистрация »

Мини-форум консультации № 191233

solowey
6-й класс

ID: 400484

# 1

= общий = | 20.07.2017, 16:14 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Добрый день,
я вижу только 2 проблемы: 1 - массив окажется не int, 2 - размер может оказаться больше длины массива.

Вот этот пример работает нормально.

#include <iostream>

using namespace std;

void displayArray(int integerArray[], int sizeOfloatArray)
{
	for (int i = 0; i < sizeOfloatArray; i++)
	{
		cout << i << ": " << integerArray[i] << endl;
	}
}

int main()
{
	int integerArray[3] = { 1, 3, 2 };

	displayArray(integerArray, 3);

    return 0;
}


А вообще, можно поподробнее о проблеме...

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 2

= общий = | 20.07.2017, 16:14 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Непонятен вопрос. Приведенный код вполне работает. Что именно не работает?

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

• Отредактировал: Лысков Игорь Витальевич (Старший модератор)
• Дата редактирования: 20.07.2017, 16:15

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 3

= общий = | 20.07.2017, 16:23 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
solowey:

© Цитата:
1 - массив окажется не int
Невозможно по определению, компилятор заверещит... smile
Вот случай с несоответствием размера, да, может дать не совсем тот результат, который ожидаем...

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 4

= общий = | 20.07.2017, 16:39 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Странное имечко sizeOfloatArray выбрано smile
Тогда уж лучше sizeOfArray
Надо стараться использовать имена, которые говорят о своем содержимом.

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 5

= общий = | 20.07.2017, 16:58 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Лысков Игорь Витальевич
Странное имечко sizeOfloatArray выбрано

Действительно странно, тем более в программе, откуда кусок я выдернула используются одни int-ы, это из книги Стефана Р.Дэвиса "С++ для чайников" smile
Сейчас напишу поподробнее.
Тема "Циклы для диапазонов".

pNod
1-й класс

ID: 401172

# 6

= общий = | 20.07.2017, 17:10 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Речь идет о новинке C++ '11 (сейчас уже не новинка, конечно).
Написано, что в ряде случаев можно обратится к элементам массива с помощью цикла for для диапазонов, и приведен пример, в котором цикл инициализирует все элементы массива nArray значением 0:

int nArray[128];
for (int& n: nArray)
{
     n=0;
}

Все прекрасно (хотя верим на слово, т.к. мой компилятор о такой новинке не в курсе, судя по сразу выданной ошибке), но далее написано, что этот цикл можно использовать только тогда, когда С++ знает размер массива во время построения программы. Таким образом, например в функции displayArray (копирую ниже), цикл работать не будет.
//функция displayArray - отображает элементы массива
//integerArray длиной sizeOfloatArray
void displayArray (int integerArray[], int sizeOfloatArray)
{
for (int i = 0; i < sizeOfloatArray; i++)
{
     cout << i << ": " << integerArray [i] << endl;
}
}

Вот и думаю - почему? Ведь размер будет известен... smile

solowey
6-й класс

ID: 400484

# 7

= общий = | 20.07.2017, 17:20 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: pNod
Все прекрасно (хотя верим на слово, т.к. мой компилятор о такой новинке не в курсе, судя по сразу выданной ошибке), но далее написано, что этот цикл можно использовать только тогда, когда С++ знает размер массива во время построения программы. Таким образом, например в функции displayArray (копирую ниже), цикл работать не будет.
Код :: выделить код
//функция displayArray - отображает элементы массива
//integerArray длиной sizeOfloatArray
void displayArray (int integerArray[], int sizeOfloatArray)
{
for (int i = 0; i < sizeOfloatArray; i++)
{
cout << i << ": " << integerArray [i] << endl;
}


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

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 8

= общий = | 20.07.2017, 17:29 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Хм, о циклах для диапазонов не слышал. Сам сижу на старом компиляторе. Разберемся.

Теперь по сути вопроса.
В первом случае, все верно, размер массива известен во время компиляции.
Во втором же параметром передается не массив, как таковой, а указатель на начало массива.
Размер его, действительно, неизвестен.
Второй параметр для компилятора - простое целое, никак не связанное с массивом.
Неважно, что мы интерпретируем его, как размер массива...

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 9

= общий = | 20.07.2017, 17:37 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: solowey
Возможно, не будет работать, если передаваемый массив будет динамически формироваться. Т.е. длина массива будет изменяться во время работы программы...


Так вроде параметрами для этого и пользуются, а не конкретным, выраженным числом размером массива...
Допустим сменилось количество, но в функцию то оно при обращении к ней снова передаваться будет, и на экран выведутся уже новые данные...
Может об этом не надо задумываться, а просто принять как данность smile ?

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 10

= общий = | 20.07.2017, 17:40 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

У меня есть несколько версий MSC++. Самая новая - MS C++10.0

Не подскажете, где в ней включить поддержку C++11
Или в этой версии этого еще нет?

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 11

= общий = | 20.07.2017, 17:43 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Лысков Игорь Витальевич
Второй параметр для компилятора - простое целое, никак не связанное с массивом.
Неважно, что мы интерпретируем его, как размер массива...


Да, это так...
Получается, что в цикле для диапазонов мы можем указать только имя массива, которое является его же адресом, а второй параметр эта новинка просто не содержит?


pNod
1-й класс

ID: 401172

# 12

= общий = | 20.07.2017, 17:50 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Лысков Игорь Витальевич
У меня есть несколько версий MSC++. Самая новая - MS C++10.0


У меня Dev-C++ 4.9.9.2, поставленная по совету автора этой книги специально для ее изучения, и все примеры из книги по идее должны в ней работать smile .
Про MS не подскажу, еще не сталкивалась.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 13

= общий = | 20.07.2017, 18:18 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

© Цитата:
Получается, что в цикле для диапазонов мы можем указать только имя массива, которое является его же адресом, а второй параметр эта новинка просто не содержит?
Если размер задан во время компиляции, то компилятор знает его размер и формирует цикл до указанного значения.
В случае же динамического массива, а задание указателя - фактически и есть динамический массив, его размер в момент компиляции неизвестен, поэтому цикл для диапазонов здесь не работает.

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 14

= общий = | 20.07.2017, 18:35 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Игорь Витальевич, может задам очень простой вопрос, но я меня, похоже, сформировались неправильные понятия о сборке программы.
Я считала, что компилятор собирает построчно сверху-вниз с выполнением запрашиваемых в теле main функций...ну и с подключением библиотек.
Например, если мы делаем динамический массив, компилируется и выполняется до места определения массива, далее пользователь вводит этот массив, например, с клавиатуры, затем компилируется дальше (при уже известных данных), не так?

Хватов Сергей
Академик

ID: 20764

# 15

= общий = | 20.07.2017, 18:41 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Вас, часом, не про такое спросили?

#include <iostream>

template<typename T, size_t SZ>
void pr_arr(const T (&a)[SZ]) {
    for (size_t i = 0; i < SZ; i++)
        std::cout << a[i] << ::std::endl;
}

int main () {
    int ia[] = {1,6,7,2,8,5,9};
    double fa[] = {.1,.6,.7,.2,.8,.5,.9};

    pr_arr(ia);
    pr_arr(fa);
    return 0;
}

pNod
1-й класс

ID: 401172

# 16

= общий = | 20.07.2017, 19:06 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Хватов Сергей
Вас, часом, не про такое спросили?

Меня не спросили, я книгу пытаюсь осилить по С++ smile

Я заинтересовалась возможностью посимвольного вывода с помощью for для диапазонов, вместо обычного, в котором надо делать
© Цитата: Хватов Сергей
i = 0; i < SZ; i++
в динамических массивах.
Но уже понимаю, что дело в самой форме нововведения, которая просто этого не предусматривает, а существует как инструмент для инициализированных массивов.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 17

= общий = | 20.07.2017, 19:17 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

© Цитата:
не так?
Конечно, не так. Программный код формируется сразу из текста программы.
Получаем файл программы EXE. Запускаем. Ну или среда запускает...

Что-то известно сразу во время компиляции, типа констант. А под что-то только резервируется место, типа адреса динамического массива.
Сам массив, адреса его элементов станут известны только во время выполнения.
Динамический массив - он потому динамический, что строится по ходу дела.
Ну и если в подпрограмму передается адрес массива, то этот адрес фактически является адресом динамического массива.

Так, как Вы описали, работают интерпретаторы. Это в них происходит работа построчно. Читается строка текста, выполняется и т.д.

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 18

= общий = | 20.07.2017, 19:29 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Хватов Сергей:

Сергей, может Вы знаете ответ на мой вопрос выше в посту №10
Давно хотел приобщиться к С++11, да все как-то особой нужды не было.
А тут вот заинтересовался.

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

pNod
1-й класс

ID: 401172

# 19

= общий = | 20.07.2017, 19:37 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Ок, тогда посмотрите, пожалуйста, все ли правильно понимаю порядок smile :
1) сразу при сохранении кода - исходный текст программы - файл с расширением .cpp
2) компиляция - перевод в машинный код исходного текста .obj
3) выполнение - создаем исполняемый файл .exe - получается здесь уже собираются модули, подключаются библиотеки и формируются динамические массивы?

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 20

 +1 
 
= общий = | 20.07.2017, 19:42 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Чуток поправлю smile
1) сразу при сохранении кода - исходный текст программы - файл с расширением .cpp - да!
2) компиляция - перевод в машинный код исходного текста .obj - да!
добавим линковку
3) линковка - создаем исполняемый файл .exe - собираются модули, подключаются библиотеки. Получаем .exe
исправляем
4) выполнение - запускаем исполняемый файл .exe - работает программа, в ходе выполнения, если надо, формируются динамические массивы

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

• Отредактировал: Лысков Игорь Витальевич (Старший модератор)
• Дата редактирования: 20.07.2017, 19:43

pNod
1-й класс

ID: 401172

# 21

= общий = | 20.07.2017, 19:49 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

Спасибо smile

Хватов Сергей
Академик

ID: 20764

# 22

 +1 
 
= общий = | 21.07.2017, 12:03 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

Не знаю: у меня Linux, а в нём gcc, который уже и C++14 поддерживает.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 23

= общий = | 21.07.2017, 12:13 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Хватов Сергей:

Точно, я и забыл...

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Хватов Сергей
Академик

ID: 20764

# 24

 +1 
 
= общий = | 21.07.2017, 12:30 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Вот это работать будет, более простые варианты - нет:

template<typename T, size_t SZ>
void pr_arr(const T (&a)[SZ]) {
    for (const T &p: a)
        std::cout << p << ::std::endl;
}
причём SZ здесь обязателен, хотя он вроде бы не используется. Естественно, настоящий указатель в такую функцию передавать нельзя, о чём сразу же заявит компилятор.

Вообще, for (TYPE value: pointer) - это всего лишь syntax sugar для перебора коллекции с помощью методов begin(), ++ и end()
Ну, и особый, но ограниченный случай для перебора элементов массива

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 25

= общий = | 21.07.2017, 14:19 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Хватов Сергей:

Мне кажется, это можно и в ответ записать...

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Хватов Сергей
Академик

ID: 20764

# 26

= общий = | 21.07.2017, 14:39 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

только я так и не понял, чего хотела автор вопроса. Тем более, что формальный ответ очень короткий: "Этот код работать будет" :)

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 27

= общий = | 21.07.2017, 14:46 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Хватов Сергей:

Она хотела понять, почему не будет работать код в вопросе, если попытаться заменить его на цикл для диапазонов, если в функцию передается указатель на массив и отдельно длина массива.
Вроде разобрались (пост №16). Но ответ надо дать. Тем более, Ваш пример достаточно интересен.

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Вадим Исаев ака sir Henry
Старший модератор

ID: 425

# 28

= общий = | 29.07.2017, 04:54 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Dev-C++ 4.9.9.2 - это старина несусветная, где в комплекте используется GCC (набор компиляторов C\C++) производства 2004 года. Так что, сами понимаете, никакго С++11 там нет.
Другое дело, если Вы ставите DevC++ без компилятора, тогда компилятор нужно ставить отдельно (например MinGW) и в этом случае, если ставить последнюю версию компилятора, он будет поддерживать C++11.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

Вадим Исаев ака sir Henry
Старший модератор

ID: 425

# 29

= общий = | 29.07.2017, 05:01 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Лысков Игорь Витальевич:

© Цитата: Лысков Игорь Витальевич
У меня есть несколько версий MSC++. Самая новая - MS C++10.0

Не подскажете, где в ней включить поддержку C++11

Скорее всего нигде, т.к. даже MSC++10-SP1 датирована мартом 2011 года. smile А вот в MSC++12 высока вероятность, что сие работает по умолчанию. А уж в MSC++14... smile

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

pNod
1-й класс

ID: 401172

# 30

= общий = | 29.07.2017, 14:48 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер

© Цитата: Вадим Исаев ака sir Henry
Dev-C++ 4.9.9.2 - это старина несусветная

Да, я поняла уже. smile
Я поставила эту версию по рекомендации автора книги по С++, которую планирую осилить до конца.
Якобы все примеры разбирались в этой в версии и работают.
Затем буду искать среду или отдельно компилятор с поддержкой последних нововведений.

Лысков Игорь Витальевич
Старший модератор

ID: 7438

# 31

= общий = | 31.07.2017, 11:06 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
Вадим Исаев ака sir Henry:

© Цитата:
Скорее всего нигде
Я уже и сам понял. smile

=====
Каждый выбирает по себе -
Щит и латы, посох и заплаты.
Меру окончательной расплаты
Каждый выбирает для себя.

Вадим Исаев ака sir Henry
Старший модератор

ID: 425

# 32

= общий = | 31.07.2017, 18:54 | цитировать цитировать  | профиль профиль  |  отправить письмо в личную почту пейджер
pNod:

Одно из двух: либо Вы не поняли автора (возможно он имел в виду только установку IDE), либо автора не понял переводчик. smile
К сожалению на сегодняшний день качество переводов плохое. Если раньше на каждого автора (и переводчика в том числе) приходилось по 5..7 редакторов\корректоров, то сегодня на одного редактора по 200...300 авторов. smile Главная задача издательств не обеспечить страждущих информацией, а побыстрей закинуть макулатуру в продажу.

=====
Я только в одном глубоко убеждён - не надо иметь убеждений! :)

• Отредактировал: Вадим Исаев ака sir Henry (Старший модератор)
• Дата редактирования: 31.07.2017, 18:55

 

Возможность оставлять сообщения в мини-форумах консультаций доступна только после входа в систему.
Воспользуйтесь кнопкой входа вверху страницы, если Вы зарегистрированы или пройдите простую процедуру регистрации на Портале.

Яндекс Rambler's Top100

главная страница | поддержка | задать вопрос

Время генерирования страницы: 0.16657 сек.

© 2001-2017, Портал RFPRO.RU, Россия
Авторское право: ООО "Мастер-Эксперт Про"
Калашников О.А.  |  Гладенюк А.Г.
Версия системы: 7.41 от 25.02.2017
Бесплатные консультации онлайн