2010-06-11 2 views
0

хорошо, я смотрю на код здесь, и идея трудно понять.Путаница о указателях и адресах их памяти

#include <iostream> 
using namespace std; 
class Point 
{ 
public : 
    int X,Y; 
    Point() : X(0), Y(0) {} 
}; 

void MoveUp (Point * p) 
{ 
    p -> Y += 5; 
} 

int main() 
{ 
    Point point; 
    MoveUp(&point); 
    cout << point.X << point.Y; 
    return 0; 
} 

Хорошо, так что я считаю, что класс создается и X и Y были объявлены и они помещаются внутри конструктора

создан метод и аргумент точки * р, что означает, что мы будут придерживаться указателя конструктора внутри функции;

Теперь мы создаем объект, называемый точкой, затем вызываем наш метод и помещаем в него адрес указателя?

не является адресом указателя только для номера памяти, такого как 0x255255?

и почему не было объявлено?

(int * p = Y) 

Что такое память? что его можно использовать в качестве аргумента?

+11

Убедитесь, что ваш компьютер находится на ровной поверхности. Весь ваш код, похоже, скользнул влево от экрана. –

+1

Да, я знаю, я живу в Калифорнии, что ты ожидаешь? – TimothyTech

+0

Для чего это стоит, предпочитайте ссылки на указатели. Ссылки - это псевдонимы, и в большинстве случаев вы хотите использовать псевдоним переменной, а не указывать на нее. Ваша функция будет 'void MoveUp (Point & p) {p.Y + = 5; } ', и вы называете его' MoveUp (point); '; теперь 'p' псевдонимы' point'. С вашим кодом рассмотрите, что происходит с 'MoveUp (0);'. – GManNickG

ответ

9

pбыл объявлен.

void MoveUp (Point * p) 
{ 
    p -> Y += 5; 
} 

это функция, которая будет принимать указатель на Point и добавить 5 к его значению Y. Это ничем не отличается следующим:

void f(int n) { 
    printf ("%d\n", n); 
} 
: 
int x = 7; 
f(x); 

Вы не сказали бы n не был определен в этом случае. То же самое для p в вашем случае.

Некоторые комментарии в коде поможет:

#include <iostream> 
using namespace std; 
class Point 
{ 

public : 
    int X,Y; 
    Point() : X(0), Y(0) {}  // Constructor sets X and Y to 0. 
}; 

void MoveUp (Point * p)   // Take a Point pointer p. 
{ 
    p -> Y += 5;     // Add 5 to its Y value. 
} 
int main() 
{ 
    Point point;     // Define a Point. 
    MoveUp(&point);    // Call MoveUp with its address. 
    cout <<point.X << point.Y; // Print out its values (0,5). 
    return 0; 
} 

Указатели просто уровень косвенности. В коде:

1 int X; 
2 int *pX = &X; 
3 X = 7; 
4 *pX = 7; 

Влияние линий 3 и 4 идентично. Это потому, что pX является указателем на X, так что *pX, содержание pX, на самом деле X.

В вашем случае, p->Y такая же, как (*p).Y или Y членом класса, на который указывает p.

+0

так что значит & точка равная? делает ли C++ адрес и полностью удаляет экземпляр конструктора или класса? – TimothyTech

+0

'& point' является указателем на' point' (ISO не указывает, что это адрес, но он обычно есть). Здесь вы смешиваете семантику C и C++. Как правило, вы будете 'p.MoveUp()' и будете манипулировать этим -> Y', а скорее способом старой школы, который здесь делается. – paxdiablo

+0

& point = индекс в массив огромных массивов ОЗУ, в котором вы можете найти экземпляр Point. Конечно, на самом деле это не так, как работают указатели, но об этом легко думать. – Puppy

3

Указатель - это просто переменная, как и любая другая, но она содержит адрес памяти.
Прочтите эту строку примерно 6 раз. Сам указатель имени кажется пугающим для людей, но на самом деле это просто называется так, чтобы облегчить себе думать о том, что происходит.

Тип указателя (например, char *, int *, Point *) просто сообщает компилятору, что хранится на этом адресе памяти.

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

и почему не было объявлено?

р объявлен:

//p is declared to be a variable that holds an address 
// and at that address it holds a type Point 
//p itself only holds an address not the actual data of the Point. 
void MoveUp (Point * p) 
{ 
    //The -> operator when applied to a pointer, means give me the object at 
    // that address and then access the following member 
    p->Y += 5; 
} 

, что является именно памяти Адресная? что его можно использовать в качестве аргумента?

Вы можете придумать адрес памяти просто как число. В 32-битных программах это число составляет 4 байта. В 64-битных программах это число составляет 8 байтов.


Рассмотрим следующий код:

Point point; 
Point *p = &point; 

Переменная point имеет тип Point. Он содержит объект класса Point.
Выражение &point возвращает адрес переменной Pointpoint. Выражение &point имеет тип Point*.
Переменная p содержит адрес типа Точка, тип p - Point*.p имеет адрес в памяти объекта point.

1

р объявляется в определении функции

void MoveUp (Point * p) 
1

Прежде чем вы посмотрите на указатели, вы должны сами определить смысл «класс», «экземпляр» и «конструктор». Ваше предложение

класс создается и X и Y являются объявлены и они помещаются внутри конструктор

показывает необходимость такого разъяснения. Вот обсуждение книг, которые вы можете прочитать: Books to refer for learning OOP through C++

1

Подумайте о памяти как о непрерывных маленьких блоках.

Теперь подумайте о классе Point как о том, что составляет 2 блока ширины, и вы поместите его в любое место в памяти. Неважно, где, важно то, что он помещен только в одну отправную точку. Вы можете переместить его и изменить эту точку зрения, но безвозвратно начнете с ОДНОЙ отправной точки.

Тогда указатель - это число ОДНОЙ отправной точки.

Когда вы передаете указатель в качестве аргумента, вы делаете

  • вы: «! Эй функция, возьмите эту точку и делать то, что вы знаете»
  • Функция: «Хорошо, но где точка !?»
  • вы: «О, извините, я не беру его со мной, он находится там, в этом блоке!'

И теперь функция будет знать, что ТЕМ есть Точка, и с магией компилятора функция будет знать, что ее ширина в 2 блока. Затем функция принимает его, меняет свой Y (еще раз спасибо, компилятор) и оставляйте его там, где он был раньше (на самом деле он даже не отнимал его оттуда). Минуты спустя вы отправитесь туда и увидите пункт. Я изменился. Вы говорите «спасибо», и вы уходите.

0

p был объявлен как параметр метода.

Указатели - это особый вид переменной, которая хранит адрес памяти значения. Символ * - это символ разыменования, который сообщает вашему коду искать значение IN в адресе памяти, удерживаемом указателем. Теперь также самое время ввести символ &, который сообщает вашему коду, чтобы получить адрес памяти значения. Например:

int i = 5; //int 
int *pointer; //int pointer 

pointer = &i; //sets pointer to the memory address of i 

doMath(&i); //passes a memory address, value inside that address is being used 
doMath(pointer); //same as above 
dontMath(i); //value of x will be 207, value of i is still 7 since a copy is being modified 

//value of pointer is a memory address 
//value of *pointer is the value stored inside that memory address, 7 
//value of &pointer is the memory address of pointer, which itself holds the memory address 


void doMath(int *p) { 
    *p++; 
} 
void dontMath(int x){ 
    x=x+200; 
} 

Смятение, которое я имел на раннем этапе, было значением символа *. В объявлении переменной это означает, что вы объявляете указатель на определенный тип данных (переменная, которая содержит адрес памяти). В другом месте это символ разыменования, указывающий вашему коду на разрешение значения.

Смежные вопросы