Форум программистов, компьютерный форум CyberForum.ru

Определить размерность массива по указателю на него - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.70
Lupus
 Аватар для Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 319
27.11.2011, 00:54     Определить размерность массива по указателю на него #1
Дано:
C++
1
2
template< typename T >
void info( T * x )
и
C++
1
2
3
4
5
    int a[4][2]; info( a );
    int b[4][4]; info( b );
    int c[1][4]; info( c );
    int d[4][1]; info( d );
    int e[1][1]; info( e );
Необходимо: в теле шаблона определить размерность массива.
Массивы НЕ инициализированы.

Собственно - можно ли как то различить массивы, поступающие в шаблон?
Или может можно передать массив не через указател, а как-то по другому?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
27.11.2011, 03:03     Определить размерность массива по указателю на него #2
C++
1
sizeof( a )/sizeof( a[0][0] )
подойдет?
Lupus
 Аватар для Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 319
27.11.2011, 03:13  [ТС]     Определить размерность массива по указателю на него #3
Цитата Сообщение от BRcr Посмотреть сообщение
C++
1
sizeof( a )/sizeof( a[0][0] )
подойдет?
почти в шаблоне массива "a" не будет, а будет "x" равный int * a. А как взять sizeof(a[0][0]) по указателю я не знаю...
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
27.11.2011, 05:18     Определить размерность массива по указателю на него #4
Цитата Сообщение от Lupus Посмотреть сообщение
Собственно - можно ли как то различить массивы, поступающие в шаблон?
можно, но только статические:
C++
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
#include <iostream>
#include <cstdlib>
 
template <class T, size_t rows, size_t cols>
void fill(T (&arr)[rows][cols])
{
    for(size_t i = 0; i < rows; ++i)
    for(size_t j = 0; j < cols; ++j)
        arr[i][j] = i + j + i * j + 1;
}
 
template <class T, size_t rows, size_t cols>
void dump(const T (&arr)[rows][cols])
{
    for(size_t i = 0; i < rows; ++i, std::cout << std::endl)
    for(size_t j = 0; j < cols; ++j)
        std::cout << arr[i][j] << '\t';
}
 
int main()
{
    int arr[2][3];
 
    fill(arr);
    dump(arr);
}
для динамических массивов нужно будет явно передавать размерность в функцию
Сыроежка
Заблокирован
27.11.2011, 05:27     Определить размерность массива по указателю на него #5
Цитата Сообщение от Lupus Посмотреть сообщение
Дано:
C++
1
2
template< typename T >
void info( T * x )
и
C++
1
2
3
4
5
    int a[4][2]; info( a );
    int b[4][4]; info( b );
    int c[1][4]; info( c );
    int d[4][1]; info( d );
    int e[1][1]; info( e );
Необходимо: в теле шаблона определить размерность массива.
Массивы НЕ инициализированы.

Собственно - можно ли как то различить массивы, поступающие в шаблон?
Или может можно передать массив не через указател, а как-то по другому?
Ваша шаблонная функция объявлена, как принимающая указатель. Указатель не имеет никакого представления о том, передаете ли вы указатель на первый элемент массива, или на одиночный объект. Поэтому, объявив таким образом функцию, вы не сможэете получить информацию о массиве, если таковой передаетя в функцию.
Более того, вы объевляете двумерный массив, а парметр у вас указан как указательна на объект. Поэтому ваш код вообще не должен компилироваться.
Вам следует изменить объявление вашей шаблонной функции и объявить параметр, как ссылку (возможно констатную ссылку, на массив. Например,


C++
1
2
template< typename T, size_t N, size_t M >
void info( T  ( &x )[M][N] );
Тогда внутри функции вы сможете выполнять операции с вашим массивом.
BRcr
 Аватар для BRcr
4003 / 2292 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
27.11.2011, 16:53     Определить размерность массива по указателю на него #6
А если, допустим, мы заранее знаем размерность массива и передаем функции указатель int * - можем ведь мы в этом случае работать с ним как с указателем на массив соответствующей размерности?
Lupus
 Аватар для Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 319
27.11.2011, 17:44  [ТС]     Определить размерность массива по указателю на него #7
Цитата Сообщение от Сыроежка Посмотреть сообщение
Ваша шаблонная функция объявлена, как принимающая указатель. Указатель не имеет никакого представления о том, передаете ли вы указатель на первый элемент массива, или на одиночный объект. Поэтому, объявив таким образом функцию, вы не сможэете получить информацию о массиве, если таковой передаетя в функцию.
Более того, вы объевляете двумерный массив, а парметр у вас указан как указательна на объект. Поэтому ваш код вообще не должен компилироваться.
Вам следует изменить объявление вашей шаблонной функции и объявить параметр, как ссылку (возможно констатную ссылку, на массив. Например,


C++
1
2
template< typename T, size_t N, size_t M >
void info( T  ( &x )[M][N] );
Тогда внутри функции вы сможете выполнять операции с вашим массивом.
Код прекрасно компилится и на Qt и на Visual Studio, просто я не знал как можно еще передать массив в шаблон. А если бы массив был заранее проинициализирован нулями, можно было каждый раз увеличивать указатель, до встречи не с нулем? Я ведь мог бы тогда узнать точный размер (с большой долью вероятности) массива?

Цитата Сообщение от Nameless One Посмотреть сообщение
можно, но только статические:
C++
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
#include <iostream>
#include <cstdlib>
 
template <class T, size_t rows, size_t cols>
void fill(T (&arr)[rows][cols])
{
    for(size_t i = 0; i < rows; ++i)
    for(size_t j = 0; j < cols; ++j)
        arr[i][j] = i + j + i * j + 1;
}
 
template <class T, size_t rows, size_t cols>
void dump(const T (&arr)[rows][cols])
{
    for(size_t i = 0; i < rows; ++i, std::cout << std::endl)
    for(size_t j = 0; j < cols; ++j)
        std::cout << arr[i][j] << '\t';
}
 
int main()
{
    int arr[2][3];
 
    fill(arr);
    dump(arr);
}
для динамических массивов нужно будет явно передавать размерность в функцию
Нубский вопрос - а почему берём в циклах именно size_t? И почему нельзя в качестве параетров принимать интовую размерность массива?
Цитата Сообщение от BRcr Посмотреть сообщение
А если, допустим, мы заранее знаем размерность массива и передаем функции указатель int * - можем ведь мы в этом случае работать с ним как с указателем на массив соответствующей размерности?
Наверное да, ведь указатель должен (должен ли ??) указывать на первый элемент массива, и мы можем увеличивать его до размера массива

P.S. а за функцию типа "T (&arr)[rows][cols]" спасибо! То, что надо!
Nameless One
Эксперт С++
 Аватар для Nameless One
5754 / 3403 / 255
Регистрация: 08.02.2010
Сообщений: 7,393
27.11.2011, 17:54     Определить размерность массива по указателю на него #8
Цитата Сообщение от Lupus Посмотреть сообщение
Нубский вопрос - а почему берём в циклах именно size_t?
потому, что размер массивов не может быть отрицательным, а число типа int - может. Поэтому обычно в качестве индексов, счетчиков циклов, переменных, обозначающих количество чего-либо (элементов в массиве, байтов и т.д.) используют именно переменные беззнакового типа.

Например, описание типа size_t:
Код
size_t Unsigned integer type of the result of the sizeof operator.
Цитата Сообщение от Lupus Посмотреть сообщение
И почему нельзя в качестве параетров принимать интовую размерность массива?
почему же, можно. Но это как минимум нелогично
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2011, 18:03     Определить размерность массива по указателю на него
Еще ссылки по теме:

Как определить размерность массива C++
Размер массива по указателю C++
Определить элементы массива, которые входят в него ровно два раза C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Сыроежка
Заблокирован
27.11.2011, 18:03     Определить размерность массива по указателю на него #9
Цитата Сообщение от Lupus Посмотреть сообщение
Код прекрасно компилится и на Qt и на Visual Studio, просто я не знал как можно еще передать массив в шаблон. А если бы массив был заранее проинициализирован нулями, можно было каждый раз увеличивать указатель, до встречи не с нулем? Я ведь мог бы тогда узнать точный размер (с большой долью вероятности) массива?
Так и происходит работа с одномерными символьными массивами. Функция strlen как раз и основывается на предположении, что символьный массив заканчиваетя терминальным нулем. Но даже с символьными массивами возникают проблемы, если массив, например, двумерный! Как определить, какой встретившийся 0 задает конец массива? Представьте себе, что вы имеет массив указателей на символьные строки. Как определить его размерность по терминальному 0?! А что если следом за массивом объявляется некий другой указатель? Как узнать, тчто этот указатель не относится к массиву?
Поэтому есть два варианта в общем случае. Это либо передавать указатель на первый элемент массива и вместе с ним передавать размер массива, либо передавать массив по ссылке.
Yandex
Объявления
27.11.2011, 18:03     Определить размерность массива по указателю на него
Ответ Создать тему
Опции темы

Текущее время: 11:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru