Cポインタの本質

2579 ワード

最近C/C++の指针に対して特に风邪を引いて、详しく研究しました
次の定義を参照してください.
      char a[] = "Hello World"; 
      char *p   = "Hello World"; 

      1.アドレス
アドレス自体は、整数、浮動小数点数、文字などの基本タイプと同じ基本データ型です.ポインタはタイプではなく、本当のタイプはアドレスであり、ポインタはアドレスというデータ型を格納する変数にすぎない. 
たとえば、
    
int i=10; 

10は整数であり、iは整数を格納する変数であり、ポインタはこのiのように、アドレスはその10のようなものである.ポインタが加減算できるのは、ポインタであるからではなく、加減算法則がポインタという変数に属するのではなく、アドレスというデータ型の本能であり、アドレスが加減算する能力を持っているからこそ、ポインタをアドレスを格納する変数として加減算演算を行うことができるからである.これは整数変数と同じで、整数は加減乗除できるので、加減乗除も可能である. 
    2.ポインタとは
ポインタ自体は変数であり、他の変数と同じです.ポインタ自体はシンボルです. 
例えばint*pでは、コンパイラがメモリに2(32ビットシステムは4バイト)バイトの記憶空間を割り当てるポインタpを定義します.私たちがpを使用するとき、pの値は割り当てられたばかりの記憶空間に保存されている内容です.変数を見てみましょう.int a=10を定義します.aは変数名です.私たちがaを使用する場合、aに対応する記憶空間の内容を使用します.a自体は、ある記憶空間に対応するシンボルであると理解できる.&aは、aに対応する記憶空間をとるアドレスである.このようにポインタも変数であり,それ自体も記号であり,pを用いる場合,pという変数に対応する記憶空間の内容を用いるが,この記憶空間の内容は整数でも浮動小数点数でもなくアドレスタイプのデータである.では、&pとはどういう意味でしょうか.&pとは、pに対応する記憶空間のアドレスです(このアドレスはpに対応する記憶空間の内容ではありませんよ).では*pはどのように理解しますか?使用時、pの値が対応する記憶空間の内容であることを覚えておくと、*pは自然にそのアドレスに対応する記憶空間の内容を取り出すことになる. 
      3.配列名とは
配列名:数です.この数は整数と似ています.浮動小数点数はアドレスタイプのデータです.int a=10のように;ここでの10は、アドレスタイプデータと同じ階層に属する整数です.すなわち、配列名は整数10と似ているが、aとの差は大きく、概念ではない.配列名は&aと同じで、アドレスデータであり、配列名は定数、アドレス定数である. 
配列を格納する領域はスタックに静的に割り当てられたメモリ(staticではない)であり、配列名はこのメモリの代表であり、このメモリのヘッダアドレスとして定義される.これは,配列名がアドレスであり,また,修正不可能な定数であることを示し,完全にはアドレス定数である.配列名は列挙定数と類似しており、シンボル定数に属します.配列名という記号は、そのメモリのヘッダアドレスを表します.気をつけて!配列名という記号の値がそのメモリのヘッダアドレスではなく、配列名という記号自体がヘッダアドレスというアドレス値を表し、それがこのアドレスであり、これが配列名がシンボル定数に属する意味である.配列名はシンボル定数であるため、右の値であり、ポインタは変数として左の値であり、右の値は永遠に左の値ではありません.では、配列名は永遠にポインタではありません. 
    4.冒頭で定義した文字配列と文字列ポインタの違いについて説明します.
この2つの定義は同じ関数(mainなど)にあると仮定した. 
続行:
*(a+1) =u;                                                
 *(p+1) = u 

ここでは、最初の操作が通過し、2番目の操作でセグメントエラーが発生します.これは何が原因ですか?では、プログラム空間割り当てにおけるストレージ領域の問題を理解する必要があります.C/C++プログラムに対応する記憶領域、分位三類
    1.静的ストレージ領域:メモリはプログラムのコンパイル時にすでに割り当てられており、この内にプログラムが存在する全実行期間が存在します.静的データ、グローバルデータ、定数を主に格納します. 
    2.スタック領域:関数を実行すると、関数内のローカル変数のメモリセルがスタック上に作成され、関数の実行が終了すると、これらのメモリセルが自動的に解放されます.スタックメモリ割り当て演算はプロセッサの命令セットに組み込まれており,効率は高いが,割り当てられたメモリ容量は限られている. 
    3.ヒープ領域:ダイナミックメモリ割り当てとも呼ばれます.プログラムは実行時にmallocまたはnewで任意のサイズのメモリを申請し、プログラマー自身が適切な時にfreeまたはdeleteでメモリを解放する責任を負う. 
ここでchar a[]=「Hello World」は、スタックに割り当てられたスペースなので、その内容を変更することができます.一方、char*p=「Hello World」は、静的記憶領域に割り当てられた空間である.Hello worldは文字列定数であり、変更は許可されていません. 
この文書のソース:http://dolive.iteye.com/blog/394706