#cpp #массивы #указатели
Пусть имеем статический массив: short tell[20]; Где: tell - адрес первого элемента массива (2-байтный блок). &tell - адрес целого массива (40-байтный блок). И имеется следующая конструкция, указывающая на массив из 20 элементов типа short: short (*pas)[20] = &tell Получившимся типом данных переменной pas является тип: short (*)[20]. Собственно вопрос, как создать переменную данного типа, и выделить ей память при помощи операции new? Пример взят из книги: Стивен Прата - Язык программирования C++ (6 издание). Стр. 182.
Ответы
Ответ 1
Если у вас есть объявление массива вида T a[N]; где T - это некоторый тип, а N - это число элементов в массиве, то указатель на первый элемент массива будет иметь тип T *. Например T *p = a; После этого определения указатель p указывает на первый элемент массива a. Чтобы выделить динамически память для массива, аналогичного массиву, определенному выше, вы можете записать T *p = new T[N]; Здесь элемент массива имеет тип T, а p как и выше показывает на первый элемент динамически выделенного безыменного массива.. Теперь представим, что T это алиас для типа short[20], например typedef short T[20]; Тогда ранее показанные объявления для указателя могут быть записаны как T *p = &a; и T *p = new T[1]; Если снова вернуться к исходному типу short[20], то получим short( *p )[20] = &a; и short( *p )[20] = new short[1][20]; Последнее предложение означает, что выделяется массив из одного элемента (вы можете выделять массив из произвольного числа элементов в соответствии с вашей задачей), элементами которого в свою очередь являются массивы из 20 элементов типа short. Имейте в виду, что когда используется так называемая арифметика указателей, то значение указателя меняется на значение кратное sizeof( T ) Поэтому если вы, например, объявите указатель как short( *p )[20] = &a; где T эквивалентно short[20], то после применения, например, инкремента к этому указателю ++p; указатель будет содержать адрес сразу же после последнего элемента массива a. Ну, и напоследок пример работы с таким указателем. #include#include #include #include #include const size_t N = 20; short ( * create_2D_array( size_t n ) )[N] { short ( *p )[N] = new short[n][N]; return p; } int main() { short a[N]; std::iota( std::begin( a ), std::end( a ), 1 ); for ( short x : a ) std::cout << std::setw( 2 ) << x << ' '; std::cout << std::endl; short ( *p )[N] = create_2D_array( 1 ); std::iota( std::reverse_iterator ( *p + N ), std::reverse_iterator ( *p ), 1 ); for ( short x : *p ) std::cout << std::setw( 2 ) << x << ' '; std::cout << std::endl; std::cout << std::endl; std::swap( a, *p ); for ( short x : a ) std::cout << std::setw( 2 ) << x << ' '; std::cout << std::endl; for ( short x : *p ) std::cout << std::setw( 2 ) << x << ' '; std::cout << std::endl; delete [] p; return 0; } Вывод программы на консоль 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Ответ 2
Вообще-то и tell, и &tell[0], и &tell - это все одна и та же сущность, адрес, с которого начинается блок памяти, выделенный для массива... typedef short array[20]; short * a = new array; Здесь мы описываем тип массива из 20 short, и создаем его динамически, возвращая указатель на начало блока с ним. Работаем с ним, как с обычным массивом, типа for(short i = 0; i < 20; ++i) { a[i] = i; }
Комментариев нет:
Отправить комментарий