Указатель на массив C++

203
26 ноября 2016, 19:02

Пусть имеем статический массив:

short tell[20];

Где:

  1. tell - адрес первого элемента массива (2-байтный блок).
  2. &tell - адрес целого массива (40-байтный блок).

И имеется следующая конструкция, указывающая на массив из 20 элементов типа short:

short (*pas)[20] = &tell

Получившимся типом данных переменной pas является тип: short (*)[20]. Собственно вопрос, как создать переменную данного типа, и выделить ей память при помощи операции new?

Пример взят из книги: Стивен Прата - Язык программирования C++ (6 издание). Стр. 182.

Answer 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 <iostream>
#include <iomanip>
#include <algorithm>
#include <numeric>
#include <iterator>
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<short *>( *p + N ), 
               std::reverse_iterator<short *>( *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 
Answer 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;
}
READ ALSO
проблема в указателях

проблема в указателях

здравствуйте, пишу односвязный список, вот кусок:

196
Простейшая задача на алгоритмизацию и SIGSEGV

Простейшая задача на алгоритмизацию и SIGSEGV

Есть простейшая задача: Найти k-ое простое число

188
Разбор рекурсии числа ряда Фибоначчи

Разбор рекурсии числа ряда Фибоначчи

Добрый вечерНе могу понять действия рекурсивной функции при нахождении числа Фибоначчи

246
Приведение const char* к char*

Приведение const char* к char*

Пытаюсь с QByteArray получить указатель на данные с помощью data(), ругается:

216