0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
||||||
1 | ||||||
Возврат функцией массива структур27.05.2014, 17:39. Показов 3350. Ответов 23
Метки нет (Все метки)
Пишу программу, которая в зависимости от выбора пользователя считывает информацию о студентах, вводимую с клавиатуры, либо использует заранее подготовленный массив. После этого сортирует массив и выводит таблицу в виде упорядоченного по группам и алфавиту списка. Проблема с использованием массива-заготовки. Как правильно передать его в функцию? И еще вопрос: вот у меня есть структура students, у нее поля name, group и др. Можно ли получить размер определенного поля структуры, не используя непосредственно переменных с этим структурным типом (т.е., я знаю, что, если student1 - переменная структурного типа students, можно написать "sizeof (student1.name)", а можно ли еще как-то)?
Кликните здесь для просмотра всего текста
0
|
27.05.2014, 17:39 | |
Ответы с готовыми решениями:
23
Возвращение функцией значения динамического массива структур Сортировка элементов массива структур шаблонной функцией Возврат объекта функцией Возврат функцией указателя на функцию |
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
27.05.2014, 18:20 [ТС] | 3 |
Например, чтобы задать ширину поля вывода для setw.
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
|
27.05.2014, 18:57 | 4 |
Чтобы правильно передать массив структур нужно в сигнатуре функции указать следующие аргументы:
(students * pStud, int n) - если нам понадобиться изменять данные массива структур и этот массив создан динамически, или (const students * pStud, int n) - если нам не понадобиться изменять данные массива структур и этот массив создан динамически. Чтобы узнать размер полей структуры можно ещё применить следующее: 1) name - sizeof(char) * name_size; 2) group - sizeof(char) * n; 3) age - sizeof(int); 4) average - sizeof(float); 5) scholarship - sizeof(float).
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
|
27.05.2014, 20:56 | 6 |
Kuzia domovenok, если уж на то пошло, то нужно прописать как strlen(stud.name), где нужно сделать предварительное объявление и инициализацию student stud;
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
28.05.2014, 08:58 [ТС] | 7 |
Kuzia domovenok, вы мой код смотрели? Мне нужно вывести таблицу, и я хочу, чтобы под вывод имени отводилось столько знаков, сколько отведено под это поле в структуре.
Добавлено через 31 минуту montkay, я правильно понимаю, что pStud - это указатель на массив структур, а n - количество его элементов? А нельзя создать массив и инициализировать его внутри функции, которая не принимает никаких параметров, возвращает только указатель на него, а потом присвоить значение этого указателя другому указателю в главной функции (как это я сделал)? Добавлено через 13 минут montkay, и еще по поводу размера поля. Конструкция "name - sizeof(char) * name_size;", насколько понимаю, возможна только потому, что я задал размер массива константой. А если он был задан просто числом (например, char name[30])?
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
|
28.05.2014, 10:17 | 8 |
Сообщение было отмечено Exzotick как решение
Решение
Exzotick, начну с последнего вашего вопроса. Чтобы узнать размер поля структуры нужно узнать размер типа данных это поля. Но если поле структуры представлено в виде массива, то нужно, помимо размера типа данных, указать также количество элементов массива. По этому чтобы узнать размер поля структуры char name[30] нужно sizeof(char) * 30.
Да, вы правильно поняли - pStud - это указатель на массив структур, а n - количество его элементов. Если создать массив структур внутри функции, то этот массив по завершению функции будет уничтожен (если этот массив будет создан на стеке, а если нет - то без очистки динамической памяти будет засорятся оперативка). И для того, чтобы сохранить массив в программе, нужно в функцию передавать значение по ссылке или по указателю. Количество элементов есть обязательным (если используется динамический массив, а это как раз ваш случай). Передавать в главную функцию указатель как это сделали вы - недопустимо, потому что указатель должен указывать на существующий объект. Сейчас объясню. Вот вы создаете и инициализируете в функции массив, а по завершению функции он умирает. Тогда на что будет указывать возвращаемое значение? Фактически это может быть всё, что угодно, но вряд ли нужное вам значение. Чтобы функция возвращала указатель, нужно чтобы она принимала указатель, обрабатывала его каким-то образом, а потом возвращала его. Тогда проблем не будет, ведь возвращаемое значение - существует вне функции, которую вызываете вы, а следовательно - после завершения функции объект будет живым =) И не забывайте использовать количество элементов обязательно, чтобы всегда знать, какой кусок памяти нужно обработать. Ведь если не знать размера этого куска памяти, то программа вплоть до аварийного завершения будет его обрабатывать.
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
28.05.2014, 13:20 [ТС] | 9 |
Не могли бы вы все-таки описать функцию и как ее вызывать. А то у меня никак не получается это правильно сделать.
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
|
28.05.2014, 15:34 | 10 |
Exzotick, хорошо. Только скажите какую именно функцию и что она должна делать.
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
28.05.2014, 16:22 [ТС] | 11 |
В функции main предоставляется выбор: заполнить массив вручную или использовать заготовку. Вот во втором случае массивом students_arr должен стать массив default_students_arr, который задан в функции use_arr.
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
||||||
28.05.2014, 18:24 | 12 | |||||
Приблизительно так может выглядеть функция. Но если вы захотите записать больше 8 человек в массив, то всем, кроме первых восьми, будет присвоено значение {"Nobody", "None", 0, 0.0, 0}.
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
28.05.2014, 18:34 [ТС] | 13 |
montkay, А почему эта функция не возвращает указатель? И еще, можно ли сделать так, чтобы первые восемь были записаны заранее, а остальные вводились с клавиатуры и добавлялись в массив?
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
||||||
28.05.2014, 19:50 | 14 | |||||
Эта функция не возвращает указатель, потому что суть её существования заключается в заполнении массива, который начинается по адресу "students * pStud", что указано в сигнатуре функции. Для чего нужно возвращать указатель? С помощью функции вы обрабатываете кусок памяти (для чего в сигнатуре нужно указывать начало массива и количество элементов). Если честно, то задам вам встречный вопрос, если вы не против - почему у вас многие функции возвращают значение? Не легче ли заполнить массив структур, а потом просто в нужный момент обращаться к членам массива и указывать их значение?
Да, можно вводить после восьмого студента вручную данные:
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
29.05.2014, 05:52 [ТС] | 16 |
montkay, просто преподаватель так сказала. А вот фразу "заполнить массив структур, а потом просто в нужный момент обращаться к членам массива и указывать их значение" я не совсем понял. Можно примерчик?
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
|
29.05.2014, 14:41 | 17 |
Exzotick, видно или преподаватель что-то другое имела ввиду, или она сама не понимает, для чего такое возвращающее значение. Тогда название функции будет таким: students * use_arr(students * pStud, int n), а возвращать функция будет return pStud;
Это самое адекватное, что могу предложить. Но это бессмысленно =( По поводу вашего вопроса. В программе вы можете вызвать средний бал, к примеру, не через функцию, которая его возвращает, а следующим образом: students_arr[i].average; Также можно любой член элементов массива структур вызвать таким образом (имя, группу, оценки и т.д.).
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
||||||
29.05.2014, 15:44 [ТС] | 18 | |||||
montkay, почему-то у меня выдает ошибку "Необработанное исключение по адресу".
0
|
12 / 12 / 12
Регистрация: 19.02.2014
Сообщений: 72
|
||||||
29.05.2014, 20:01 | 19 | |||||
Случай case '2' я подкорректировал немножко, также как ещё пару функций. Честно, потенциальных ошибок у вас очень много, по этому точно сказать причину возникновения сообщения "Необработанное исключение по адресу" не смогу сказать. Но вторая функция в switch (choice) у меня нормально работает.
0
|
0 / 0 / 0
Регистрация: 25.05.2014
Сообщений: 25
|
|
31.05.2014, 15:03 [ТС] | 20 |
Есть еще одна проблема. Функции для заполнения имени приходится возвращать всю структуру, потому что если ее описать как char* fill_name (students), то выдает ошибку. Можно ли сделать, чтобы она возвращала только одно поле структуры (stu-data.name)?
Добавлено через 1 час 50 минут montkay, я тут маленько поиздевался над вашим кодом и понял, что ошибка возникает, если в case 2 не делать динамического выделения памяти. Почему это необходимо, если в функции use_arr мы создаем статический массив, и присваиваем его pStud?
0
|
31.05.2014, 15:03 | |
31.05.2014, 15:03 | |
Помогаю со студенческими работами здесь
20
Возврат функцией экземпляра класса Можно ли присвоить одному массиву структур значение другого массива структур и записать его в файл Как сделать возврат функцией (или процедурой) массива Возврат значения функцией Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |