パートCアレイ(一次元アレイ - で)

その後の記事では、Cの配列について何かを言うために続けて

 

関数パラメータとして6配列名

配列名は何が起こるかの関数の引数として渡されたのはいつですか?

値の配列名は、配列の最初の要素へのポインタであり、関数に渡さこの時点でポインタのコピーであり、容易に明らかです。次の関数は添字参照が実際にアクセス動作への間接ポインタ、および、そのような間接的なアクセスを実行行った場合は、プログラムの配列要素を呼び出す機能にアクセスして変更することができます。

今矛盾の伝送パラメータの上面Cに説明します。前に述べた関数に渡されるすべてのパラメータが値によって行われているが、配列名引数の振る舞いは、それがパスの呼び出しを通過された場合。データへのパス電話アクセスは、所望の要素へのポインタを渡すことによって達成され、その後、関数ポインタの間接的なアクセス動作を実行します。パラメータとして配列の名前がポインタである、添字参照は、実際の実行への間接的なアクセスです。

だから、行動の価値アレイによる呼び出しは、どのような場所に反映されていますか?関数に渡される(コピーの配列に位置ポインタ開始点)パラメータのコピーであり、この関数は自由に引数として、対応する修飾されたポインタを心配することなく、そのポインタパラメータを操作することができます。

だから、ここには矛盾がありません。すべてのパラメータは値によって渡されます。あなたは、変数へのポインタを渡す場合はもちろん、関数ポインタと間接アクセス操作が行われ、その関数はその変数を変更することができます。明白なように見えるではないが、しかし、正式にこのような状況が発生したときに、パラメータ名として配列。このパラメータ(ポインタ)は実際値によって渡され、関数ポインタを変更することができるコピーを得られるが、呼び出し元のプログラムに渡される引数は影響されません。

以下は、説明するため、これらのビューの簡単な関数です。

void strcpy(char *buffer, char const *string){  /* 复制字符,直到遇到NULL字节 */  while((*buffer++ = *string++) != '\0');}

どのコピー指すバッファの最初のパラメータの2番目のパラメータの文字列。バッファを呼び出すプログラムは、間接的なアクセス操作のパラメータの関数として変更されます。しかし、関係なく、関数のパラメータ(ポインタ)の方法の変更は、呼び出し側のポインタ引数自体は変更されません(それが指す内容を変更する場合があります)。

注しばらく*文字列++式文います。これは、文字列を指さ行われ、副作用をもたらす、それは次の文字を指す文字列を、変更することです。コピー機能の唯一のシェアを渡すように変更されているように、このように修正さ形状パラメータの引数は、呼び出し元のプログラムには影響を与えません。

7.宣言配列パラメータ

ここで興味深い質問ですね。あなたが関数に配列名パラメータを渡したい場合は、正しい関数のパラメータは次のようにすべきですか?これは、ポインタまたは配列として宣言すべきですか?

あなたが見ることができるように、実際の関数呼び出しはポインタが渡され、関数のパラメータは、いくつかのコンパイラは、関数のパラメータの配列を受け取り、実際のポインタですが、初心者のための使いやすいです。このように、関数は、次の2種類は同じです。

int型はstrlen(CHAR *文字列);

INT STRLEN(文字列[])。

この平等はポインタを意味し、配列名は、実際には同じであるが、それはだまされてはいけません!これらの2つのステートメントは同じことを行うが、唯一の現在の環境のコンテキストインチ 他の場所に存在する場合、それは前に述べたように、完全に異なっていてもよいです。しかし、配列パラメータのために、次の文のいずれかの形式を使用することができます。

あなたは声明のいずれかの形式を使用していますが、これは「より正確に」を意味することができますか?答えはポインタです。引数が実際にポインタの代わりに配列されているため。同様に、値はsizeof(文字列)文字長ではなく、配列の長さへのポインタです。

アレイ状関数プロトタイプのパラメータは、関数が配列パラメータのためのメモリを割り当てていないので、その中の要素の数を指定する必要はありません、なぜあなたは今、明確にする必要があります。パラメータはちょうど良いのメモリへのポインタは、他の場所で空間に割り当てられています。配列パラメータ配列は、その実際の長さのいずれかと一致させることができる理由はこの事実は、単に配列の最初の要素へのポインタを渡す----説明しています。一方、この実装は、配列の長さの関数ことを知ることができません。あなたは、配列の長さを知る必要がある場合、それは明示的な関数にパラメータとして渡さなければなりません。

8.初期化

スカラ変数は、その文のように初期化することができますように、配列は同じことを行うことができます。唯一の違いは、アレイは、一連の値を必要とする初期化することです。これらの値は、各値がカンマで区切られ、括弧の対の間に配置されています。以下の例に示すように:

INTベクトル[5] = {10、20、30、40、50}。

一つによって与えられたリストのいずれかの配列の各要素に割り当てられた値を初期化し、ベクトルは[0]の値は、ベクトルは[1]の値が20を得、そしてようにされて、10が得られます。

静的および自動初期化

ウェイ配列の初期化は、そのストレージ・タイプに応じて、ある初期化されるスカラ変数----に似ています。静的初期化のメモリアレイに保存されているのみ、このプログラムが起動する前に、それが、あります。プログラムは、彼らがそこに開始する、適切な場所にこれらのコマンド値を実行する必要はありません。このプロセスは、実行可能プログラムを適切な値を含むファイル内の配列要素で初期化されるリンカーによって行われます。配列が初期化されていない場合、配列の要素の初期値は自動的に0に設定されます。このファイルがメモリにロードされ、実行されたときに初期化後の配列の値のようなプログラム命令は、メモリにロードされます。プログラムが実行されたときしたがって、静的アレイが初期化されています。

しかし、自動変数の初期化処理は、自動可変位置ランタイムスタックので、各エントリは、その実行フローは、コードブロックは、そのような各変数は、同じメモリ位置に配置されなくてもよい場合には、それほど単純ではありません。プログラムが始まる前、コンパイラはこれらの場所を初期化する方法はありません。そうすることによって、デフォルトの自動変数が初期化されていません。自動変数の宣言が実行は変数のスコープに自動的に流れるたびに宣言され、初期値が与えられた場合、変数は暗黙割り当て初期化であろう。時間と空間としてこの暗黙の割り当てのニーズと一般的な割り当てが実行します。問題は、配列の初期化リストは、多くの割り当てを生成することが価値の多くを、持っていることです。これらの非常に大きなアレイの場合、その初期化時間がかなりあってもよいです。

だからここでは比較検討することが必要です。機能(ブロック)にローカル配列を初期化するときは、慎重に計画の実施に使用すると、流れ関数(またはブロック)を入力するたびに、再初期化するために、それぞれの時間は、アレイはそれだけの価値はありませんが、考慮すべきです。答えはNOである場合にプログラムを開始する前に、配列の初期化は一度だけ行って、あなたが入れた配列は、staticとして宣言されていません。

9.不完全な初期化

以下では2つのステートメントは、それが起こると宣言しましたか?

INTベクトル[5] = {1、2、3、4、5、6}。

INTベクトル[5] = {1、2、3、4}。

両方の場合において、アレイ素子の数とは、初期値と一致しません。最初の1文が間違っている、私たちは5つの整数変数にロードされた6つの整数値に方法がありません。しかし、第2のステートメントは、それが配列の最初の4つの要素の初期値を法的提供され、最後の要素がゼロに初期化されます。

だから、我々はそれの真ん中にそれらの値のリストを省略することができますか?

INTベクトル[5] = {1,5}。

コンパイラは、初期値だけでは十分ではありません知っているが、それは行方不明者の値を知ることはできません。したがって、唯一の最後のいくつかの初期値は省略しました。

10は、配列の長さが自動的に計算され

ここで便利なヒントのもう一つの例です。

INTベクトル[] = {1、2、3、4、5}。

文は、配列の長さを与えていない場合は、配列の長さを置くために、コンパイラは、すべて初期値の長さに対応するだけのことができるように設定されています。値の初期リストが頻繁に変更された場合は、この技術は特に便利です。

11.文字の配列を初期化します

学んだ現在の知識によると、あなたは、このフォーム以下の文字列が初期化されると思うかもしれません。

文字メッセージ[] = {H '' E '' L '' L '' O」、0}。

この方法は、もちろん可能であるが、非常に短い文字列を除いて、この方法は本当に不器用です。したがって、標準の迅速な方法を提供する言語が文字の配列を初期化するために使用されます。

チャーメッセージは、[]に "Hello" =。

それは文字列定数、のように見えますが、実際にはありませんこれは前例の初期化リストのちょうど別の方法です。

彼らはまったく同じに見える場合は、どのように文字列定数と迅速な初期化リストこの表記それを区別するのですか?彼らは、それらが置かれている状況に応じて区別されます。文字の配列を初期化するために使用する場合は、初期化リストです。他の場所では、文字列定数を表します。

次に例を示します。

char型のメッセージ1 [] = "こんにちは";

char *メッセージ2 = "こんにちは";

どちらも初期化ルックスが好きですが、彼らは異なる意味を持っています。後者は実際の文字列定数である前者は、文字の配列の要素を初期化します。以下に示すように、ポインタ変数は、文字列定数の格納場所を指すように初期化されます。


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

おすすめ

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