powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / как определить размерность массива в C++?
17 сообщений из 17, страница 1 из 1
как определить размерность массива в C++?
    #33110601
Фотография Фрилансер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
После трехлетнего перерыва пришлось вновь столкнуться с сями. Столько интересного! :)
Возник вопрос: можно ли определить размерность (кол-строк и столбцов) двумерного массива?
И еще один... А как передать в функцию произвольный двумерный массив?
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33110647
Guest12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
std::vector ?
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33110664
Фотография Фрилансер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не совсем понимаю...
вектор - это класс векторов? но мне ведь нужен обычный массив...
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33110688
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ФрилансерВозник вопрос: можно ли определить размерность (кол-строк и столбцов) двумерного массива?
Нет. Двумерный массив в принципе ничем не отличается от одномерного. Когда ты задаешь i=arr[x,y] компилятор расшифровывает это в формулу i=*(arr+x*N+y) где N - длина строки.
Обычно делают так:
#define N 10
#define M 15
int arr[N, M];
for (i=0; i<N; i++) {}

ФрилансерИ еще один... А как передать в функцию произвольный двумерный массив?
Имя массива любой размерности это константный указатель на первую ячейку массива. Функция должна принимать указать определенного типа, а в вызове просто указываешь имя массива. Функция сама должна знать сколькомерный он. Но с точки зрения компилятора он всегда будет одномерным.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
int foo(int *arr, int RowToCount, int SizeOfRow) {
  int sum, i;
  sum =  0 ;
  for(i = RowToCount*SizeOfRow; i < (RowToCount+ 1 )*SizeOfRow; i++) {
    sum += arr[i];
  }
  return sum;
}

int a1[ 3 , 3 ] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 };
printf("sum of second row is: %d\n", foo(a1,  1 ,  3 ));
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33110692
Фотография Землекоп
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Специально для любителей C++ и STL сделал пример. Я думаю, что он отвечает на все вопросы.

Код: plaintext
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 <vector>
#include <iostream>

template <typename T>
class array2
{
public:
  array2(){};
  array2(int r, int c)
  {
	rows=r;
	cols=c;
    for(int i= 0 ; i<rows; ++i)
    {
      data.push_back(std::vector<T>(cols));
    }
  }
  

  inline std::vector<T> & operator[](int i) { return data[i]; }

  inline const std::vector<T> & operator[] (int i) const { return data[i]; }
  int rows, cols;
private:
  std::vector<std::vector<T> > data;  
};
  
void myprint(array2<int> &a)
	{
	for(int i= 0 ; i<a.rows; ++i)
		{
		for(int j= 0 ; j<a.cols; ++j)
			{
			std::cout << a[i][j] <<"  ";
			}
		std::cout << std::endl;
		}
	}
int main()
 {
 array2<int>a( 10 , 3 );
 for(int i= 0 ; i< 10 ; ++i)
   for(int j= 0 ; j< 3 ; ++j)
     {
     a[i][j] = i+j;
     }

 myprint(a);
 return  0 ;
 }


...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33110811
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlКогда ты задаешь i=arr[x,y] компилятор разве не напишет C++Builder[C++ Error] Unit1.cpp(15): E2290 Array bounds missing ] ?
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33111145
Интегратор
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ФрилансерПосле трехлетнего перерыва пришлось вновь столкнуться с сями. Столько интересного! :)
Возник вопрос: можно ли определить размерность (кол-строк и столбцов) двумерного массива?
И еще один... А как передать в функцию произвольный двумерный массив?

Лучше воспользуйся boost::array ;)
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33112452
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlИмя массива любой размерности это константный указатель на первую ячейку массива. Функция должна принимать указать определенного типа, а в вызове просто указываешь имя массива. Функция сама должна знать сколькомерный он. Но с точки зрения компилятора он всегда будет одномерным.

Нет, массив и указатель это совершенно разные типы, которые не имеют ничего общего.
Тем не менее, компилятор всегда заменяет тип аргумента функции с "массив" на "указатель на элемент", сохраняя тип элемента. Так что если бы мы написали
Код: plaintext
1.
2.
3.
void foo(int arg[ 10 ][ 10 ]){
...
}
Компилятор заменит тип arg c int[10][10] на тип *int[10].

Но автоконверсия с типа на тип не означает идентичности типов. int в double тоже автоконвертируется, и что? int - это double?

Тем не менее массивы и указатели имеют разный linkage, так что мы не можем написать в *.h файле
Код: plaintext
1.
extern char foo[];
а в *.cpp
Код: plaintext
1.
char *foo = "a string";
Выскочит ошибка линковки, поскольку линкер не найдет символа foo, имеющего тип char[].

По поводу топика...
В общем, на эту тему есть два подхода - Pure C и C++

C не проверяет границы массива, так что можно нахимичить такую вешь:

struct IntegerArray {
int elementCount;
int arr[1];
};

Нам нужен массив со 100 элементами

struct IntegerArray* ia = (struct IntegerArray*)_alloca(sizeof(struct IntegerArray) + sizeof(int) * 100 )
ia->elementCount = 100;

Поскольку С не проверяет выхода за границы массива мы можем свободно юзать элементы с индексами 0 - 99, ибо свободная память есть. Для штампования таких структур можно написать макрос.

В С++ более предпочтителен строгий контроль, и лучше использовать чего - то типа std::vector, оверхед будет небольшой.
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33112753
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас Барабас White OwlКогда ты задаешь i=arr[x,y] компилятор разве не напишет C++Builder[C++ Error] Unit1.cpp(15): E2290 Array bounds missing ] ?
Это смотря какой компилятор. Большинство умеет работать с двойным синтаксисом. То есть i=arr[x,y] полностью равняется i=arr[x][y]. Но некоторые действительно предпочитают более стандартный синтаксис i=arr[x][y].
А у некоторых (например у VC7) вообще каша - иногда они съедают arr[x,y] иногда ругаются. Пока я так и не понял в каком случае оно ругается а когда нет :)

Сергей ИльичНет, массив и указатель это совершенно разные типы, которые не имеют ничего общего.
Да??? :)

Сергей Ильич
Тем не менее массивы и указатели имеют разный linkage, так что мы не можем написать в *.h файле
extern char foo[];
а в *.cpp
char *foo = "a string";
Выскочит ошибка линковки, поскольку линкер не найдет символа foo, имеющего тип char[].
Естественно. Потому что в заголовке ты объявил КОНСТАНТНЫЙ указатель. А в коде, ты его пытаешься изменить. А вот например
Код: plaintext
1.
2.
3.
extern char foo[];
char foo[ 10 ]="abcdefghij";
char *foo1;
foo1 = foo;
отработает без проблем, а если посмотришь на ассемблерный код - обнаружишь простое присвоение :)

Сергей ИльичC не проверяет границы массива, так что можно нахимичить такую вешь:
Намного чаще такие "безразмерные" массивы объявляют так:
Код: plaintext
1.
2.
3.
struct IntegerArray {
  unsigned int elementCount;
  int arr[ 0 ];
};
Ноль - потому что считать реальный размер структуры потом будет проще.
А твоя формула расчета на самом деле выделит память не под сто элементов, а под сто один :)
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33112952
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quote White Owl] Естественно. Потому что в заголовке ты объявил КОНСТАНТНЫЙ указатель. А в коде, ты его пытаешься изменить.
[/quote]
Ни фига. extern означает, что где-то есть такой символ, но не в этом модуле.
Компилятор пожимает плечами и делегирует работу линкеру.

extern char foo[]
означает что в в каком то модуле есть глобальный массив foo.

char foo[] = "a string";
В данном случае отработает нормально, т.к. foo - массив
char *foo = "a string";
не отработает, т.к. foo - указатель.

http://www.prolegomena.net/Cstuff/ptrs/ptr.html

[quote White Owl]
> Между массивом и указателем нет ничего общего
Да??? :)
[/quote]

А что общего между пачкой значений одинакового типа(массив) и значением, содержащин некий адрес (указатель)?

[quote White Owl]
Намного чаще такие "безразмерные" массивы объявляют так:

struct IntegerArray {
unsigned int elementCount;
int arr[0];
};

Ноль - потому что считать реальный размер структуры потом будет проще.
А твоя формула расчета на самом деле выделит память не под сто элементов, а под сто один :)
[/quote]
Микрософт в почему-то предпочитает вариант с одним элементом. Например, в структуре BITMAPINFO. Влом глядеть в стандарт, может быть в C89 массивы нулевого размера и запрещены.

Лучше пускай четыре лишних байта лягут в стек, от греха подальше.
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33112977
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты эта... кнопочкой "предварительный просмотр" пользуйся, да. А то читать тебя очень затруднительно.

Сергей ИльичНи фига. extern означает, что где-то есть такой символ, но не в этом модуле. Компилятор пожимает плечами и делегирует работу линкеру.
Несовсем так. extern действительно означает что где-то, в каком-то из модулей есть переменная с таким-то именем, такого-то типа. И ее надо будет положить в сегмент DATA. Она может быть фактически объявленая в том же самом или другом модуле что и extern. В приниципе extern можно использовать для предопределения переменных.

Сергей Ильичextern char foo[]
char *foo = "a string";
не отработает, т.к. foo - указатель.
Нет. Это не отработает, потому в первой строке утверждается что где то будет объявлен константный указатель. А фактически объявляется переменная. Ты читать умеешь? Третий раз уже пишу - имя массива это КОНСТАНТНЫЙ указатель. Не переменная указатель, а константа. Ты не можешь ее куда-то перенаправить. А в этом примере ты как раз и делаешь перенаправление.

Сергей ИльичА что общего между пачкой значений одинакового типа(массив) и значением, содержащин некий адрес (указатель)?
Значение ничего не может содержать. Это во первых.
А во вторых.... ну как тебе объяснить.... разве что читать длинную лекцию про сегменты кода и памяти? :) В общем, пачка значений где-то находится, так? Значит у нас есть адрес первого элемента этой пачки (иначе мы до нее никогда не доберемся). Как этот адрес в нашей программе обозначен? Вот как раз через имя пачки значений :)

Сергей ИльичЛучше пускай четыре лишних байта лягут в стек, от греха подальше.
Какой стек, если ты память динамически выделяешь? :)
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33113479
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl
Несовсем так. extern действительно означает что где-то, в каком-то из модулей есть переменная с таким-то именем, такого-то типа. И ее надо будет положить в сегмент DATA. Она может быть фактически объявленая в том же самом или другом модуле что и extern. В приниципе extern можно использовать для предопределения переменных.

А почему в BSS не положить? Некоторые компиляторы кладут неинициализированный глобальный массив в .bss , некоторые - в .data . В результате иногда получается, что int foo[100][100] превратился в ~40k нулей в бинари.

White Owl
Сергей Ильичextern char foo[]
char *foo = "a string";
не отработает, т.к. foo - указатель.
Нет. Это не отработает, потому в первой строке утверждается что где то будет объявлен константный указатель. А фактически объявляется переменная. Ты читать умеешь? Третий раз уже пишу - имя массива это КОНСТАНТНЫЙ указатель. Не переменная указатель, а константа. Ты не можешь ее куда-то перенаправить. А в этом примере ты как раз и делаешь перенаправление.

Какое перенаправление?

Код: plaintext
1.
2.
3.
extern char foo[];

char foo[] = "a string";
Это работает

Код: plaintext
1.
2.
3.
extern char *const foo;

char *const foo = "a string";
Это тоже работает. Заметь - указатель константный.

Код: plaintext
1.
2.
3.
extern char foo[];

char *const foo = "a string";
Это не работает.

White Owl
Сергей ИльичА что общего между пачкой значений одинакового типа(массив) и значением, содержащин некий адрес (указатель)?
...
В общем, пачка значений где-то находится, так? Значит у нас есть адрес первого элемента этой пачки (иначе мы до нее никогда не доберемся). Как этот адрес в нашей программе обозначен? Вот как раз через имя пачки значений :)

А почему тогда структура - это не указатель? Ведь она тоже где-то лежит?

White Owl
Сергей ИльичЛучше пускай четыре лишних байта лягут в стек, от греха подальше.
Какой стек, если ты память динамически выделяешь? :)
_alloca() выделяет память в стеке. Очень многие реализации С предоставляют возможность выделять память в стеке.
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33113712
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlЭто смотря какой компилятор. Большинство умеет работать с двойным синтаксисом. То есть i=arr[x,y] полностью равняется i=arr[x][y]. Но некоторые действительно предпочитают более стандартный синтаксис i=arr[x][y].


Заявление о двойном синтаксисе является ... (как бы это помягче сказать). В C/C++ есть оператор "запятая". Результатом выполнения выражения x, y, z является z, поэтому:

Код: plaintext
1.
2.
int arr[ 10 ,  15 ];
arr[ 0 ,  1 ] =  100 ;
для любого компилятора тождественно
Код: plaintext
1.
2.
int arr[ 15 ];
arr[ 1 ] =  100 ;

Удачи!
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33113715
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl Сергей ИльичНет, массив и указатель это совершенно разные типы, которые не имеют ничего общего.
Да??? :)


Да, массив приводится к указателю на свой первый элемент, но массив и указатель это две разные сущности. Массив самостоятельный элемент языка.

авторТретий раз уже пишу - имя массива это КОНСТАНТНЫЙ указатель

Не показывайте свое невежество - вы наговорили столько ерунды, что можно только развести руками.
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33114464
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сергей ИльичА почему в BSS не положить? Некоторые компиляторы кладут неинициализированный глобальный массив в .bss , некоторые - в .data .
Ну да, это зависит от компилятора. Может быть и там и там или даже на стеке.

Сергей ИльичКакое перенаправление?
Виноват, не "перенаправление", а "переопределение". Опечатался в пылу спора :)

Сергей ИльичА почему тогда структура - это не указатель? Ведь она тоже где-то лежит?
А имя структуры это тоже указатель :) Все точно так же как и с объявлеными в коде массивами.
Код: plaintext
1.
2.
3.
4.
5.
typedef struct {
  int x,y;
} POINT;

POINT p, *pp;
pp = p;
Работает без малейших проблем. А вот p=pp уже даст ошибку компилятора. Все точно так же как и с массивами.
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33114524
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ой как меня щас будут пинааать.... :)
...
Рейтинг: 0 / 0
как определить размерность массива в C++?
    #33114620
Фотография Сергей Ильич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owlой как меня щас будут пинааать.... :)
К сожалению, тема разошлась с той, ради чего я начинал этот спор.
А ради чего я начинал, я забыл. Так что расслабься.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / как определить размерность массива в C++?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]