にメモリを割り当てる場合はchar a[256]、各要素を異なる値に初期化し、これを関数に渡します。
int subFunc(a);
スタックフレームはどのようにsubFunc見えますか?
スタックフレームには、256バイトすべてが含まれていますか、それともa(4バイト)のアドレスへのポインタのみが含まれていますか。
ポインタの場合、内部のデータにどのようにアクセスしますか、subFuncまたはこのデータはどこで利用できますsubFuncか?
にメモリを割り当てる場合はchar a[256]、各要素を異なる値に初期化し、これを関数に渡します。
int subFunc(a);
スタックフレームはどのようにsubFunc見えますか?
スタックフレームには、256バイトすべてが含まれていますか、それともa(4バイト)のアドレスへのポインタのみが含まれていますか。
ポインタの場合、内部のデータにどのようにアクセスしますか、subFuncまたはこのデータはどこで利用できますsubFuncか?
C言語は、スタックベースのマシンを必要としません。とはいえ、スタックベースのマシンでは、ブロックスコープ配列がスタックに割り当てられる可能性があります。
Cの関数に配列を渡すことはできません。言語subFunc(a)は、の最初の要素へのポインターを受け取ることを指定しますa。subFunc (char *a)これは、2つの宣言(またはプロトタイプ)とsubFunc (char a[])が同一に扱われるという事実によって例示されます。
subFunccharの配列ではなく、へのポインタを受け取りますchar。そのポインタがどのように渡されるかの詳細は、実装によって異なります。ポインター値はスタックにプッシュされるか、レジスターに渡されます(RedHatのgcc2.96は前者を実行し、SLES10のgcc4.1.2は後者を実行します)。これは最適化設定などに依存する場合があります。 、デバッグバージョンを生成しているかどうかなど。プラットフォームでどのように機能するかを確認する唯一の方法は、コードを作成してビルドし、生成されたマシンコードを確認することです。
ほとんどの場合、「N-element array of 」タイプの式Tは、「pointer to T」タイプの式に変換(「decay」)され、式の値は、配列の最初の要素のアドレスになります。 。この規則の例外は、配列式が、、、または単項演算子のオペランドであるsizeof場合、または宣言内の別の配列の内容を初期化するために使用される文字列リテラルである場合です。 _Alignof&
与えられたコード
char a[256];
...
subFunc(a);
a呼び出しの式のsubFuncタイプは「256要素の配列char」です。char上記の規則により、「ポインタ」( )型の式に置き換えられ、char *その値はのアドレスになりa[0]ます。
したがって、subFuncの配列ではなく、ポインタ値を受け取りますchar。
関数パラメーター宣言のコンテキストでは、は;として解釈されることに注意しT a[]てくださいT a[N]。T *aのプロトタイプsubFuncが
int subFunc(char a[256])
それは次のように解釈されます
int subFunc(char *a)
呼び出した関数にはsubFunc()がありchar a[256]ます。そして、その関数は最初にスタックにあります。その後、subFunc()スタックにプッシュされました。ただし、呼び出した関数subFunc()は、の最初のアドレスをに渡す必要がありaますsubFunc()。の長さをに渡せば、それはより良いでしょaうsubFunc()。 subFunc()次のように変更する必要があります。
int subFunc(char *, int);
スタックフレームには4バイト長の値(32ビットOSの場合)しかありません。この値はの開始アドレスですchar a[256]。どこから開始するかがわかったのでa、データにアクセスできます。