Получение размерности двумерного массива через операцию sizeof();
Подскажите пожалуйста форумчане можно ли получить размерность двумерного массива через операцию sizeof() ?
Пример функции для одномерного массива :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
void maxmin(int d[ ],int size,int *pmax,int *pmin) { int i=0; int max,min; min=max=d[0]; for(i;i12;i++) { if (d[i]>max) max=d[i] ; if (d[i]min) min=d[i] ; } *pmax=max; *pmin=min; }
Объявление в main:
maxmin (array_0,sizeof(array_0)/sizeof(int), & max, & min);
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Определение и вывод номеров минимальных элементов двумерного массива и ввод массива меньшей размерности
Доброго времени суток. Пожалуйста, помогите с решением задания. Заранее спасибо. Исходная.
Получение размерности получаемого сообщения через TcpClient
Вопрос вот в чем: Мне нужно передавать сообщение статического размера по сети. Проблема в том, что.
Ввод вручную размерности двумерного массива
Здравствуйте уважаемые форумчане. Такая небольшая проблема. У нас есть двумерный массив.
Проблема с передачей размерности двумерного массива
Пользователь вводит количество строк и стобцов массива. Есть несколько способов ввода: с.
Почетный модератор
64291 / 47589 / 32740
Регистрация: 18.05.2008
Сообщений: 115,181
Двумерный массив размером n*m это для памяти тоже что и одномерный размером n*m
4984 / 3091 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
Принцип тот же.
1 2 3 4 5 6 7 8 9 10 11
#include #include using namespace std; int main() { int arr[3][4]; cout sizeof( arr ) / sizeof( arr[0][0] ) endl; // 12 return 0; }
Добавлено через 11 минут
На Си.
1 2 3 4 5 6 7 8 9 10 11 12
#include int main() { int arr[3][4]; printf( "rows: %d\n", sizeof( arr ) / sizeof( arr[0] ) ); printf( "columns: %d\n", sizeof( arr[0] ) / sizeof( arr[0][0] ) ); printf( "number of elements: %d\n", sizeof( arr ) / sizeof( arr[0][0] ) ); return 0; }
5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
Сообщение от Boderman
Подскажите пожалуйста форумчане можно ли получить размерность двумерного массива через операцию sizeof() ?
В общем случае даже размер одномерного массива получить нельзя.
Регистрация: 25.03.2013
Сообщений: 140
Сообщение от Nameless One
В общем случае даже размер одномерного массива получить нельзя.
Почетный модератор
64291 / 47589 / 32740
Регистрация: 18.05.2008
Сообщений: 115,181
Это точно. И когда научимся писать вопрос по русски.
Добавлено через 1 минуту
Сообщение от Boderman
Да потому что sizeof определяет не размерность массива, а размер выделенной памяти.
5827 / 3478 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
Boderman, потому что sizeof возвращает размер в байтах своего операнда. При применении этого оператора к (статическому) массиву возвращается размер в байтах всего массива — это, по сути, единственный случай, когда sizeof позволяет узнать размер массива. При применении же его к указателю возвращается размер указателя. А теперь вспомни, что динамические массивы на самом деле являются обычными указателями, а при передачи статического массива в функцию он превращается в указатель, и ты получишь ответ на свой вопрос.
Можешь ещё почитать, что в стандарте написано по этой теме.
Пример вместо тысячи слов:
1 2 3 4 5 6 7 8 9 10 11 12 13
#include void foo(int *x) { printf("%d\n", sizeof x); } int main(void) { int x[3]; foo(x); return 0; }
Двумерные массивы
Объявление int A[n] создает в памяти одномерный массив: набор пронумерованных элементов, идущих в памяти последовательно. К каждому элементу массива можно обратиться, указав один индекс — номер этого элемента. Но можно создать и двумерный массив следующим образом: int A[n][m] . Данное объявление создает массив из n объектов, каждый из которых в свою очередь является массивом типа int [m] . Тогда A[i] , где i принимает значения от 0 до n-1 будет в свою очередь одним из n созданных обычных массивов, и обратиться к элементу с номером j в этом массиве можно через A[i][j] .
Подобные объекты (массивы массивов) также называют двумерными массивами. Двумерные массивы можно представлять в виде квадратной таблицы, в которой первый индекс элемента означает номер строки, а второй индекс – номер столбца. Например, массив A[3][4] будет состоять из 12 элементов и его можно записать в виде
A[0][0] A[0][1] A[0][2] A[0][3] A[1][0] A[1][1] A[1][2] A[1][3] A[2][0] A[2][1] A[2][2] A[2][3]
Для считывания, вывода на экран и обработки двумерных массивов необходимо использовать вложенные циклы. Первый цикл – по первому индексу (то есть по всем строкам), второй цикл – по второму индексу, то есть по всем элементам в строках (столбцам). Например, вывести на экран двумерный массив в виде таблицы, разделяя элементы в строке одним пробелом можно следующим образом:
int A[n][m]; for (int i = 0; i < n; ++i) < // Выводим на экран строку i for (int j = 0; j < m; ++j) < cout cout
А считать двумерный массив с клавиатуры можно при помощи еще более простого алгоритма (массив вводится по строкам, то есть в порядке, соответствующему первому примеру):
for (i = 0; i < n; ++i) < for (j = 0; j < m; ++j) < cin >> A[i][j]; > >
Обработка двумерного массива
Обработка двумерных массивов производится аналогичным образом. Например, если мы хотим записать в массив таблицу умножения, то есть присвоить элементу A[i][j] значение i * j , это можно сделать следующим образом при помощи вложенных циклов:
for (i = 0; i < n; ++i) < for (j = 0; j < m; ++j) < A[i][j] = i * j; >>
Рассмотрим более сложную задачу и несколько способов ее решения. Пусть дан квадратный двумерный массив int A[n][n] . Необходимо элементам, находящимся на главной диагонали проходящей из левого верхнего угла в правый нижний (то есть тем элементам A[i][j] , для которых i == j ) присвоить значение 1 , элементам, находящимся выше главной диагонали – значение 0, элементам, нахощящимся ниже главной диагонали – значение 2. То есть получить такой массив (пример для n == 4 ):
1 0 0 0 2 1 0 0 2 2 1 0 2 2 2 1
Рассмотрим несколько способов решения этой задачи. Элементы, которые лежат выше главной диагонали – это элементы A[i][j] , для которых i < j , а для элементов ниже главной диагонали i >j . Таким образом, мы можем сравнивать значения i и j и по ним определять значение A[i][j] . Получаем следующий алгоритм:
for (i = 0; i < n; ++i) < for (j = 0; j < n; ++j) < if (i < j) < A[i][j] = 0; >else if (i > j) < A[i][j] = 2; >else < A[i][j] = 1; >> >
Данный алгоритм плох, поскольку выполняет одну или две инструкции if для обработки каждого элемента. Если мы усложним алгоритм, то мы сможем обойтись вообще без условных инструкций.
Сначала заполним главную диагональ, для чего нам понадобится один цикл:
for (i = 0; i
Затем заполним значением 0 все элементы выше главной диагонали, для чего нам понадобится в каждой из строк с номером i присвоить значение элементам A[i][j] для j = i+1 , . n-1 . Здесь нам понадобятся вложенные циклы:
for (i = 0; i < n; ++i) < for (j = i + 1; j < n; ++j) < A[i][j] = 0; >>
Аналогично присваиваем значение 2 элементам A[i][j] для j = 0 , . i-1 :
for (i = 0; i < n; ++i) < for (j = 0; j < i; ++j) < A[i][j] = 2; >>
Можно также внешние циклы объединить в один и получить еще одно, более компактное решение:
for (i = 0; i < n; ++i) < // Заполняем строку с номером i for (j = 0; j < i; ++j) < A[i][j] = 2; // Сначала пишем 2 ниже диагонали >A[i][j] = 1; // После завершения предыдущего цикла i==j, пишем 1 for (++j; j < n; ++j) // Цикл начинаем с увеличения j на 1 < A[i][j] = 0; // Записываем 0 выше диагонали >>
Многомерные массивы
Можно объявлять не только двумерные массивы, но и массивы с большим количеством измерений. Например, объявление int A[n][m][l] создает трехмерный массив из n*m*l элементов. Для обращения к каждому элементу такого массива необходимо указать три индекса: A[i][j][k] , при этом 0
Передача двумерных массивов в функцию
В функцию можно передавать двумерный массив в качестве параметра, если размер этого массива фиксирован и объявлен в описании функции. То есть если заранее известен размер массива, то можно определить функцию, получающую в качестве параметра двумерный массив такого размера:
void f (int A[10][10]) < . >int main()
Проблема заключается в том, что в этом случае нельзя использовать массивы произвольного размера.
Чтобы использовать массивы произвольного размера, нам на помощь прийдут указатели. Для начала разберемся, как представлять двумерный массив в виде указателей.
Одномерный массив int A[n] это почти то же самое, что указатель на переменную типа int : int * A .
Тогда двумерный массив - это массив, каждый из элементов которого является одномерным массивом, то есть указателем на какой-то адрес целого числа в памяти. То есть двумерный массив - это массив элементов типа int * или же это указатель на переменную типа int * , то есть это переменная типа int ** .
Итак, двойной указатель можно объявить так:
int ** A;
Теперь выделим память для массива A . Если мы хотим, чтобы в массиве A было n элементов, каждый из которых является указателем на тип int , то сделаем это при помощи операции new :
A = new int * [n];
Теперь A указывает на область памяти, содержащей n элементов, каждый из которых имеет тип int * и указывает на некоторую область памяти, пока еще не выделенную. Выделим эту память - сделаем все A[i] указателями на область памяти из m элементов типа int :
for (int i = 0; i
Функцию, получающую в качестве параметра двумерный массив, можно объявлять так:
void f (int ** A, int n, int m)
Как и в случае с одномерным массивом, передаваемым как указатель, нам нужно одновременно передавать размеры массива - количество строк n и количество столбцов m .
При таком способе объявления массива и выделения памяти можно сделать так, чтобы в разных строчках массива было различное число элементов.
Форматирование чисел при выводе
Допустим, мы заполним массив таблицей умножения: A[i][j]=i*j как в примере в начале раздела. Если мы теперь попробуем вывести этот массив на экран, разделяя элементы в строке одним пробелом, то из-за того, что числа имеют различную длину столбцы таблицы окажутся неровными:
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 10 12 14 16 18 0 3 6 9 12 15 18 21 24 27
Для того, чтобы получить ровные столбцы необходимо, выводить числа так, чтобы одно выводимое число имело ширину, например, ровно в 3 символа, а “лишние” позиции были бы заполнены пробелами. Тогда получится следующая таблица:
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9 0 2 4 6 8 10 12 14 16 18 0 3 6 9 12 15 18 21 24 27
Для того, чтобы выводимое число или строка имело ровно заданную ширину, необходимо перед выводом его на экран для потока cout вызвать метод width с параметром 3 . Данный метод устанавливает ширину поля для выводимого значения. Получим следующую программу для вывода:
for(int i = 0; i < n; ++i) < for(int j = 0; j < m; ++j) < cout.width(3); cout cout
Заметим, что мы теперь не выводим пробел после каждого числа, поскольку мы добавили этот пробел к ширине выводимого поля. Функция width действует однократно, только на следующее выводимый в поток значение, поэтому ее нужно вызывать перед каждым выводом числа на экран.
Внимание! Если выводимое число или строка имеет большую длину, чем это было установлено функцией width , то это число или строка будут выведены полностью, а не будет обрезано до указанного значения. То есть предпочтительней вывести результат некрасиво, нежели неверно.
Упражнения
Общие требования к оформлению программ.
Считывание данных осуществляется функцией void Read (int **& A, int & n, int & m) . Эта функция считывает размер массива в переменные n и m , передаваемые по ссылке, выделяет память под хранение массива.
Решение задачи осуществляется функцией, получающей в качестве параметра массив (типа int ** ), его размеры, дополнительные параметры при необходимости.
Вывод массива на экран осуществляется отдельной функцией Print , получающей в качестве параметров массив и его размеры.
Типичный вид программы на примере задачи A:
void Read (int **& A, int & n) < . >void Fill (int ** A, int n) < . >void Print (int ** A, int n) < . >int main()
A: Максимум
Найдите индексы первого вхождения максимального элемента. Выведите два числа: номер строки и номер столбца, в которых стоит наибольший элемент в двумерном массиве. Если таких элементов несколько, то выводится тот, у которого меньше номер строки, а если номера строк равны то тот, у которого меньше номер столбца.
3 4
0 3 2 4
2 3 5 5
5 1 2 3
Как узнать размер двумерного массива c
На этом шаге мы рассмотрим организацию и доступ к элементам такого массива .
В двумерном массиве для однозначной идентификации элемента в массиве необходимо указать два индекса. Двумерный массив удобно представлять в виде таблицы. Первый индекс определяет строку, в которой находится элемент, а второй индекс определяет столбец. Создается двумерный массив практически так же, как и одномерный: объявляется переменная массива, создается собственно массив, и ссылка на этот массив записывается в переменную массива. При объявлении переменной двумерного массива после идентификатора типа указываются квадратные скобки с запятой внутри [,] . Например, если мы хотим объявить переменную для двумерного целочисленного массива, то соответствующая инструкция могла бы выглядеть как
int[,] nums; .
При создании двумерного массива используется инструкция new , а после нее указывается идентификатор типа для элементов массива и в квадратных скобках разделенные через запятую два целых числа, определяющих размер массива по каждому из индексов (количество строк и столбцов в двумерном массиве). Например, создать двумерный целочисленный массив из 3 строк и 5 столбцов можно инструкцией
new int [3, 5].
Как и для одномерного массива, значением инструкции, создающей двумерный массив, является ссылка на этот массив. Поэтому если переменная nums предварительно объявлена командой
int [,] nums; ,
то законной была бы команда
nums = new int [3, 5]; .
Команды объявления переменной массива и создания массива можно объединять:
int[,] nums = new int [3, 5]; .
Ниже приведен шаблон объявления переменной для двумерного массива и создания двумерного массива:
тип[,] переменная; переменая = new тип[размер, размер];
Можно использовать и такой шаблон:
тип[,] переменная = new тип[размер, размер];
Для обращения к элементу массива указывают имя массива и в квадратных скобках через запятую - индексы этого элемента. Индексация по каждому индексу начинается с нуля. То есть инструкция nums[0, 0] означает обращение к элементу массива nums , который расположен в первой строке и первом столбце (в строке с индексом 0 и столбце с индексом 0). Выражение nums[1, 2] является обращением к элементу, находящемуся в строке с индексом 1 (вторая по порядку строка) и столбце с индексом 2 (третий по порядку столбец).
Свойство Length для двумерного массива возвращает общее количество элементов в массиве. То есть для массива nums из 3 строк и 5 столбцов значением выражения nums.Length является число 15 (произведение 3 на 5). Чтобы узнать размер массива по какому-то индексу (то есть количество строк или количество столбцов в массиве), используют метод GetLength() . Метод вызывается из переменной массива, а аргументом методу передается целое число, определяющее индекс, для которого возвращается размер массива.
Массивы в C# по факту реализуются как объекты. Как и у прочих объектов, у массива есть методы (и свойства). Более детально объекты обсуждаются немного позже. Здесь для нас важно научиться пользоваться преимуществами, которые имеются у массивов благодаря такому "объектному" способу их реализации.
Размерность массива определяется количеством индексов, которые нужно указать для идентификации элемента массива. Определить размерность массива можно с помощью свойства Rank . Размерность двумерного массива равна 2.
Если мы вызываем метод GetLength() с аргументом 0, то значением возвращается размер массива по первому индексу. Если вызвать метод GetLength() с аргументом 1, то получим размер массива по второму индексу.
Например, если массив nums состоит из 3 строк и 5 столбцов, то значением выражения nums.GetLength(0) является число 3 (размер но первому индексу - количество строк), а значением выражения nums.GetLength(1) является число 5 (размер по второму индексу - количество столбцов).
НИже приведен пример, в котором иллюстрируется способ создания двумерного массива: создается целочисленный массив и построчно заполняется натуральными числами.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr56_1 < class Program < static void Main() < // Количество строк и столбцов в массиве: int rows = 3, cols = 5; // Создание двумерного массива: int[,] nums = new int[rows, cols]; // Значение первого элемента в массиве: int value = 1; // Заполнение и отображение массива. // Перебор строк в массиве: for(int i = 0; i < nums.GetLength(0); i++) < // Перебор столбцов в строке: for (int j = 0; j < nums.GetLength(1); j++) < // Присваивание значения элементу массива: nums[i, j] = value; // Это будет значение следующего элемента: value++; // Отображение элемента в строке: Console.Write(nums[i, j] + "\t"); > // Переход к новой строке: Console.WriteLine(); > // Задержка: Console.ReadLine(); > > >
Архив проекта можно взять здесь.
Результат выполнения программы представлен ниже.
Рис.1. Результат работы приложения
В программе количество строк и столбцов в двумерном массиве задается через целочисленные переменные rows и cols (значения 3 и 5 соответственно). Двумерный массив создается командой
int[,] nums = new int[rows, cols]; .
Для заполнения массива и отображения значений его элементов используются вложенные конструкции цикла. Во внешнем цикле индексная переменная i перебирает строки двумерного массива. Начальное значение переменной равно 0, а верхняя граница определяется значением выражения nums.GetLength(0) (количество строк в массиве nums - переменная i строго меньше этого значения). Во внутреннем цикле переменная j перебирает столбцы двумерного массива. Начальное значение переменной равно 0, и за каждый цикл переменная увеличивается на единицу. Конструкция цикла выполняется, пока значение переменной строго меньше значения выражения nums.GetLength(1) (количество столбцов в массиве nums ). При заданных значениях индексов i и j командой
nums[i, j] = value;
соответствующему элементу массива присваивается значение. Начальное значение переменной value равно 1, поэтому первый элемент в массиве (элемент с двумя нулевыми индексами - элемент в первой строке в первом столбце) получает единичное значение. После выполнения команды
value++;
значение переменной value увеличивается на единицу. На следующей итерации цикла это новое значение будет присвоено очередному элементу.
После того как значение элементу присвоено, командой
Console.Write(nums[i, j] + "\t");
оно отображается в консольном окне. Элементы из одной строки массива отображаются в одной и той же строке консольного окна. Для размещения элементов в строке использована табуляция.
Тело внешнего цикла состоит из внутренней конструкции цикла и команды
Console.WriteLine(); .
Внутренний цикл нужен для заполнения строк массива и отображения значений элементов в консольном окне. Когда внутренний цикл завершает работу, благодаря команде
Console.WriteLine();
выполняется переход к новой строке. На этом завершается очередная итерация внешней конструкции цикла. На следующей итерации внешнего цикла снова выполняется внутренняя конструкция цикла, и затем команда
Console.WriteLine(); ,
и так далее, пока не будут перебраны все строки двумерного массива.
На следующем шаге мы закончим изучение этого вопроса .
Как узнать размер двумерного массива по sizeof?
Кто знает, почему sizeof не так работает с двумерными массивами, и как можно вывести размер двумерного массива?
Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Как узнать размер двумерного вектора?
есть квадратная матрица. Для ее хранения создаю динамический массив: double **matrix = new.
Получение размерности двумерного массива через операцию sizeof();
Подскажите пожалуйста форумчане можно ли получить размерность двумерного массива через операцию.
Как узнать размер строки как размер массива
const char* test_str = "01234\x00 789"; //очевидно, что strlen(test_str) == 5; sizeof(test_str).
Как изменить размер двумерного массива?
Вот часть кода, создающая массив. По идее массив должен быть динамическим. Но в C# я не нашел.
7595 / 6418 / 2924
Регистрация: 14.04.2014
Сообщений: 27,946
Сообщение было отмечено SalavatGood как решение
Решение
arr - указатель. Чего ты ожидаешь? Размер содержимого:
sizeof(int) * row * col
8737 / 4315 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
Сообщение от SalavatGood
Кто знает, почему sizeof не так работает с двумерными массивами
потому что ты в своём коде используешь указатель, а вовсе не двухмерный массив.
а на указателе не написано, куда именно он указывает.
Сообщение от SalavatGood
как можно вывести размер двумерного массива?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#include templateclass T> struct count_elements { using type = T; static constexpr size_t count = 1; static constexpr size_t size = sizeof(type); }; templateclass T, size_t N> struct count_elements T[N] > { using type = typename count_elementsT>::type; static constexpr size_t count = N * count_elementsT>::count; static constexpr size_t size = count * sizeof(type); }; templateclass t> void print_count_of_elements(const t& ar) { using type = typename std::remove_reference decltype(ar) >::type; static_assert( std::is_arraytype>::value, "ERROR: expected array" ); constexpr size_t count = count_elementstype>::count; constexpr size_t size = count_elementstype>::size; std::cout <"count = " <", " "sizeof = " <'\n' ; } int main() { int a[10]; int b[10][10]; int c[10][10][10]; print_count_of_elements(a); print_count_of_elements(b); print_count_of_elements(c); }