Как посчитать память массива c
Как показала практика, у начинающих кодеров возникает множество вопросов при решении задач по теме «Массивы». В данной статье затронуты вопросы, относящиеся только к массивам в классическом понимании. Работа с контейнерами STL — это отдельная тема.
Как правило, задачи сводятся к следующему: заполнить массив, произвести некие операции с элементами массива, распечатать результат. Уже в постановке задачи угадываются логические блоки её решения. Далее я постараюсь показать типовые «кирпичики», из которых можно сложить решение задачи — т. е. программу.
Организация массива
Память под массив может выделяться автоматически или динамически.
Автоматическое выделение памяти используют, когда размер массива известен на этапе компиляции (т. е. при написании кода).
Динамическое выделение памяти используют, когда размер массива неизвестен на этапе компиляции (допустим, запрашивается у пользователя).
Оба типа массивов могут быть как глобальными (определёнными вне функций), так и локальными (определёнными внутри функции или блока). Здесь для автоматических массивов существует одна тонкость. Память для локального автоматического массива выделяется в стеке. Поэтому размер такого массива должен быть небольшим. В противном случае можно получить переполнение стека и, как следствие, аварийное завершение программы. Переполнение стека также можно получить и при небольших размерах локального автоматического массива, при многократных рекурсивных вызовах функции. Поэтому, когда вы определяете в функции автоматический массив, вы должны точно знать, что делаете.
Глобальные автоматические массивы в плане переполнения стека безопасны. Но они будут видны во всём коде, лексикографически расположенному после объявления массивов, что может спровоцировать их использование напрямую, минуя их передачу в функции через параметры. Это приведёт к возникновению побочных эффектов работы функций, что затрудняет отладку и делает программы менее надёжными. Такого использования глобальных массивов следует избегать.
Для массивов, использующих динамическое выделение памяти, память распределяется из «кучи» (heap). Куча — это память, выделяемая программе операционной системой, для использования этой программой. Размер кучи, как правило, значительно больше размера стека, а для ОС, поддерживающих парадигму виртуальной памяти, размер кучи теоретически может ограничиваться только разрядностью приложения.
Использование автоматических массивов
Автоматические массивы используют, когда размер массива известен на этапе компиляции.
Размер массива в коде настоятельно рекомендуется указывать с помощью именованной константы. Это полезно по нескольким соображениям:
- имя константы должно указывать на область её применения — самодокументирование кода;
- при необходимости изменить в коде размер массива потребуется внести правку только в одном месте;
- размер массива, как правило, используется в циклах прохода по массиву, проверки границы и пр., поэтому использование символического имени избавит от необходимости тщательной проверки и правки всего кода при изменении размера массива.
Тип константного выражения для определения размера (количество элементов) автоматического массива должен быть целочисленный: char , int , unsigned int , long , etc.
Память, отведённая под автоматические массивы, освобождается при выходе из области видимости переменной-массива. Для локальных массивов это функция или блок. Глобальные массивы уничтожаются при выходе из программы.
Пример определения глобального автоматического массива длиной 10 элементов типа int :
Пример определения локального автоматического массива длиной 10 элементов типа int :
Использование массивов с динамическим выделением памяти
Массивы с динамическим выделением памяти используют, когда размер массива не известен на этапе компиляции. Реальный размер массива может вычисляться в программе или вводиться пользователем — неважно.
Память для массива выделяется оператором new в форме new тип[количество_элементов] .
Тип выражения, определяющего размер (количество элементов) массива должен быть целочисленным. Также это выражение может быть и константным.
Когда работа с массивом закончена, память, выделенную под массив необходимо освободить. Это делается с помощью оператора delete в форме delete [] имя_переменной . После того, как память освобождена, работать с массивом нельзя.
Пример использования массива с динамическим выделением памяти:
Заполнение массива значениями
При решении учебных задач, обычно предлагается заполнить массив значениями либо введёнными с клавиатуры, либо случайными значениями из определённого диапазона. Начнём со второго случая, как более простого (Парадокс? Нет, правда жизни).
Заполнение массива случайными числами
Для начала необходим генератор случайных чисел. Ниже приведён код одной из простейших реализаций:
Однако без дополнительных телодвижений стандартная функция rand() будет при каждом запуске программы генерировать одинаковую последовательность случайных чисел (кстати, это очень удобно при отладке!). Для того, что бы при каждом запуске программы получать уникальную последовательность случайных чисел, функцию rand() надо «разогнать» начальным случайным значением. Это делается с помощью функций srand() и time() .
Заполнение массива значениями, естественно, делаем в цикле. Помним, что элементы массива в C/C++ нумеруются с 0. Следовательно последний элемент массива имеет индекс на единицу меньший, чем размер массива.
В примере показано заполнение глобального автоматического массива из 10 элементов типа int случайными значения из диапазона от −100 до 100 включительно:
Обратите внимание на включение заголовочных файлов!
Заполнение массива числами, введёнными пользователем
Как ни странно, это более сложный случай. Дело в том, что во-первых, наличие человека всегда может приводить к некорректному вводу данных (ошибкам), во-вторых, для человека необходимо обеспечить какой-никакой интерфейс, а в-третьих, система потокового ввода-вывода STL имеет свои неприятные особенности.
Оно как бы работает, но если вы попытаетесь в качестве числа (конечно случайно!) ввести 1111111111111111111111111111111111 или 11q, то, в зависимости от компилятора, сможете наблюдать некоторые интересные эффекты работы вашей программы.
Поэтому приходится писать более сложный код:
Подробный разбор данного фрагмента выходит за рамки данной статьи. Но интересующиеся могут его разобрать, вооружившись, например, известной книгой Г. Шилдта.
Вывод на консоль значений из массива
Вывод значений массива на консоль реализуется элементарно. В свете уже вышесказанного даже нечего добавить:
Данный код может быть оптимизирован, но я не стал этого делать, дабы были лучше видны те самые «кирпичики», из которых он собран.
Как видно из комментариев, за поиск минимального значения и его индекса отвечает последний фрагмент программы.
Определяются две переменные, одна из которых будет содержать минимальное значение, а вторая — индекс элемента с минимальным значением. Эти переменные инициализируются первым (нулевым) элементом массива и нулём соответственно. Далее, в цикле каждое следующее значение элемента массива сравнивается с уже найденным наименьшим значением и, если текущее значение меньше запомненного, то запоминается текущее значение и его индекс.
Понятно, что поиск максимального значения производится полностью аналогично, с точностью до знаков «больше»/«меньше», вывода строки пользователю и наименования переменных.
Поиск определённого значения в массиве
Поиск определённого значения в неупорядоченном массиве осуществляется с помощью алгоритма линейного поиска. Этот простейший алгоритм заключается в последовательном переборе элементов массива и сравнением их с искомым значением.
Задачи на поиск в массиве могут быть в двух формах:
- найти первое (последнее) вхождение искомого значения
- найти все вхождения
Поиск первого вхождения:
Поиск последнего вхождения:
Обратите внимание на следующие моменты.
Переменная цикла i описана перед циклом. Таким образом, эта переменная продолжает существовать после окончания цикла, и её значение может быть использовано.
Если искомый элемент найден, то цикл завершается досрочно оператором break : просматривать остальную часть массива не имеет смысла — задача уже выполнена.
Во втором случае переменная i имеет знаковый тип int . Отрицательное значение используется в качестве флага, что весь массив просмотрен, и значение не найдено.
Поиск всех вхождений:
Здесь цикл не прерывается. Массив просматривается полностью.
Сумма/произведение отрицательных элементов массива
Сумма элементов массива с чётными/нечётными индексами
Работа с массивами с применением функций
Практически все фрагменты кода, приведённые выше, можно оформить как функции, а массив передавать через параметры. В качестве примера приведу программу нахождения суммы элементов массива с чётными индексами, в которой используется (ради разнообразия) динамический массив.
Обратите внимание, что выделение памяти под массив и её освобождение происходит в одной функции (в данном случае, в main() ). Выделять память в одной функции, а освобождать в другой — плохая идея, чреватая ошибками.
Заключение
В этой статье рассмотрены только самые элементарные приёмы работы с массивами, которые помогут (надеюсь!) начинающему кодеру понять принципы работы с массивами.
То есть, количество элементов, которые может содержать массив?
ОТВЕТЫ
Ответ 1
Управляющее резюме:
Полный ответ:
Чтобы определить размер вашего массива в байтах, вы можете использовать оператор sizeof :
На моем компьютере длина целых 4 байта, поэтому n равно 68.
Чтобы определить количество элементов в массиве, мы можем разделить общий размер массива на размер элемента массива. Вы можете сделать это с типом, как это:
и получить правильный ответ (68/4 = 17), но если тип изменился вы бы неприятная ошибка, если вы забыли изменить a sizeof(int) , а также.
Поэтому предпочтительным делителем является sizeof(a[0]) , размер нулевого элемента массива.
Еще одним преимуществом является то, что теперь вы можете легко параметризовать имя массива в макросе и получить:
Ответ 2
Способ sizeof - это правильный путь iff, который вы имеете в виду массивы, не полученные в качестве параметров. Массив, отправленный как параметр функции, рассматривается как указатель, поэтому sizeof вернет размер указателя вместо массива.
Таким образом, внутри функций этот метод не работает. Вместо этого всегда передавайте дополнительный параметр size_t size , указывающий количество элементов в массиве.
Выход (в 64-разрядной ОС Linux):
Выход (в 32-разрядной ОС Windows):
Ответ 3
Стоит отметить, что sizeof не помогает при работе со значением массива, которое разложилось на указатель: хотя он указывает на начало массива, компилятору он совпадает с указателем на один элемент этого массива. Указатель не "помнит" ничего о массиве, который использовался для его инициализации.
Ответ 4
Размерный "трюк" - это лучший способ, который я знаю, с одним маленьким, но (для меня это является основным мозолем для домашних животных) важное изменение в использовании скобок.
Как ясно из Википедии, C sizeof не является функцией; это оператор . Таким образом, он не требует скобок вокруг своего аргумента, если аргумент не является именем типа. Это легко запомнить, поскольку он делает аргумент похожим на литое выражение, которое также использует скобки.
Итак: Если у вас есть следующее:
Вы можете найти количество элементов с таким кодом:
Это, для меня, намного легче, чем альтернатива с круглыми скобками. Я также предпочитаю использовать звездочку в правой части деления, поскольку она более лаконична, чем индексирование.
Конечно, это тоже время компиляции, поэтому нет необходимости беспокоиться о делении, влияющем на производительность программы. Поэтому используйте эту форму, где можете.
Всегда лучше использовать sizeof для фактического объекта, если он есть, а не на типе, поскольку вам не нужно беспокоиться о том, чтобы сделать ошибку и указать неправильный тип.
Например, скажем, у вас есть функция, которая выводит некоторые данные в виде потока байтов, например, по сети. Позвольте вызвать функцию send() и заставить в качестве аргументов указывать указатель на отправляемый объект и количество байтов в объекте. Итак, прототип будет выглядеть следующим образом:
Теперь вы ввели тонкий способ стрелять себе в ногу, указав тип foo в двух местах. Если кто-то меняет, а другой - нет, код прерывается. Таким образом, всегда делайте это так:
Теперь вы защищены. Конечно, вы дублируете имя переменной, но это имеет высокую вероятность взлома способом, который может обнаружить компилятор, если вы его измените.
Ответ 5
Откроется эта ссылка для объяснения
Ответ 6
Вы можете использовать оператор sizeof, но он не будет работать для функций, потому что для ссылки на указатель вы можете сделать следующее, чтобы найти длину массива:
Ответ 7
Если вам известен тип данных массива, вы можете использовать что-то вроде:
Или, если вы не знаете тип данных массива, вы можете использовать что-то вроде:
Примечание. Эта вещь работает только в том случае, если массив не определен во время выполнения (например, malloc), и массив не передается в функции. В обоих случаях arr (имя массива) является указателем.
Ответ 8
Макрос ARRAYELEMENTCOUNT(x) , который каждый использует, оценивает неправильно. Это реалистично, это просто деликатный вопрос, потому что вы не можете иметь выражения, которые приводят к типу "массив".
Фактически оценивается как:
Он правильно оценивает:
Это действительно не имеет особого отношения к размеру массивов явно. Я только что заметил много ошибок, не наблюдая, как работает препроцессор C. Вы всегда переносите параметр макроса, а не включаете в него выражение.
Это правильно; мой пример был плохим. Но это на самом деле то, что должно произойти. Как уже упоминалось ранее, p + 1 закончится как тип указателя и аннулирует весь макрос (как если бы вы попытались использовать макрос в функции с параметром указателя).
В конце дня, в данном конкретном случае, ошибка не имеет большого значения (поэтому я просто теряю время, huzzah!), потому что у вас нет выражений с типом "массива", Но на самом деле вопрос о тонкостях оценки препроцессора, я думаю, является важным.
Ответ 9
Для многомерных массивов это несколько сложнее. Часто люди определяют явные макроконстанты, т.е.
Но эти константы могут быть вычислены и во время компиляции с sizeof:
Обратите внимание, что этот код работает в C и С++. Для массивов с более чем двумя измерениями используйте
и т.д., ad infinitum.
Ответ 10
Размер массива в C:
Ответ 11
Ответ 12
"вы ввели тонкий способ стрелять себе в ногу"
C 'native' массивы не сохраняют свой размер. Поэтому рекомендуется сохранять длину массива в отдельной переменной /const и передавать его всякий раз, когда вы передаете массив, а именно:
Вы ДОЛЖНЫ всегда избегать встроенных массивов (если только вы не можете, и в этом случае, обратите внимание на вашу ногу). Если вы пишете С++, используйте контейнер STL. "По сравнению с массивами они обеспечивают почти ту же производительность", и они гораздо полезнее!
Ответ 13
Ответ 14
@Магнус: стандарт определяет sizeof как уступающий количеству байтов в объекте, а sizeof (char) всегда один. Количество бит в байте является специфичным для реализации.
Изменить: стандартный раздел ANSI С++. 5.3.3. Размер:
Оператор sizeof дает количество байтов в представлении объекта своего операнда. [. ] sizeof (char), sizeof (подпись char) и sizeof (без знака char) равны 1; результат sizeof, применяемый к любому другому фундаментальному типу, определяется реализацией.
Раздел 1.6 Модель памяти С++:
Основным блоком памяти в модели памяти С++ является байт. Байт, по меньшей мере, достаточно большой, чтобы содержать любой элемент базового набора символов выполнения и состоит из непрерывной последовательности бит, число которых определяется реализацией.
Ответ 15
@Skizz: Я уверен, что я прав, хотя лучший "источник", который я могу вам дать в данный момент, - это Википедия, из статьи о sizeof:
Википедия ошибается, Skizz прав. sizeof (char) равен 1, по определению.
Я имею в виду, просто внимательно прочитайте запись в Википедии, чтобы понять, что это неправильно. msgstr "кратные char". sizeof(char) никогда не может быть ничего, кроме "1". Если бы это было, скажем, 2, это означало бы, что sizeof(char) был в два раза меньше char!
Ответ 16
Если вы действительно хотите сделать это, чтобы передать свой массив, я предлагаю реализовать структуру для хранения указателя на тип, в котором вы хотите получить массив и целое число, представляющее размер массива. Затем вы можете передать это своим функциям. Просто присвойте значение переменной массива (указатель на первый элемент) этому указателю. Затем вы можете перейти Array.arr[i] , чтобы получить i-й элемент и использовать Array.size , чтобы получить количество элементов в массиве.
Я включил для вас какой-то код. Это не очень полезно, но вы можете расширить его с большим количеством функций. Если честно, если это то, что вы хотите, вы должны прекратить использовать C и использовать другой язык с этими встроенными функциями.
Ответ 17
Лучший способ сохранить эту информацию, например, в структуре:
Внедрите все необходимые функции, такие как создание, уничтожение, проверка равенства и все остальное, что вам нужно. Это легче передать в качестве параметра.
Ответ 18
Функция sizeof возвращает количество байтов, которое используется вашим массивом в памяти. Если вы хотите вычислить количество элементов в вашем массиве, вы должны разделить это число с типом переменной sizeof массива. Пусть say int array[10]; , если целочисленное целое число переменной на вашем компьютере равно 32 бит (или 4 байта), чтобы получить размер вашего массива, вы должны сделать следующее:
то есть, количество элементов, которые может содержать массив?
определить размер массива в байтах, вы можете использовать sizeof оператор:
на моем компьютере ints имеют длину 4 байта, поэтому n-68.
определить количество элементов в массиве, мы можем разделить общий размер массива по размеру элемента массива. Вы можете сделать это с типом, например:
и получаем правильный ответ (68 / 4 = 17), но если тип из a изменено у вас будет неприятная ошибка, если вы забыли изменить the sizeof(int) как хорошо.
так что выбранный делитель sizeof(a[0]) , размер zeroeth элемент массива.
еще одно преимущество заключается в том, что теперь вы можете легко параметризовать имя массива в макросе и получить:
на sizeof путь это правильный путь iff вы имеете дело с массивами не получили в качестве параметров. Массив, отправленный в качестве параметра функции, рассматривается как указатель, поэтому sizeof вернет размер указателя, а не массива.
таким образом, внутри функции этот метод не работает. Вместо этого всегда передавайте дополнительный параметр size_t size указание количества элементов в матрица.
стоит отметить, что sizeof не помогает при работе со значением массива, которое распалось на указатель: хотя оно указывает на начало массива, для компилятора это то же самое, что указатель на один элемент этого массива. Указатель не "помнит" ничего другого о массиве, который использовался для его инициализации.
размер "трюк" - лучший способ, который я знаю, с одним небольшим, но (для меня, это главное домашнее животное) важным изменением в использовании скобок.
как показывает запись Википедии, C's sizeof не является функцией; это оператор. Таким образом, он не требует скобок вокруг своего аргумента, если аргумент не является именем типа. Это легко запомнить, так как это делает аргумент похожим на выражение cast, которое также использует скобка.
Итак: если у вас есть следующие:
вы можете найти количество элементов с таким кодом:
это, для меня, читается намного проще, чем альтернатива с круглыми скобками. Я также предпочитаю использовать звездочку в правой части раздела, поскольку она более лаконична, чем индексация.
конечно, это все время компиляции тоже, поэтому нет необходимости беспокоиться о разделении, влияющем на производительность программа. Так что используйте эту форму везде, где сможете.
всегда лучше использовать sizeof на фактическом объекте, когда у вас есть один, а не на типе, так как тогда вам не нужно беспокоиться о том, чтобы сделать ошибку и указать неправильный тип.
например, скажем, у вас есть функция, которая выводит некоторые данные в виде потока байтов, например по сети. Назовем функцию send() , и сделать его в качестве аргументов указатель на объект для отправки и количество байтов в объект. Итак, прототипом становится:
теперь вы ввели тонкий способ выстрелить себе в ногу, указав тип foo в двух местах. Если одно меняется, а другое нет, код ломается. Таким образом, всегда делайте это так:
теперь вы защищены. Конечно, вы дублируете имя переменной, но это имеет высокую вероятность нарушение таким образом, что компилятор может обнаружить, если вы измените его.
этот вопрос был вдохновлен аналогичным вопросом: Как удалить[] "знать" размер массива операндов?
мой вопрос немного иначе: есть ли способ определить размер массива c++ программно? А если нет, то почему? каждая функция, которую я видел, которая принимает массив, также требует целочисленного параметра, чтобы дать ему размер. Но, как указал связанный вопрос, delete[] должен знать размер памяти, чтобы быть освободившему.
рассмотрим этот код C++:
это выводит " Size of arr: 4 ", который является просто размером указателя. Было бы неплохо иметь некоторую функцию, которая печатает 256, но я не думаю, что она существует в C++. (Опять же, часть вопроса заключается в том, почему он не существует.)
уточнение: Я знаю, что если я объявил массив на стеке вместо кучи (т. е. " int arr[256]; "), что sizeof оператор вернет 1024 (длина массива * sizeof (int)).
delete [] Не знаю размер, который был выделен. Однако эти знания хранятся в среде выполнения или в диспетчере памяти операционной системы, что означает, что они недоступны компилятору во время компиляции. И sizeof() не является реальной функцией, она фактически оценивается в константу компилятором, что он не может сделать для динамически выделенных массивов, размер которых не известен во время компиляции.
кроме того, рассмотрим это пример:
как компилятор узнает, что размер p - это? Корень проблемы заключается в том, что массивы в C и C++ не являются объектами первого класса. Они распадаются на указатели, и компилятор или сама программа не могут узнать, указывает ли указатель на начало куска памяти, выделенного new , или к одному объекту, или к какому-то месту в середине куска памяти, выделенного new .
одной из причин этого является то, что C и C++ оставляют управление памятью программисту и операционной системе, поэтому у них также нет сборки мусора. Реализация new и delete не является частью стандарта C++, потому что C++ предназначен для использования на различных платформах, которые могут управлять своей памятью очень по-разному. Возможно, можно позволить C++ отслеживать все выделенные массивы и их размеры, если вы пишете текстовый процессор для окна windows, работающего на последнем процессоре Intel, но это может быть совершенно невозможно, когда вы пишете встроенную систему, работающую на DSP.
нет, это невозможно сделать в стандартном C++.
нет действительно веской причины, почему бы и нет, что я знаю. Вероятно, размер считался деталью реализации, а лучше всего не выставлялся. Обратите внимание, что когда вы говорите malloc (1000), нет никакой гарантии, что возвращаемый блок составляет 1000 байт --- только то, что это по крайней мере 1000 байт. Скорее всего, это около 1020 (1K минус 4 байта для накладных расходов). В этом случае размер "1020" является важным для библиотека времени выполнения для запоминания. И, конечно же, это будет меняться между реализациями.
именно поэтому комитет по стандартам добавил std: vector, который отслеживает его точный размер.
Ну есть на самом деле способ определить размер, но это не "безопасно" и будет отличаться от компилятора к компилятору. поэтому он не должен использоваться вообще.
когда вы делаете: int* arr = new int[256];
256 не имеет значения вам будет дано 256 * sizeof ( int) предполагая, что в этом случае 1024, это значение будет сохранено, вероятно, в (arr - 4 )
так, чтобы дать вам количество "элементов"
int* p_iToSize = arr - 4;
printf ("количество элементов %d", *p_iToSize / sizeof(int));
для каждого malloc, new, независимо от того, что перед блоком памяти continuos, который вы получаете, также выделяется место, зарезервированное с некоторой информацией о блоке памяти, который вам был предоставлен.
Первый элемент имеет порядковый номер 0. Важно понимать, почему. В дальнейшем будем представлять память компьютера в виде ленты. Имя массива - это указатель на адрес памяти, где располагаются элементы массива.
Рис. 1 Массив хранит адрес первого элемента. Индекс i элемента - это сдвиг на i*sizeof(тип) байт от начала
Индекс массива указывает, на сколько байт необходимо сместиться относительно начала массива, чтобы получить доступ до нужно элемента. Например, если массив A имеет тип int, то A[10] означает, что мы сместились на 10*sizeof(int) байт относительно начала. Первый элемент находится в самом начале и у него смещение 0*sizeof(int) .
В си массив не хранит своего размера и не проверяет индекс массива на корректность. Это значит, что можно выйти за пределы массива и обратиться к памяти, находящейся дальше последнего элемента массива (или ближе).
Начальная инициализация массива.
Н апишем простую программу. Создадим массив, после чего найдём его максимальный элемент.
Разберём пример. Сначала мы создаём массив и инициализируем его при создании. После этого присваиваем максимальному найденному элементу значение первого элемента массива.
После чего проходим по массиву. Так как мы уже просмотрели первый элемент (у него индекс 1), то нет смысла снова его просматривать.
Тот же пример, только теперь пользователь вводит значения
В том случае, если при инициализации указано меньше значений, чем размер массива, остальные элементы заполняются нулями.
Если необходимо заполнить весь массив нулями, тогда пишем
Можно не задавать размер массива явно, например
массив будет иметь размер 3
Размер массива
М ассив в си должен иметь константный размер. Это значит, что невозможно, например, запросить у пользователя размер, а потом задать этот размер массиву.
Создание динамических массивов будет рассмотрено дальше, при работе с указателями и памятью
В некоторых случаях можно узнать размер массива с помощью функции sizeof.
Но это вряд ли будет полезным. При передаче массива в качестве аргумента функции будет передаваться указатель, поэтому размер массива будет невозможно узнать.
Статические массивы удобны, когда заранее известно число элементов. Они предоставляют быстрый, но небезопасный доступ до элементов.
Переполнение массива
П ускай у вас есть такой код
- 1. Используйте тип size_t для индексирования. Он обезопасит вас от отрицательных значений и его всегда хватит для массива любого размера.
- 2. Помните, что массив начинается с нуля.
- 3. Последний элемент массива имеет индекс (размер массива - 1)
Примеры
Т еперь несколько типичных примеров работы с массивами
1. Переворачиваем массив.
Здесь незнакомая для вас конструкция
макрос. Во всём коде препроцессор автоматически заменит все вхождения SIZE на 10u.
2. Удаление элемента, выбранного пользователем.
Удаление элемента в данном случае, конечно, не происходит. Массив остаётся того же размера, что и раньше. Мы просто затираем удаляемый элемент следующим за ним и выводим SIZE-1 элементов.
3. Пользователь вводит значения в массив. После этого вывести все разные значения, которые он ввёл.
Пусть пользователь вводит конечное число элементов, допустим 10. Тогда заранее известно, что всего различных значений будет не более 10. Каждый раз, когда пользователь вводит число будем проходить по массиву и проверять, было ли такое число введено.
4. Пользователь вводит число - количество измерений (от 2 до 10). После этого вводит все измерения. Программа выдаёт среднее значение, дисперсию, погрешность.
5. Сортировка массива пузырьком
6. Перемешаем массив. Воспользуемся для этого алгоритмом Fisher-Yates:
Для i от N-1 до 1 выбираем случайное число j в пределах от 0 до i и меняем местами i-й и j-й элементы.
Читайте также: