2011-12-08 5 views
0

このチュートリアルで述べたように: http://www.learncpp.com/cpp-tutorial/79-the-stack-and-the-heap/LIFOはどういう意味ですか?

コンピュータプログラミングにおいて、スタックは、(アレイのような多くの)他の 変数を保持する容器です。ただし、配列では にアクセスして任意の順序で要素を変更できますが、スタックは に制限されています。スタック上で実行できる操作は、上のものと同じ です。

1)スタック上の一番上の項目を調べます(通常はtop35)スタック(ポップ()と呼ばれる 機能を介して行う)3)(プッシュ(と呼ばれる 機能を介して行う)スタックの一番上に新しいアイテムを入れて)

のしかし、私はCで2つの変数が定義されている場合++私は、定義の同じ順序でそれらを使用する必要はありません。

例:

int main() { 
int a; 
int b; 

b = 5; 
a = 6; 
} 

このコードの問題はありますか?私は好きな順番でそれらを使うことができます!! 最初にbを使用する必要はありません。

私は何かを誤解していますか?それは何ですか?

答えて

8

2種類のスタックが混乱しています。

1つのスタックは、アプリケーションのメモリの一部が割り当てられます。これは、スタックとヒープ、およびメモリが割り当てられている場所に関する議論の一部です。

他の種類のスタックは、アクセスのLIFOスタイルに準拠したデータ構造です。これは、std :: vectorまたは他の形式のデータ構造を使用して実装できます。

+2

または 'std :: stack'自体。 – GManNickG

0

スタックは、その場所全体で使用される標準的なデータ構造です。実際にスタックと呼ばれるスレッドがこのパラダイムの実装です。メモリ位置を指すスタックポインタ(通常はプロセッサレジスタ内にあります)があります。データは、spを動かすことによってこのスタックに「プッシュ」されます。それが指し示す値を返し、反対方向にspを動かすことによってポップします。

これまでに宣言されているa、bまでは違いはありません。彼らは両方が使用される前に割り当てられています。

4

ところで、呼び出されたメソッドのローカル変数を保持する "自動ストレージ"がスタックに割り当てられます。しかし、自動ストレージスタックでは、個々の値ではなく、メソッドのすべてのローカル変数を含む "スタックフレーム"をプッシュしポップします(可変サイズ)。

項目を押すとポップされていることを除いてこれは、あなたが引用記事で説明したスタックの種類と概念的に似ているがはるかに大きいです。

どちらの場合でも、メソッドを呼び出すときに "スタックをポップする"ことによって本質的に戻ってくるので、メソッドは常に逆の順序でメソッドから返さなければならないので、メカニズムは "LIFO"です。

1

アム私は何かを誤解しますか?それは何ですか?

あなたは変数の外に作られていない(AHEAD巨大な単純化と概念化を警告)された上で「A」と「B」を入れている「スタック」。それはスタックフレームから作られています。スタックフレームは、関数へのパラメータとその戻り値のためのスペースとからなり、場合によっては関数内で使用される変数も含みます(ただし、これらもレジスタに保持され、時にはパラメータもレジスタを介して渡されます)。このスタックに「押し込む」ことは、関数を呼び出すことによって達成されます。このスタックからの「ポップ」は、関数から戻ることによって実現されます。あなたは確かに "トップ"要素にアクセスするだけです。現在の関数がパラメータとして明示的に渡されていない限り、現在の関数を呼び出した関数の変数を読み取ることはできません。

0

スタックプログラム:

あなたのプログラム例では、スタックの実装ではありません。 Stackは、LIFO(先入れ先出し)順に要素をプッシュ(格納)またはポップ(引き出し)できる配列のような要素を格納します。実装は2つの変数を宣言するほど簡単ではありません。 Standard C++はスタッククラスを提供していますので、独自に実装する必要はありません。

スタックメモリ:関数で

変数はLIFO順にスタックメモリ(RAM内のどこか)に格納されています。あなたの例から、変数aが作成され、スタックメモリにプッシュされます。次に、変数bがスタックメモリにプッシュされます。関数の実行が完了すると、変数はLIFO形式で破棄されます。したがって変数bは最初に破棄され、最後に変数aは破棄されます。あなたはそのコードを書いていません。コンパイラは、アセンブリ用の低レベルのコードを書くように注意します。

1

他のデータ構造と同様に、スタックはLIFO(後入れ先出し)原理に従うデータ構造です。あなたの質問に記載されているように、LIFO原理に従ってデータを入力して取り出すためのプッシュ/ポップ操作を行います。

すべてのプロセスが

テキストを実行している場合の処理​​ にアクセス されたアドレス空間の基本的に4つの部分から成り - この部分は を実行する実際のM/C命令を含みます。多くのオペレーティングシステムでは、これは読み取り専用に設定されているため、 プロセスは命令を変更できません。これにより、プログラムの複数のインスタンス がテキストの単一のコピーを共有することができます。

データ - この部分には、プログラムのデータ部分が含まれます。これは、初期化読み取り専用データ)

1分け をfurthere - これはプログラムによって初期化されており、それらは唯一のプロセスの 実行時に読み込まれるデータ要素 が含まれています。

2)初期化された読み取り書き込みデータ - これは、プログラムによって初期化された データ要素を含み、 プロセス実行中に変更されます。

3)未初期化データ - この要素には、プログラムによって初期化された が含まれておらず、プロセスが実行される前に0に設定されています。 これらは、BSS(Block Started Symbol)と変更して参照することもできます。このような要素の advは、この領域のプログラムファイルに のスペースを割り当てる必要はありません。つまり、 プロセスが実行される前に、OSによって0に初期化されます。

スタック - この部分は、ローカル変数のために使用され、フレーム

ヒープスタック - この部分は動的に割り当てられたメモリが含まれてい

int abc = 1;       ----> Initialized Read-Write Data 
char *str;        ----> BSS 
const int i = 10;      -----> Initialized Read-Only Data 

main() 
{ 
    int ii,a=1,b=2,c;       -----> Local Variables on 
Stack 

    char *ptr; 
    ptr = malloc(4);      ------> Allocated Memory in Heap 

    c= a+b;        ------> Text 

} 

データ、ストアデータ テキスト、店舗コードがあり

リンカによって生成されたファイルの3つの(メイン?)セグメント/セクションです。テキスト - プログラムテキスト(そして明らかにconst char配列、おそらく他の 'const'配列は変更できません)。私は配列の部分について100%確信していません、おそらく 誰かが私を修正します。

データで初期化されたグローバルデータ。以下の例を参照してください。 bss - 初期化されていないグローバルデータ。ここで は、いくつかの例

int x = 1; /* goes into data */ 
int y;  /* goes into bss */ 
const int z = 1; 

これは、我々はとにかく変更することはできませんが、シンボル

によって開始

const char array[] = {'a','b'....etc} 


/* the rest goes into text */ 

int main(void) 
    { 
    return EXIT_SUCCESS; 
    } 

ブロックを保護することができるので、「テキスト」に行く見てきました

(BSS)Unixリンカによって生成された初期化されていないデータセグメント。他のセグメントは、プログラムコードを含む「テキスト」セグメントであり、「データ」セグメントは、 の初期化データを含む。 bssセグメントのオブジェクトには名前とサイズのみがあり、値はありません。

1

は、定義された順序でを使用する必要はありません。しかし、彼らはが破壊された - その順序でスタックから取り除かれています。 LIFOはアクセスを参照するものではなく、スタック上に物を置くか、スタックから取り除くだけです。

intをデストラクタに印刷するタイプを変更することで、これを簡単に観察できます。

関連する問題