2015-12-25 4 views
4

У меня есть несколько вопросов. Это не домашнее задание. Я просто хочу понять лучше.Попытка понять * и & в C++

Так что, если у меня есть

int * b = &k;

  1. Тогда k должно быть целым числом, а b является указателем на k «s положение в памяти, правильно?

  2. В чем заключается «тип данных» b? Когда я вывожу его, он возвращает такие вещи, как 0x22fe4c, который я предполагаю шестнадцатеричным для позиции памяти 2293324, правильно?

  3. Где именно находится позиция памяти '2293324'? «Куча»? Как я могу вывести значения, например, в позиции памяти 0, 1, 2 и т. Д.?

  4. Если выходной я *b, это то же самое, как вывод k непосредственно, потому что * каким-то образом означает, что значение указывает b. Но это выглядит иначе, чем объявление b, которое было объявлено int * b = k, поэтому, если * означает «значение», то это не значит «объявить b на значение k? Я знаю, что это не так, но я все еще хочу понять именно то, что это означает, что язык мудрого.

  5. Если я выход &b, это фактически возвращая адрес самого указателя, и не имеет ничего общего с k, правильно?

  6. Я также могу сделать int & a = k;, который кажется как это делается int a = k;. Как правило, нет необходимости использовать & таким образом?

+0

@intboolstring Это не дубликат, так как некоторые из моих вопросов не в этой связи. –

+1

Ну, вы должны были поставить те, которые там не рассматривались. – intboolstring

+0

Также, согласно комментариям в этой ссылке, некоторая информация неточна. Я не хочу потенциально учиться неточным вещам. –

ответ

1

1- Да.

2- Не существует «базового типа данных». Это указатель на int. Это его природа. Это тип данных как «int» или «char» для c/C++.

3- Вы даже не должны пытаться использовать выходные значения памяти, которые не были выделены вами. Это ошибка сегментации. Вы можете попробовать сделать b-- (что делает «b» указывать на «int» перед фактической позицией. По крайней мере, для вашей программы считается, что это int.)

4- * с указателями является оператором , С любым типом данных это другой тип данных. Это как символ =. Он имеет одно значение, когда вы ставите == и другое, когда вы ставите =. Символ не обязательно соотносится с этим значением.

5- & b - направление b. Это связано с k, а b указывает на k. Например, если вы делаете (** (& b)), вы делаете значение, указанное значением, указанным в направлении b.Это k. Если вы не изменили его, конечно.

6- int & a = k означает, что направление a направлено в направлении k. a будет, на всякий случай, k. Если вы сделаете a = 1, k будет равно 1. Они будут оба ссылками на одно и то же.

Открыт для исправления, конечно. Вот как я это понимаю.

+0

Is (** (& b)) то же, что и * b? Как я интерпретирую ** в этой ситуации? –

+0

Да, они такие же. ** будет означать два оператора. То есть, им нужен «указатель на указатель» после их работы. И они возвращают значение, указанное значением, указанным значением, переданным им. Соблюдайте беспорядок, но вы можете понять его как '* (* (& b))'. – Desaroll

+0

Может ли он пройти бесконечно глубоко? ******* & б? –

1

Есть комплименты друг другу. * либо объявляет указатель, либо разыгрывает его. & либо объявляет ссылку (lvalue), либо берет адрес объекта или встроенного типа. Поэтому во многих случаях они работают в тандеме. Чтобы сделать указатель объекта, вам нужен его адрес. Чтобы использовать указатель в качестве значения, вы разыскиваете его.

1

3 - Если k является локальной переменной, она находится в стеке. Если k - статическая переменная, она находится в разделе данных программы. То же самое относится к любой переменной, включая b. Указатель указывает на некоторое место в куче, если используются новые, malloc(), calloc(), .... Указатель указывает на стек, если используется alloca() (или _alloca()) (alloca() аналогично использованию массива локальной переменной длины).

Пример с участием массив:

int array_of_5_integers[5]; 
int *ptr_to_int; 
int (*ptr_to_array_of_5_integers)[5]; 

    ptr_to_int = array_of_5_integers; 
    ptr_to_array_of_5_integers = &array_of_5_integers; 
2

В ответ на вопросы:

  1. Да, b является pointer в k: Он содержит адрес k в куче, но не значение k.

  2. «тип данных» из b является int: По сути, это говорит о том, что адрес, по которому b точки является адресом из int, но это не имеет ничего общего с самой b: b только адрес к переменной.

  3. Не пытайтесь вручную выделять память на определенный адрес: память распределяется на основе размера объекта, который был инициализирован, поэтому адреса памяти расположены на расстоянии друг от друга, чтобы оставить место для объектов, которые будут расположены рядом друг с другом в память, поэтому ручное изменение это плохая идея.

  4. * В данном случае это де-ссылка на b. Как я уже сказал, b является адресом памяти, но *b - это то, что по адресуb. В этом случае это k, поэтому управление *b - это то же самое, что и управление k.

  5. Исправить, &b - это адрес указателя, который отличается от k и b.

  6. Использование int & a = k создает ссылку наk, которые могут быть использованы, как будто это само по себе k. Этот случай тривиален, однако ссылки идеальны для функций, которые должны изменять значение переменной, которая выходит за рамки самой функции.

Например:

void addThree(int& a) { 
    a += 3; 
} 

int main() { 
    int a = 3; //'a' has a value of 3 
    addThree(a); //adds three to 'a' 
    a += 2; //'a' now has a value of 8 

    return 0; 
} 

В приведенном выше случае, addThree принимает ссылку на a, а это означает, что значение int a в main() манипулируют непосредственно функции.

Это также будет работать с указателем:

void addThree(int* a) { //Takes a pointer to an integer 
    *a += 3; //Adds 3 to the int found at the pointer's address 
} 

int main() { 
    int a = 3; //'a' has a value of 3 
    addThree(&a); //Passes the address of 'a' to the addThree function 
    a += 2; //'a' now has a value of 8 

    return 0; 
} 

Но не с копией возведенных аргумента:

void addThree(int a) { 
    a += 3; //A new variable 'a' now a has value of 6. 
} 

int main() { 
    int a = 3; //'a' has a value of 3 
    addThree(a); //'a' still has a value of 3: The function won't change it 
    a += 2; //a now has a value of 5 

    return 0; 
} 
Смежные вопросы