Использование sizeof() для выделения памяти
Часть раздела Logic & Flow путешествия по C на Coddy — урок 33 из 63.
Хотя malloc() позволяет динамически выделять память, существует важная передовая практика, которая делает ваш код более переносимым и поддерживаемым: использование оператора sizeof() для определения количества байтов, которые необходимо выделить.
Оператор sizeof() возвращает количество байтов, необходимых для хранения определенного типа данных в вашей системе. Вместо того чтобы жестко задавать размеры в байтах, вы можете позволить sizeof() автоматически вычислить правильное значение:
// Вместо того чтобы угадывать размер в байтах:
int *ptr = (int*)malloc(4); // Предполагается, что int занимает 4 байта
// Используйте sizeof() для переносимости:
int *ptr = (int*)malloc(sizeof(int)); // Всегда правильноЭтот подход становится особенно ценным при выделении памяти под массивы. Чтобы выделить место для нескольких элементов, умножьте количество элементов на размер каждого элемента:
// Выделение памяти для 10 целых чисел
int *arr = (int*)malloc(10 * sizeof(int));
// Выделение памяти для 5 чисел типа double
double *values = (double*)malloc(5 * sizeof(double));Использование sizeof() позволяет вашему коду корректно работать на различных системах, где типы данных могут иметь разные размеры, и это четко передает ваше намерение выделить место для определенного количества элементов конкретного типа.
Задание
ЛегкоНапишите программу на языке C, которая демонстрирует правильное использование sizeof() вместе с malloc() для динамического выделения памяти. Ваша программа должна:
- Считать целое число
nот пользователя, представляющее количество элементов для выделения памяти - Использовать
malloc()сsizeof()для динамического выделения памяти под массив изnзначений типа double - Привести возвращаемый указатель типа void к указателю на double
- Считать
nзначений типа double от пользователя и сохранить их в выделенном массиве - Рассчитать общий объем выделенной памяти в байтах и вывести его в формате:
Memory allocated: [bytes] bytes - Рассчитать и вывести среднее арифметическое всех значений ровно с 2 знаками после запятой в формате:
Average: [value] - Найти и вывести наибольшее значение ровно с 2 знаками после запятой в формате:
Largest: [value]
Не забудьте включить заголовочный файл <stdlib.h> для использования malloc(). Ваша программа должна демонстрировать, как sizeof() обеспечивает корректное выделение памяти независимо от размеров типов данных в системе.
Например, если на вход подается:
3
2.5 7.8 4.1Ваш вывод должен быть следующим:
Memory allocated: 24 bytes
Average: 4.80
Largest: 7.80Эта задача подчеркивает важность использования sizeof() для того, чтобы сделать динамическое выделение памяти переносимым и удобным в поддержке, автоматически вычисляя правильное количество байтов, необходимых для любого типа данных в любой системе.
Попробуйте сами
#include <stdio.h>
#include <stdlib.h>
int main() {
// Прочитать количество элементов
int n;
scanf("%d", &n);
// TODO: Напишите свой код ниже
// 1. Выделите память для n значений типа double, используя malloc() и sizeof()
// 2. Приведите возвращенный указатель к типу double*
// 3. Прочитайте n значений типа double и сохраните их в выделенном массиве
// 4. Вычислите и выведите объем выделенной памяти в байтах
// 5. Вычислите и выведите среднее арифметическое с 2 знаками после запятой
// 6. Найдите и выведите наибольшее значение с 2 знаками после запятой
return 0;
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Logic & Flow
1Основы указателей
Что такое указатель?Объявление указателейОператор взятия адреса (&)Оператор разыменования (*)Указатели NULLИтоги: Основы указателей4Проект: Простая текстовая утилита
Обзор проектаПодсчет символов2Указатели и массивы
Имена массивов как указателиЭлементы массива — указателиАрифметика указателейСравнение указателейИтоги: Обход массива через указатели5Указатели и функции
Передача по значениюПередача указателей в функцииИзменение переменных через указателиКлассический пример: SwapПередача массивов в функцииИтоги: указатели как аргументы функций8Структуры и указатели
Указатели на структурыОператор «стрелка» (->)Передача структур по значениюПередача указателей на структурыДинамическое выделение памяти для структурИтоги: Изменение структур через указатели11Итоговые задачи на повторение
Повторение: динамическая конкатенация строкПовторение: массив структурПовторение: счетчик частоты слов3Символьные массивы и строки
Строки как массивы charНуль-терминаторВвод строк с помощью scanfИспользование strlen()Использование strcpy()Использование strcat()Использование strcmp()Итоги: основные строковые функции6Управление памятью
Стек против кучиДинамическое выделение — malloc()Использование sizeof() для выделения памятиПроверка ошибок выделения памятиОсвобождение памяти с помощью free()Выделение памяти с помощью calloc()Итоги: Динамический массив