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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 30, средняя оценка - 4.70
Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 326
#1

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

27.11.2011, 00:54. Просмотров 4293. Ответов 8
Метки нет (Все метки)

Дано:
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 );
Необходимо: в теле шаблона определить размерность массива.
Массивы НЕ инициализированы.

Собственно - можно ли как то различить массивы, поступающие в шаблон?
Или может можно передать массив не через указател, а как-то по другому?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.11.2011, 00:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Определить размерность массива по указателю на него (C++):

Определить размер массива по указателю - C++
Собственно вопрос в следующем: можно ли определить размер выделенного динамически массива по указателю на область памяти? int *ptr =...

Как определить размерность массива - C++
Есть такая задача : Найти общие элементы 2-х массивов и записать результат в файл. Как определить размерность 3-го массива , в...

Определить элементы массива, которые входят в него ровно два раза - C++
Я новичок и у меня не получается решить задачу,возникают трудности с синтаксисом.Кому не сложно сделайте пж,через динамический массив

Считывание элементов массива из файла, где в первой строке можно задавать размерность массива - C++
Разработать программу для работы с одномерным массивом. Ее функции: - считывание элементов массива из файла (txt), где в первой строке...

Размер массива по указателю - C++
Не уверен, что всё правильно понимаю... Про &quot;new&quot; пишут, что оно выделяет необходимое количество памяти и возвращает указатель на начало...

Обход массива по указателю - C++
Доброго времени суток. К примеру, у меня есть такой код: #include &lt;iostream&gt; using namespace std; int main() { int mass; ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BRcr
4008 / 2297 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
27.11.2011, 03:03 #2
C++
1
sizeof( a )/sizeof( a[0][0] )
подойдет?
0
Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 326
27.11.2011, 03:13  [ТС] #3
Цитата Сообщение от BRcr Посмотреть сообщение
C++
1
sizeof( a )/sizeof( a[0][0] )
подойдет?
почти в шаблоне массива "a" не будет, а будет "x" равный int * a. А как взять sizeof(a[0][0]) по указателю я не знаю...
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
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);
}
для динамических массивов нужно будет явно передавать размерность в функцию
1
Сыроежка
Заблокирован
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] );
Тогда внутри функции вы сможете выполнять операции с вашим массивом.
1
BRcr
4008 / 2297 / 155
Регистрация: 03.02.2011
Сообщений: 5,064
Записей в блоге: 10
27.11.2011, 16:53 #6
А если, допустим, мы заранее знаем размерность массива и передаем функции указатель int * - можем ведь мы в этом случае работать с ним как с указателем на массив соответствующей размерности?
1
Lupus
22 / 22 / 1
Регистрация: 13.03.2011
Сообщений: 326
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]" спасибо! То, что надо!
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
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 Посмотреть сообщение
И почему нельзя в качестве параетров принимать интовую размерность массива?
почему же, можно. Но это как минимум нелогично
1
Сыроежка
Заблокирован
27.11.2011, 18:03 #9
Цитата Сообщение от Lupus Посмотреть сообщение
Код прекрасно компилится и на Qt и на Visual Studio, просто я не знал как можно еще передать массив в шаблон. А если бы массив был заранее проинициализирован нулями, можно было каждый раз увеличивать указатель, до встречи не с нулем? Я ведь мог бы тогда узнать точный размер (с большой долью вероятности) массива?
Так и происходит работа с одномерными символьными массивами. Функция strlen как раз и основывается на предположении, что символьный массив заканчиваетя терминальным нулем. Но даже с символьными массивами возникают проблемы, если массив, например, двумерный! Как определить, какой встретившийся 0 задает конец массива? Представьте себе, что вы имеет массив указателей на символьные строки. Как определить его размерность по терминальному 0?! А что если следом за массивом объявляется некий другой указатель? Как узнать, тчто этот указатель не относится к массиву?
Поэтому есть два варианта в общем случае. Это либо передавать указатель на первый элемент массива и вместе с ним передавать размер массива, либо передавать массив по ссылке.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.11.2011, 18:03
Привет! Вот еще темы с ответами:

Получение массива по указателю - C++
Привет, возникла сложность с пониманием как работают указатели, привожу код test(unsigned char testar) { const unsigned char...

Передача массива в функцию по указателю - C++
Помогите с заданием нужно передать массив в функцию по указателю

Создание массива по Указателю на массив - C++
(к сведенью. пользую C++, версия Dev C++ 4.9.9.2) Я создал указатель на массив: char (*e); Мне нужно создать по этому указателю...

Правильное удаление массива по указателю из списка - C++
Не удаляется массив символов в структуре. Комментарий в коде удаления. Структура: struct pointDir { char *data; ...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.11.2011, 18:03
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru