Указатели в с ++ - PullRequest
       8

Указатели в с ++

1 голос
/ 12 марта 2011

Я новичок в C ++, и я нашел этот код в учебнике. Я озадачен, чтобы найти двойные звезды вместо одной звезды, используемой для определения указателя. Это замена для двумерного массива? Если да, то как?

Например:

int* A = new int[5];

делает полосу массива, как это происходит в int **A?

#include <iostream>
using namespace std;

int main () {

 int **A;
    A = new int*[10] ;

    for (int j=0; j<20; j++) 
       A[j] = new int[20] ;

    for (int i=0; i<10; i++) 
       for (int j=0; j<20; j++) 
        A[i][j] = (i+1)*(j+1);


    for (int i=0; i<10; i++) {
       for (int j=0; j<20; j++) 
        cout << A[i][j] << " ";
       cout << endl;
    }

    cout << endl;

} 

Ответы [ 6 ]

4 голосов
/ 12 марта 2011

Да.Это двумерный массив: точнее, указатель на указатель!

И вы должны освободить его, как только закончите.Вот как вы должны удалить его:

for (int j=0; j<20; j++) 
   delete[] A[j];
delete[] A;

Хорошо, что вы экспериментируете с ним.Было бы также хорошо, если бы вы также познакомились с std::vector и поэкспериментировали с ним.


Пример std::vector

#include <vector>

std::vector<std::vector<int> > A(10, vector<int>(20));

for (int i=0; i<10; i++) 
   for (int j=0; j<20; j++) 
    A[i][j] = (i+1)*(j+1);

for (int i=0; i<10; i++) {
   for (int j=0; j<20; j++) 
    cout << A[i][j] << " ";
   cout << endl;
}

То есть, если вы используетеstd::vector, тогда вам не нужно беспокоиться о выделении и освобождении памяти!

Демонстрация на ideone: http://ideone.com/LEOBe

3 голосов
/ 12 марта 2011

int **A; означает, что это указатель на указатель.Это часто используется для представления двумерного массива.В вашей программе -

int *A; A = new int[10] ;

for (int j=0; j<20; j++) 
   A[j] = new int[20] ; // A[j] means dereferencing to the location itself. So, it should hold `int`
                        // as stated but not `int*` that is returned by new operator.

A - это указатель, который указывает 10 областей памяти, которые могут содержать int.И когда вы говорите, A[j], вы на самом деле разыменовываете местоположение.Таким образом, он содержит int, а не int*.Кроме того, существует переполнение, поскольку количество местоположений A указывает на 10 , но не 20 мест памяти.

Редактировать 1: ОП отредактировал программу.Это не то же самое, что было раньше.

Теперь с программой все в порядке, за исключением возврата ресурсов обратно в бесплатное хранилище.

int **A;
A = new int*[10] ;

A - указатель на указатель.Таким образом, a должен содержать адрес указателя или массив, который может содержать адрес указателей.Так,

A = new int*[10] ;

A содержит начальный адрес массива указателей, размер которого 10.Теперь это все еще не так.

for (int j=0; j<20; j++) 
   A[j] = new int[20] ; // Because `A[j]` is invalid from 10-19. There is no such index where A[j] can dereference to. So, j should run from 0 to 10 instead.

С этим исправлено -

A[j] = new int[20] ;

Теперь каждый указатель указывает на 20 int мест.Итак, в массиве 10 * 20 элементов.

Эта диаграмма размерного массива 2 * 3 должна дать вам представление.Кроме того, вы должны рассмотреть ответ @Nawaz на освобождение массива, поскольку ресурсы управляются программистом.

2*3 Array Lay Out

2 голосов
/ 12 марта 2011

Первое, что вам нужно знать, это разница между указателем и массивом в C и C ++.Массив type array[size] - это размер последовательных ячеек размера данных (типа).Указатель - это переменная, которая содержит адрес.Путаница возникает из-за того, что указатель используется для хранения адреса первой ячейки динамически размещаемого массива (malloc в C, new [] в C ++).

Итак, в чем разница между int array[10] и int* pi?массив - это область памяти размером 10 дюймов, а pi - это переменная, которая содержит адрес типа int.

Чтобы объявить массив двух измерений, вы можете ввести: int array2d[10][10] или вы можете объявить указательна указатель ", такой как int** ppi.Не забывайте, что если вы используете второй вариант, вам нужно выделить как первое (массив указателей), так и второе (ваш фактический массив значений).

2 голосов
/ 12 марта 2011

Это указатель на указатель.В данном случае это двумерный массив.

1 голос
/ 12 марта 2011

Чтобы создать 2D-массив, вы можете либо создать массив массивов (в результате получается зубчатый массив), либо вы можете создать 1D-массив и ссылаться на него таким образом, чтобы он был похож на 2D-массив (этот второй методэто немного неловко).

// array of arrays
int **A = new int*[5]; // an array of potentially 5 int arrays
for( int i = 0; i < 5; ++i)
{
    A[i] = new int[5];
}

// access the array using two brackets
A[0][0] = 1; // element in the zeroth row and zeroth col = 1
A[1][0] = 2; // element in the first row and zeroth col = 2
// you must delete the inside arrays first before deleting the array of arrays
for(int i = 0; i < 5; ++i)
{
    delete[] A[i];
}
delete[] A;
1 голос
/ 12 марта 2011

Два запуска означают, что это указатель на указатель.Эта строка:

  A = new int*[10];

Распределяет пространство для значений 10 int*.Позже каждое из этих int* значений инициализируется с помощью:

   for (int j=0; j<20; j++) 
       A[j] = new int[20];

Результатом является «зубчатый массив» или массив массивов.Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...