物品( - 上の1次元配列)のC配列

アレイは、私たちが使用していると信じています。この記事では、そのような多次元配列などのトピックのいくつかのより高度な配列を探索するプログレッシブアプローチの配列を議論する、というように、ポインタと配列との配列を初期化します。

一次元アレイ

多次元配列を議論する前に、最初は次の次元配列を学びます。まず、我々は概念を学び、C言語の設計に欠陥があることを多くの人に考えられています。しかし、実際には、この概念は一緒にリンクされ、いくつかの完全に異なる概念を置くための非常にエレガントな方法です。

1.配列名

次の文を考えてみましょう。

int型;

int型B [10]。

私たちは、それが単一の値であるため、変数の型が整数である、スカラー変数と呼ばれます。それは値の集合であるので、我々は、配列変数bを呼ばれます。そしてセット内の特定の値を識別するために、インデックスを持つ配列名を使用。例えば、B [0]の値は、第一の配列bを識別する。それぞれの特定の値はスカラーであり、それはどのようなコンテキストスカラデータに使用することができます。

B [4]はint型ですが、タイプBは何ですか?それは何を表しているのですか?論理的な答えは、それが全体の配列を識別することであるが、そうではありません。Cにおいては、配列名を使用して、ほぼすべての式では、配列名の値は、ポインタ定数である配列の最初のエレメントのアドレスです。配列要素がintである場合、配列の名前は「intへのconstポインタ」されるタイプ;その型は配列要素の種類に依存する他のタイプの場合は、配列名の種類は、「他のタイプを指す定数ポインタ」です。

配列とポインタが同じ結論している。この事実に来ないでください。そして、ポインタ配列は、多数の異なる特徴を持ちます。例えば、アレイは、要素の決定された数が、唯一ポインタスカラー値を有します。コンパイラは、これらの特性を覚えて配列名を使用しています。配列名は、式の中で使用された場合にのみ、コンパイラはそれに一定のポインタを生成します。

この値はポインタ定数ではなく、ポインタ変数であることに注意してください。あなたは、定数の値を変更することはできません。あなたはちょうどあなたがこの制限が正当化されると思われます、瞬間を勉強;定数ポインタはメモリアレイ内の開始位置に、あなたはこのポインタ定数を変更した場合、唯一の現実的な操作が別の場所メモリに配列全体を移動することです。しかし、プログラムのリンクが完了した後に、メモリアレイの位置が固定されているので、プログラムが実行されている場合、配列は手遅れになる移動を考えます。こうして値は、配列名定数へのポインタです。

---オペランドまたはオペレータのsizeof単項&演算子時間として使用される名前であり、アレイのための唯一の配列名ポインタ一定でない両方の場合において。sizeofはなくポインタ配列の長さよりも、配列全体の長さを返します。生成された名前の配列のアドレスを取得する配列へのポインタではなくポインタ定数へのポインタです。

例えば:

INT [10]。

int型B [10]。

int型* C;

...

C =&[0]。

発現&[0]は配列の最初の要素へのポインタです。この割り当てと割り当て上記1次のタスクがまったく同じに行われるので、しかし、それは、配列名自体の値は、です。

C =。

配列名の表現が本当に意味を理解することは非常に重要である理由この代入文は説明しています。配列名は配列全体を表す場合、この文は配列全体を新しい配列にコピーされると言います。しかし、実際には絶対にない場合、割り当ては、点Cは、配列の最初の要素であり、実際にはポインタのコピーです。したがって、以下のような式:

B =。

違法である、あなたは別の配列に配列の要素のすべてをコピーする代入演算子を使用することはできません。あなたは、それぞれの要素をコピーして、ループを使用する必要があります。

次の文を考えてみましょう。

A = C。

Cは、ポインタ変数、ポインタのいくつかのフォームの実装のように、この文のルックスを宣言するために割り当てられたにCの値をコピーしますが、この割り当ては違法であり、例えば上記されています忘れないでください!この式において、の値は一定であり、変更することができません。

2.参照インデックス

前の文のコンテキストでは、次の式はそれが何を意味するのでしょうか?

*(B + 3)

まず、Bの値は、整数へのポインタであり、3の値は、整数値の長さに応じて調整されます。B + 3の整数を示すポインタの別の結果であり、それは配列の最初の要素を指すが後方位置3つの整数の長さをシフトします。次に、*式全体が正しい値であるとき、それは例値は、それが新しい値になりますとき、式全体の値が残っているそこを取得する新しい位置への間接アクセス事業者のアクセスが保存されています敷地内。

このプロセスの音は非常に精通していませんか?それが実装プロセスとインデックスの参照と全く同じであるためです。実際には、優先順位、および間接的なアクセスに加えて、同一の参照を添え字。たとえば、次の2つの式はまったく同じです。

アレイ[添字]

*(配列+(添字))

3.ポインタの添字

あなたはポインタ式と添字式を入れ替えることができます場合は、1が行うどの使うべきでしょうか?ここでは、ほとんどの人々のために、添字簡単に特に多次元配列では、理解することが、明確な答えはありません。だから、読みやすさの面で、添字は、いくつかの利点があります。一方、この選択は、実行時の効率に影響を与える可能性があります。

これらの2つの方法が正しいと仮定すると、添字はポインタよりも効率的ではありませんが、ポインタが時々インデックスよりも効率的です。

この効率の問題を理解するために、2つのサイクルを調べてみましょう。彼らは、同じタスクを実行します。まず、我々は、アレイ内のすべての要素が0に設定されている添字のプログラムを使用しています。

INTアレイ[10]、I。

以下のための式(I = 0、I <10; I ++)

    配列[I] = 0;

添字の発現を評価するために、コンパイラは、iの値を得るために、プログラムに命令を挿入し、それを整数の長さ(即ち、4)が乗算されます。全体の乗算は、いくつかの時間と空間をとります。

今、このサイクルでの見てみましょう、それはサイクルの前のタスクと同じことを実行します。

int配列[10]、* P。

用(P =配列; p <アレイ+ 10; P ++)

    * P = 0;

インデックスがここに存在していませんが、それでも乗算があります。

今、この乗算はfor文の調整部分に表示されます。長さ+ 1は整数を乗じ、次いでポインタに追加されなければなりません。しかし、有意な差が存在する:実行ループの各実行は、2つの数の同一の乗算(1からプラス操作と整数長4)です。その結果、乗算は現在コンパイル時に命令プログラムを含む----一度だけ実行され、ポインタ4が追加されます。これは、実行時に乗算演算を実行しません。

アレイに移動させると、この例では、(又は固定された数)が1ステップ場合に、より効率的でよりコンパイル時間スケールで行わ固定デジタル操作を乗じポインタを----示します以下、実行時に必要な命令そう。ほとんどのマシンでは、プログラムはより速く、小さくなります。

今、次のコードを考えてみます。

A = GET_VALUE()。A = GET_VALUE()。

[A] = 0アレイ。*(配列+)= 0。

コードステートメントの両側には差が発生しません。任意の値であってもよい、我々は実行時に知っています。どちらも、の値を調整するため、その乗算命令が必要です。この例では、ポインタの効率を示し、同じ機会を添え字。

4.効率ポインタ

上述したように、ポインタは、時々インデックスよりも効率的であり、それらが適切に使用されていれば、その結果は、コンパイラやマシンに依存して、変化してもよいです。しかし、手続きの有効性は、あなたが書いたコードに依存し、ポインタはまた、貧しいコードの品質を書くのは非常に簡単であり、通常より多くの可能性が高いとしてインデックスを使用しています。

それは、コンパイル、長さ、及び他の実用的な理由に関連します。ここでは特に最適化されたポインタの文言を話す起動しないでください、それだけで評価を行います。

一般的には、評価は、効率を高めるために、非常に限られ、ポインタの最適化の文言によって、関係するだけでなく、コードが「不可解な」コードを理解することは非常に容易になる可能されます。まれなケースでは、このようなアプローチの価値は使用しますが、ほとんどの場合、動作効率を維持するためにプログラムを困難にするのは少しのために、それは非常に価値があります。

あなたは簡単に、経験豊富なCプログラマポインタがあまりにも多くのトラブルが発生しません使用しているときと主張することができます。しかし2で、この不条理な引数の存在は、最初は「まだ問題になる。」手段「あまりにも多くのトラブルが発生しません」本質的には、あまりにも多くの複雑な関係使い方の簡単な使用よりも大きなリスク。第二には、あなたのコードは、経験豊富なプログラマとしてではないかもしれない維持、プログラムの保守は、製品が配置されているソフトウェアの主要な費用ですそれが仕事のプログラミング技術を維持するためにプログラムをより困難にして慎重に使用する必要があります。

同時に、いくつかのマシンは、配列の添字の目的を実行するための特別な手順で設計されているが、より迅速に、この非常に一般的な操作にするために、このようなマシンでは、コンパイラが実装する特別な命令を使用しますです添字表現が、コンパイラは、必ずしもこれらの命令とポインタの発現を達成することはありません。したがって、このようなAマシン上で、下付き文字は、ポインタの効率よりも高くてもよいです。

配列とポインタ

ポインタと配列は等しくありません。この概念を説明するために、次の2つのステートメントを考えてみます。

INT [5]。

int型* B;

aおよびbは、ポインタ値を有し、添え字操作を参照する間接的にアクセスすることができます。しかし、彼らはまだかなりの違いがあります。

あなたは配列を宣言すると、コンパイラは、指定された配列に予約メモリ空間内の要素の数に基づいて、その後、配列名を作成され、その値は、開始位置、このスペースを指し、一定です。ポインタ変数を宣言し、コンパイラ自体はポインタのみメモリ空間のために予約され、それは任意の整数値メモリ空間を割り当てません。そして、ポインタ変数は、それが自動変数であれば、それも初期化されません、既存のメモリ空間を指すように初期化されていません。あなたがそれらの間に有意な差があるかもしれません、2つの宣言を表現するために、このメソッドを使用します。

したがって、上記の文の後に、式が*完全に合法が、表現* bが違法です。*不確実性の位置で、または終了するプログラム原因・アクセス・メモリにB。一方、式Bは++コンパイルすることができるが、の値が一定であるため++ではありません。

次のトピックは、私たちは水を濁っすることも可能で議論ので、あなたは明らかに、非常に重要であり、それらの間の違いを、理解する必要があります。

公開された60元の記事 ウォン称賛18 ビュー20000 +

おすすめ

転載: blog.csdn.net/BadAyase/article/details/101353610