Указатели C ++ - объявление конфликта и указатель на указатель - PullRequest
0 голосов
/ 27 января 2011

Когда я сделал следующие заявления:

int b;
int c;
int *b;
int *c;

Я получил следующий вывод при компиляции:

enter image description here

Примечание: я использую консоль Cygwin, поэтому не могу скопировать и вставить вывод

Итак, делаем ли мы здесь вывод, что когда мы объявляем переменную pointer, это одновременно обычная переменная, которая может хранить данные самостоятельно? Другими словами, ячейка памяти, которая имеет адрес и значение?

Я спрашиваю об этом, так как хочу попробовать pointer-to-pointer?

Если у меня, например, `int ** c ', как я могу заставить его содержать следующее:

Значение (b) / Адрес (b) / Значение (a) / Адрес (a)

И есть ли int ***c?

Большое спасибо.

Ответы [ 6 ]

2 голосов
/ 27 января 2011

Вы объявляете две переменные с одинаковым именем в одной и той же области видимости.Это не разрешено.

1 голос
/ 27 января 2011

Итак, делаем ли мы здесь вывод, что когда мы объявляем переменную-указатель, в то же время это обычная переменная, которая может хранить данные самостоятельно? Другими словами, ячейка памяти, которая имеет адрес и значение?

Да, это точно. Указатель - это переменная, которая содержит адрес. В вашем коде вы объявили две переменные с одинаковым именем (в одном и том же пространстве имен). Это не разрешено.

1 голос
/ 27 января 2011

Давайте научим вас некоторым основам.

int b;

b - это переменная типа int, которая содержит целочисленное значение, например 3, -28, 49382

int *b;

b - это переменная типа int *, которая содержит указатель. Это может быть NULL или указатель на переменную, которая содержит int. Поскольку это не const int *, вы можете писать в него и читать из него. Вы можете перемещать его так, чтобы он указывал на различные переменные типа int, если у них нет квалификаторов const (или volatile). Вы также можете использовать указатель, чтобы указать на некоторую динамически распределенную память или на начало массива таких (например, int *b = new int; или int *b = new int[N]) или на местоположение в статическом массиве.

Таким образом, b является либо целочисленной переменной, либо переменной-указателем. Это не может быть и то и другое.

Чтобы ответить на ваш последний пункт, да, у вас могут быть указатели на указатели, и нет никаких ограничений в глубине, хотя, очевидно, станет нечитаемым иметь int *******p

1 голос
/ 27 января 2011

Да, указатель - это обычная переменная, которая имеет значение и занимает некоторую память.Причина ошибки, которую вы получаете, не имеет к этому никакого отношения, но просто потому, что вы пытаетесь объявить две разные вещи с одним и тем же именем.

И, конечно, вы можете иметь указатели на указатели или даже указатели науказатели на указатели или даже больше уровней этого безумия.Единственный вопрос будет в том, как их использовать.Я могу представить себе множество вариантов использования указателей на указатели.Для большего количества уровней я могу только представить себе вид использования «массива массивов», но это все же что-то.

Но то, что вы не должны делать, это хранить значения неправильного типа в переменной.Если у вас есть указатель на указатель, вы должны хранить там адрес некоторого указателя (правильного типа), ничего больше, например:

int a;
int *b = &a;
int **c = &b;

В этом примере было бы абсолютно неправильно хранитьзначение a в c, хотя это возможно на платформах, где int и указатели имеют одинаковый размер.Но это все равно, что хранить текстовую строку в - абсолютно бессмысленно и опасно.

1 голос
/ 27 января 2011

Указатель - это переменная, в которой хранится адрес памяти.Итак, да, у него есть значение и адрес памяти.

int *p = 0; int **pp = &p.Это верно, p - это указатель, который хранится в стеке и имеет значение 0 и некоторый адрес памяти;pp также выделяется в стеке, имеет другой адрес памяти и содержит адрес памяти p.

Адрес памяти должен храниться где-то и занимать фиксированный объем памяти.Например, адрес памяти, в зависимости от вашей реализации, может храниться в четырех байтах.В этом случае у вас есть

  • sizeof(char) = 1
  • sizeof(char *) = 4
  • sizeof( любой другой тип указателя, включая указатель науказатель ) = 4.

, поэтому, выполнив reinterpret_cast s, ваш указатель может сохранить любой тип, который занимает до четырех байтов.Но почему вы хотите это сделать?

1 голос
/ 27 января 2011
int b;
int *b; 

Очевидно, это объясняет ошибку, которую вы видите.

Как вы можете объявить две переменные с одинаковым именем?Две переменные с одинаковым именем вызывают конфликт!

То же самое и для этого объяснения:

int c;
int *c;

Две переменные с одинаковым именем, следовательно, конфликт!

...