как узнать размер массива
Как узнать размер массива переданного в функцию?
Необходимо определить размер массива, переданного в функцию. Пробовал вот так:
но в SIZE сохраняется 1, независимо от размера массива. Можно, конечно, вместе с массивом передать в функцию и его размер, но может существует более изящное решение?
P.S.: Кстати, заметил нечто странное. Запускал эту программу через Visual Studio и Qt. В VS в SIZE сохраняется 1, а в Qt 2.
1 ответ 1
У вас параметр функции foo объявлен как указатель типа int *
Следовательно внутри функции выражение
Но даже если вы объявите эту функцию как
все равно параметр функции неявно преобразуется в указатель на элемент массива. То есть эти два объявления функции объявляют одну и ту же функцию и эквивалетны следующему объявлению
Так что внутри функции вы снова будете иметь дело с указателем.
Когда массив передается по значению, то вам следует также объявлять второй параметр, который задает размер массива.
То есть в общем случае вам следует объявлять функцию как
Недостаток этого объявления состоит в том, что эта функция может иметь дело только с массивами, заданного в ее параметре размера.
Чтобы обойти это ограничение, вы можете объявить шаблонную функцию. Например,
В этом случае компилятор, используя шаблон, создаст столько функций, сколько массивов разной длины были использованы в качестве аргумента.
Массивы
Массивы
П усть нам необходимо работать с большим количеством однотипных данных. Например, у нас есть тысяча измерений координаты маятника с каким-то шагом по времени. Создавать 1000 переменных для хранения всех значений очень. обременительно. Вместо этого множество однотипных данных можно объединить под одним именем и обращаться к каждому конкретному элементу по его порядковому номеру.
Массив в си определяется следующим образом
[ ];
Например,
int a[100];
Мы получим массив с именем a, который содержит сто элементов типа int. Как и в случае с переменными, массив содержит мусор.
Для получения доступа до первого элемента, в квадратных скобках пишем его номер (индекс). Например
Начальная инициализация массива.
Н апишем простую программу. Создадим массив, после чего найдём его максимальный элемент.
Разберём пример. Сначала мы создаём массив и инициализируем его при создании. После этого присваиваем максимальному найденному элементу значение первого элемента массива.
После чего проходим по массиву. Так как мы уже просмотрели первый элемент (у него индекс 1), то нет смысла снова его просматривать.
Тот же пример, только теперь пользователь вводит значения
В том случае, если при инициализации указано меньше значений, чем размер массива, остальные элементы заполняются нулями.
Если необходимо заполнить весь массив нулями, тогда пишем
Можно не задавать размер массива явно, например
массив будет иметь размер 3
Размер массива
М ассив в си должен иметь константный размер. Это значит, что невозможно, например, запросить у пользователя размер, а потом задать этот размер массиву.
Создание динамических массивов будет рассмотрено дальше, при работе с указателями и памятью
В некоторых случаях можно узнать размер массива с помощью функции sizeof.
Но это вряд ли будет полезным. При передаче массива в качестве аргумента функции будет передаваться указатель, поэтому размер массива будет невозможно узнать.
Статические массивы удобны, когда заранее известно число элементов. Они предоставляют быстрый, но небезопасный доступ до элементов.
Переполнение массива
П ускай у вас есть такой код
Примеры
Т еперь несколько типичных примеров работы с массивами
1. Переворачиваем массив.
Здесь незнакомая для вас конструкция
макрос. Во всём коде препроцессор автоматически заменит все вхождения SIZE на 10u.
2. Удаление элемента, выбранного пользователем.
Удаление элемента в данном случае, конечно, не происходит. Массив остаётся того же размера, что и раньше. Мы просто затираем удаляемый элемент следующим за ним и выводим SIZE-1 элементов.
3. Пользователь вводит значения в массив. После этого вывести все разные значения, которые он ввёл.
Пусть пользователь вводит конечное число элементов, допустим 10. Тогда заранее известно, что всего различных значений будет не более 10. Каждый раз, когда пользователь вводит число будем проходить по массиву и проверять, было ли такое число введено.
5. Сортировка массива пузырьком
6. Перемешаем массив. Воспользуемся для этого алгоритмом Fisher-Yates:
Для i от N-1 до 1 выбираем случайное число j в пределах от 0 до i и меняем местами i-й и j-й элементы.
Изучаем C++. Часть 7. Массивы и работа с ними
Разбираемся, как пользоваться одним из самых удобных способов хранения данных.
Это седьмая часть из серии статей «Глубокое погружение в C++». В прошлой статье мы узнали, как использовать циклы while, do-while и for и сокращать с их помощью код. Сегодняшняя тема — массивы.
Массив — это определённое число ячеек памяти, расположенных подряд. Они позволяют эффективно хранить однотипные данные: зарплаты сотрудников, координаты персонажей, баллы учеников и так далее.
На картинке выше показано объявление массива из четырёх элементов целочисленного типа. Несмотря на то что значения элементам не присваивались, массив всё равно будет занимать такой объём памяти, который занимали бы четыре переменные. В данном случае — 16 байт.
Массивы очень удобные и быстрые: расположение ячеек друг за другом позволяет увеличить скорость работы с данными в них.
Пишет о программировании, в свободное время создает игры. Мечтает открыть свою студию и выпускать ламповые RPG.
Как объявить массив в C++
Есть несколько способов объявления массивов:
Нумерация в массивах начинается с нуля, а не с единицы. При этом длина остается обычной. То есть в массиве длиной в десять ячеек индекс последней будет 9.
Важно! Массивы — иммутабельные (неизменяемые). Вы можете скорректировать значения отдельных элементов, но не сам массив — нельзя изменить его длину или присвоить одному массиву другой.
Всегда следите, чтобы не обращаться к ячейке данных, которая находится за пределами массива. Если длина равна 5, а вы обратитесь к ячейке под индексом 5, 6, 7 и так далее, то результат может быть непредсказуемым.
Есть ли способ определить размер массива C++ программно? А если нет, то почему?
этот вопрос был вдохновлен аналогичным вопросом: Как удалить[] «знать» размер массива операндов?
мой вопрос немного иначе: есть ли способ определить размер массива c++ программно? А если нет, то почему? каждая функция, которую я видел, которая принимает массив, также требует целочисленного параметра, чтобы дать ему размер. Но, как указал связанный вопрос, delete[] должен знать размер памяти, чтобы быть освободившему.
рассмотрим этот код C++:
это выводит » Size of arr: 4 «, который является просто размером указателя. Было бы неплохо иметь некоторую функцию, которая печатает 256, но я не думаю, что она существует в C++. (Опять же, часть вопроса заключается в том, почему он не существует.)
уточнение: Я знаю, что если я объявил массив на стеке вместо кучи (т. е. » int arr[256]; «), что sizeof оператор вернет 1024 (длина массива * sizeof (int)).
20 ответов:
delete [] Не знаю размер, который был выделен. Однако эти знания хранятся в среде выполнения или в диспетчере памяти операционной системы, что означает, что они недоступны компилятору во время компиляции. И sizeof() не является реальной функцией, она фактически оценивается в константу компилятором, что он не может сделать для динамически выделенных массивов, размер которых не известен во время компиляции.
кроме того, рассмотрим это пример:
одной из причин этого является то, что C и C++ оставляют управление памятью программисту и операционной системе, поэтому у них также нет сборки мусора. Реализация new и delete не является частью стандарта C++, потому что C++ предназначен для использования на различных платформах, которые могут управлять своей памятью очень по-разному. Возможно, можно позволить C++ отслеживать все выделенные массивы и их размеры, если вы пишете текстовый процессор для окна windows, работающего на последнем процессоре Intel, но это может быть совершенно невозможно, когда вы пишете встроенную систему, работающую на DSP.
нет, это невозможно сделать в стандартном C++.
именно поэтому комитет по стандартам добавил std: vector, который отслеживает его точный размер.
Ну есть на самом деле способ определить размер, но это не «безопасно» и будет отличаться от компилятора к компилятору. поэтому он не должен использоваться вообще.
когда вы делаете: int* arr = new int[256];
так, чтобы дать вам количество «элементов»
printf («количество элементов %d», *p_iToSize / sizeof(int));
для каждого malloc, new, независимо от того, что перед блоком памяти continuos, который вы получаете, также выделяется место, зарезервированное с некоторой информацией о блоке памяти, который вам был предоставлен.
общий способ справиться с этим-либо использовать вектор
Как определить размер моего массива в C?
Как определить размер моего массива в C?
то есть, количество элементов, которые может содержать массив?
21 ответов
определить размер массива в байтах, вы можете использовать sizeof оператор:
на моем компьютере ints имеют длину 4 байта, поэтому n-68.
определить количество элементов в массиве, мы можем разделить общий размер массива по размеру элемента массива. Вы можете сделать это с типом, например:
и получаем правильный ответ (68 / 4 = 17), но если тип из a изменено у вас будет неприятная ошибка, если вы забыли изменить the sizeof(int) как хорошо.
еще одно преимущество заключается в том, что теперь вы можете легко параметризовать имя массива в макросе и получить:
на sizeof путь это правильный путь iff вы имеете дело с массивами не получили в качестве параметров. Массив, отправленный в качестве параметра функции, рассматривается как указатель, поэтому sizeof вернет размер указателя, а не массива.
таким образом, внутри функции этот метод не работает. Вместо этого всегда передавайте дополнительный параметр size_t size указание количества элементов в матрица.
стоит отметить, что sizeof не помогает при работе со значением массива, которое распалось на указатель: хотя оно указывает на начало массива, для компилятора это то же самое, что указатель на один элемент этого массива. Указатель не «помнит» ничего другого о массиве, который использовался для его инициализации.
как показывает запись Википедии, C’s sizeof не является функцией; это оператор. Таким образом, он не требует скобок вокруг своего аргумента, если аргумент не является именем типа. Это легко запомнить, так как это делает аргумент похожим на выражение cast, которое также использует скобка.
Итак: если у вас есть следующие:
вы можете найти количество элементов с таким кодом:
это, для меня, читается намного проще, чем альтернатива с круглыми скобками. Я также предпочитаю использовать звездочку в правой части раздела, поскольку она более лаконична, чем индексация.
конечно, это все время компиляции тоже, поэтому нет необходимости беспокоиться о разделении, влияющем на производительность программа. Так что используйте эту форму везде, где сможете.
всегда лучше использовать sizeof на фактическом объекте, когда у вас есть один, а не на типе, так как тогда вам не нужно беспокоиться о том, чтобы сделать ошибку и указать неправильный тип.
и затем вам нужно отправить целое число, поэтому вы кодируете его следующим образом:
теперь вы ввели тонкий способ выстрелить себе в ногу, указав тип foo в двух местах. Если одно меняется, а другое нет, код ломается. Таким образом, всегда делайте это так:
теперь вы защищены. Конечно, вы дублируете имя переменной, но это имеет высокую вероятность нарушение таким образом, что компилятор может обнаружить, если вы измените его.