Инициализация указателя - PullRequest
2 голосов
/ 06 июня 2010

Извините, если этот вопрос был задан ранее. При поиске через SO я не нашел тот, который спросил, что я хотел знать.

В основном, когда у меня есть это:

typedef struct node
{
    int data;
    node *node;
} *head;

и сделать node *newItem = new node;

У меня сложилось впечатление, что я объявляю и резервирую пространство, но не определяю указатель на struct node, это правильно?

Так что, когда я делаю

newItem->data = 100 и newItem->next = 0

Я запутался. newItem = 0 объявит что именно? Оба data и next? Объект в целом?

Я особенно запутался, когда использую typedef. Какая часть является макросом? Я предполагаю узел, потому что так я его называю, но зачем он мне нужен?

Наконец, что происходит, когда я делаю:

node *temp;
temp = new node;

temp = head->next;
head->next = newItem;
newItem->next = temp;

Я имею в виду, head-> next - это указатель, указывающий на объект newItem, поэтому я предполагаю, что это не newItem.data или next. Так как же мне безопасно использовать неинициализированный указатель, который я описал выше, как здесь? голова теперь не указывает на неинициализированный указатель?

Ответы [ 4 ]

10 голосов
/ 06 июня 2010

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

Нет. Вы объявляете указатель, выделяете место в стеке для указателя и динамически выделяете хранилище для узла, на котором он находится.

Не путайте себя, написав что-то вроде этого:

typedef struct node
{
    int data;
    node * next;
} *head;

Способ написания структуры в C ++:

struct node
{
    int data;
    node * next;
};

Теперь вы можете создать указатель:

node * pnode;

, который выделяет память для указателя.

и вы можете динамически распределять хранилище для узла и указывать на него указатель:

pnode =  new node;

или делайте все в одном:

node * pnode = new node;

Теперь, когда вы говорите:

pnode->data = 10;

Вы ничего не выделяете. Вы назначаете 10 члену с именем data экземпляра узла, на который указывает pnode. Конечно, если вы дали вашему узлу конструктор (что вы обычно должны делать), вы можете сделать все это в одном:

struct node
{
    int data;
    node * next;

    node( int n, node * np ) : data( n ), next( np ) {}
};

node * pnode = new node( 10, 0 );
3 голосов
/ 06 июня 2010
typedef struct node
{
    int data;
    node *node;
} *head;

Это объявляет node как структуру и определяет head как синоним для node*, поэтому head является типом, а не объектом.

Это делает это незаконным: temp = head->next;, потому что -> - это не то, что вы можете применить к типу.

new node динамически распределяет объект node и возвращает указатель на него. node *newItem = new node; назначает этот указатель на newItem. Тем не менее, обратите внимание, что newItem->node (node здесь является объектом-указателем, а не типом node) не инициализируется, поэтому не является ни нулевым, ни указывает на действительный node объект.

Это также незаконно, потому что node не имеет next члена.

newItem->next = temp;

Я предлагаю вам выбрать соглашение об именах, которое означает, что вы храните свои типы и переменные отдельно. Это несколько сбивает с толку.

3 голосов
/ 06 июня 2010

Когда вы определяете свою структуру, как вы сделали, и вызываете new, как вы это сделали, то вы делаете:

  1. выделите новый struct node в куче.
  2. выделяет место в стеке для newItem и устанавливает его значение в адрес новой выделенной структуры.

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

3 голосов
/ 06 июня 2010
node *newItem = new node;

Вы создаете:

  • новый узел в куче (который в вашем случае содержит неинициализированные значения, потому что вы опустили ()
  • указатель настек, который указывает на этот новый узел.

    newItem-> data = 100

просто устанавливает data член вновь выделенного узла равным 100.

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