5

私は C でいくつかのコードを書いていますが、メソッドに出くわしたときに、パラメーター変数がメモリのどこに格納されているのか疑問に思いました。私は次のことを知っています:

グローバル変数 -> static のコード セクションに格納

静的変数 ->

ローカル自動変数 (メソッド内) -> スタックに保存

ローカル静的変数 -> スタックに保存

ローカル const 変数 -> スタックに格納

私の仮定が正しいと仮定します。

しかし、パラメータ変数はどこに保存されているのでしょうか? 例: int *(int x, char *c);

ありがとう!

編集: 何かをmallocすると、それがヒープに配置されることはわかっていますが、ポインターを逆参照してポインターの場所の値を取得すると、それもヒープに保存されているのでしょうか、それともスタックにあるのでしょうか?

4

3 に答える 3

7

それはさまざまなことに依存します。呼び出し規約は主に調べる必要があります。このx86ページでは、さまざまな呼び出し規則と、パラメーターが関数に渡される方法について説明します。このリファレンスでは、さまざまな C++ コンパイラとプラットフォームで使用される呼び出し規則について説明します。一般に、それはスルー レジスタのスタック上にあります。

C++ (ネストされた) 関数呼び出し命令に対する私の回答- レジスターも関連しており、さらに便利なリンクがいくつかあります。

于 2013-04-30T16:30:04.973 に答える
4

関数の引数 (「パラメーター」) を格納する必要はまったくありません。覚えておいてください: C は値による呼び出しを使用します。値はメモリの場所に格納する必要はなく、レジスタに格納することも、何らかの方法でプログラムの状態からその値を決定することもできます。

たとえば、 strlen() や sin() 、 cos() 、 sqrt() などのライブラリ関数をハードウェアに実装できます。sin(x)は、対応する値を特殊関数レジスタに格納し、特殊関数命令を発行して結果を引き出すことで実装できます。x(浮動小数点ハードウェアには、たとえば Pi を可能な限り最高の精度で表現する疑似命令がある場合もあります。Pi 値は決して渡されず、命令のみが渡されます:「Pi/2 を使用する」)

「通常の」ユーザー定義関数の場合でも、引数をレジスタ経由で渡すことができ、複数の引数を組み合わせて大きなレジスタにすることができ、最適化することさえできます。

これは、インライン化された関数で最もよく表示されます。関数の機能が呼び出し元の機能と組み合わされているため、これらの関数は完全に消える可能性があります。

関数がその引数の 1 つのアドレスを取得する場合は状況が異なります (たとえばint func(int arg) { int *p = &arg; }、arg にアドレスを強制します) が、このケースは比較的まれです。

WRT 標準: C 関数にはアクティベーション レコードがあります。(非標準的な人は、おそらく「スタック フレーム」と呼ぶでしょう)。また、関数は引数がローカル変数の一部であるのように動作し、関数が戻るとスコープ外になります。それらが値を取得する方法はまったく関係ありません。理論的には、メッセージパッシングによって行うことさえできます。

于 2013-04-30T17:11:37.260 に答える