9

関数の直後に単項「&」演算子を適用して、関数の戻り値を操作したいと考えていました。ただし、コンパイル時にエラーが発生します (MinGW の gcc を使用しています)。

test.c: 関数 'main' 内:

test.c:8:12: エラー: 単項 '&' オペランドとして左辺値が必要です

質問を理解しやすくするためにコードを作成しました。

int function();
void function2(int *param);

main()
{
    function2(&function1());
}

int function1()
{
    return 10;
}

void function2(int *param)
{
    return;
}

このコードは、同じコンパイル時エラーを作成します。

問題は、他のコードなしで、function2 "()" から '&' 演算子を使用するにはどうすればよいかということです。

4

5 に答える 5

13

あなたが望むことは、C99以降で次の方法で実現できます。

function2((int[]){function1()});

つまり、関数の戻り値を含む複合リテラルを作成します。

于 2012-07-09T15:41:55.883 に答える
12

できません。関数の戻り値は値ですが、オブジェクトではありません。メモリ内に指定された場所もアドレスもないため、ポインタを取得することはできません。代わりに、次のように書くことができます:

int a = function1();
function2(&a);
于 2012-07-09T15:07:41.590 に答える
4

問題は&、変数のアドレスを取ることです。関数の戻り値は必ずしもメモリに格納されるとは限りません。つまり、 ではありませんlvalue( の左側に置くことはできません=)。したがって、そのアドレスを尋ねることは意味がありません (存在しないため)。

あなたがすべきことは次のとおりです。

int result = function1();
function2(&result);

C11 標準ではlvalue、6.3.2.1 で次のように定義されています。

左辺値は、潜在的にオブジェクトを指定する (void 以外のオブジェクト型を持つ) 式です。(脚注: ''lvalue'' という名前は、元は代入式 E1 = E2 に由来します。ここで、左側のオペランド E1 は (変更可能な) 左辺値である必要があります。おそらく、オブジェクト ''ロケーター値' を表すと考えたほうがよいでしょう) 「右辺値」と呼ばれることがあるものは、この国際標準では「式の値」として記述されています)

同じ標準では、6.5.3.2 で次のように述べています。

単項 & 演算子のオペランドは、関数指示子、[] または単項 * 演算子の結果、またはビット フィールドではなく、レジスタ ストレージ クラス指定子で宣言されていないオブジェクトを指定する左辺値のいずれかでなければなりません。 .

于 2012-07-09T15:09:02.697 に答える
3

関数が返す値のアドレスを取得することはできません。

その値が CPU レジスタを介して呼び出し元に返されるとどうなるでしょうか?

function2() に function1() の結果を使用させる唯一の方法は、たまたまメモリ内にアドレスを持つ中間変数を使用することです。

main()
{
    int a;

    a = function1();
    function2(&a);
}
于 2012-07-09T15:10:00.643 に答える
2

これを直接行うことはできません。関数の戻り値は、スタックに格納されるか (すぐに別の関数呼び出しで上書きされます)、レジスタなどに格納されます (呼び出し規約によって異なります)。

おそらく、これらの場所のいずれにも直接アクセスしたくないでしょうし、あまり意味がありません (自分が何をしているのかを実際に理解していない限り)。

使用する関数の戻り値は右辺値 (まあ...単に値) ですが、コンパイラ出力で見たように、'&' 演算子には左辺値 (代入できるもの) が必要です。したがって、戻り値を変数 (「main()」内のローカル変数) に格納し、そのアドレスを取得するだけです。

int main() {
    int x = function1();
    function2(&x);
}
于 2012-07-09T15:12:48.523 に答える