ポインタについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
tak2929

ポインタについて

#1

投稿記事 by tak2929 » 8年前

ポインタに関して理解不足のため、ご教授いただけないでしょうか。
下記コードの24〜40の関数におけるポインタの挙動がよくわかりません。
具体的には、
①main関数の111行目を実行して2個目の数値をキューに入れた際にhead->nextがtail->nextのアドレスになる理由
②その際、headのアドレスはtailのアドレスにならない理由
③main関数の112行目を実行して3個目の数値をキューに入れた際にはhead->nextがtail->nextのアドレスにならない理由が分かりません。
よろしくお願いします。

コード:

#include <iostream>
#include <cstdlib>
#include <cctype>
using namespace std;

class list {
public:
  list *head; // リスト先頭へのポインタ
  list *tail; // リスト末尾へのポインタ
  list *next; // 次項目へのポインタ
  int num;    // 格納される値
  list() { head = tail = next = NULL; }
  virtual void store(int i) = 0;
  virtual int retrieve() = 0;
};

// キュー型リストの作成
class queue : public list {
public:
  void store(int i);
  int retrieve();
};

void queue::store(int i)
{
  list *item;
  item = new queue;

  if(!item) {
    cout << "メモリ割り当てエラー\n";
    exit(1);
  }
  item->num = i;

  // リスト末尾に置く
  if(tail) tail->next = item;
  tail = item;
  item->next = NULL;
  if(!head) head = tail;
}

int queue::retrieve()
{
  int i;
  list *p;

  if(!head) {
    cout << "リストは空です\n";
    return 0;
  }

  // リスト先頭から取り除く
  i = head->num;
  p = head;
  head = head->next;
  delete p;
  return i;
}

// スタック型リストの作成
class stack : public list {
public:
  void store(int i);
  int retrieve();
};

void stack::store(int i)
{
  list *item;
  item = new stack;

  if(!item) {
    cout << "メモリ割り当てエラー\n";
    exit(1);
  }
  item->num = i;

  // スタックのような操作になるよう、リスト最前部に置く
  if(head) item->next = head;
  head = item;
  if(!tail) tail = head;
}

int stack::retrieve()
{
  int i;
  list *p;

  if(!head) {
    cout << "リストは空です\n";
    return 0;
  }

  // リスト先頭から取り除く
  i = head->num;
  p = head;
  head = head->next;
  delete p;
  return i;
}

int main()
{
  list *p;

  // キューのデモ
  queue q_ob;
  p = &q_ob; // キューを指す

  p->store(1);
  p->store(2);
  p->store(3);

  cout << "キュー: ";
  cout << p->retrieve();
  cout << p->retrieve();
  cout << p->retrieve();

  cout << "\n";

  // スタックのデモ
  stack s_ob;
  p = &s_ob; // スタックを指す

  p->store(1);
  p->store(2);
  p->store(3);

  cout << "スタック: ";
  cout << p->retrieve();
  cout << p->retrieve();
  cout << p->retrieve();

  cout << "\n";

  return 0;
}
 

アバター
Tatu
記事: 445
登録日時: 13年前
住所: 北海道

Re: ポインタについて

#2

投稿記事 by Tatu » 8年前

最初はコンストラクタにより
q_ob:{値:代入なし,head:NULL,tail:NULL,next:NULL}
となります。


110行目を実行すると
36-39行目で
q_ob.tailがNULLなのでこの行の処理は行わない。
q_ob.tailをitem(1つ目)にする。
1つめのnextをNULLにする。
q_ob.headがNULLなのでq_ob.headをq_ob.tailにする。

結果
q_ob:{値:代入なし,head:1つ目,tail:1つ目,next:NULL}
1つ目:{値:1,head:NULL,tail:NULL,next:NULL}
となります。


111行目を実行すると
36-39行目で
q_ob.tailがNULLでないのでq_ob.tail(=1つ目)->nextをitem(2つ目)にする。
q_ob.tailをitem(2つ目)にする。
2つ目のnextをNULLにする。
q_ob.headがNULLでないのでこの行の処理は行わない

結果
q_ob:{値:代入なし,head:1つ目,tail:2つ目,next:NULL}
1つ目:{値:1,head:NULL,tail:NULL,next:2つ目}
2つ目:{値:2,head:NULL,tail:NULL,next:NULL}
となります。


112行目を実行すると
2回目と同様の処理を行い、
q_ob:{値:代入なし,head:1つ目,tail:3つ目,next:NULL}
1つ目:{値:1,head:NULL,tail:NULL,next:2つ目}
2つ目:{値:2,head:NULL,tail:NULL,next:3つ目}
3つ目:{値:3,head:NULL,tail:NULL,next:NULL}
となります。

閉鎖

“C言語何でも質問掲示板” へ戻る