2012-05-03 20 views
0

構造体を別の関数の引数として渡すとき、Cの構造体について学習しています。他の関数ですべてのメンバー値をコピーしていますか?引数として配列を渡すと、配列の最初のアドレス(array [0])が渡されます。物事は構造がとてもシンプルに見えません。私の推測では、値をコピーすることも、住所を渡すこともないということです。必要に応じて渡される構造体のメンバのアドレスを使用できるようにコンパイラに指示します。私は確信していますが..どんな助けもありがとうございます。構造体を使用してCで参照されるメモリ

答えて

1
#include <stdio.h> 

struct foo { 
    int a; 
} 

void by_value(struct foo x) { 
    x.a = 10; 
} 

void by_reference(struct foo* x) { 
    x->a = 10; 
} 

int main(int argc, char* argv[]) { 
    struct foo v; 
    v.a = 5; 

    by_value(v); 
    printf("%d\n", v.a); 

    by_reference(&v); 
    printf("%d\n", v.a); 

    return 0; 
} 

コンパイルして実行すると、これはあなたの質問に答えるはずです。

+0

構造にメンバーが多い場合はどうなりますか? – KawaiKx

+1

@Saurabh値で渡すと、その中のすべてがコピーされます。メンバーの数は関係ありません。しかし、コピーは浅いことに留意してください。これは、構造体にポインタが含まれている場合、ポインターの値がコピーされ、ポインターの値はコピーされないことを意味します。 – HonkyTonk

+0

は配列のように、構造体をグローバルに宣言できますか?または構造特有の機能ですか? – KawaiKx

1

Structresは値と参照の両方で渡すことができます。渡された構造体のコピーが呼び出される関数 に説明するようスタック空間の膨大な量を消費することができる他の参照によって渡すことがそのことをお勧め大きな構造がある場合

Are there any downsides to passing structs by value in C, rather than passing a pointer?

を渡す構造についての詳細を知るために、これを読んで
+0

したがって、構造体は配列とは異なり、ソースコードファイル内のすべての関数でグローバルに使用できるわけではありませんか?私はそう言うことができますか?他の機能がそれらを必要とするたびにそれらを渡す必要がありますか? – KawaiKx

+1

@Saurabhいいえ。すべての機能でアクセスできる配列のようなグローバル構造があります。値渡しできるという理由だけでは、それらが関数間でアクセスする唯一の方法ではありません。 –

1

それはstructが渡された方法によって異なります。値によって渡された場合

  • コピーが作られ、structに関数の内部で行われた変更は、呼び出し側に表示されていない
  • 参照によって渡された場合、コピーが作られ、structに関数内の変更は、例えば、発信者

に表示されていない。

#include <stdio.h> 

struct X { 
    int value; 
}; 

void pass_by_value(struct X a_x) 
{ 
    a_x.value = 10; 
    printf("by_value(address=%p, value=%d)\n", &a_x, a_x.value); 
} 

void pass_by_ref(struct X* a_x) 
{ 
    a_x->value = 20; 
    printf("by_ref(address=%p, value=%d)\n", a_x, a_x->value); 
} 

int main() 
{ 
    struct X my_x = { 1 }; 

    printf("my_x(address=%p, value=%d)\n\n", &my_x, my_x.value); 

    pass_by_value(my_x); 
    printf("my_x(address=%p, value=%d)\n\n", &my_x, my_x.value); 

    pass_by_ref(&my_x); 
    printf("my_x(address=%p, value=%d)\n\n", &my_x, my_x.value); 

    return 0; 
} 

は出力:

 
my_x(address=0013FF74, value=1) 

by_value(address=0013FF78, value=10) 
my_x(address=0013FF74, value=1) 

by_ref(address=0013FF74, value=20) 
my_x(address=0013FF74, value=20) 
+0

構造内に1つのメンバーしか使用していません。構造体に多くのメンバーがあるとします。そのような場合、 'pass_by_value(my_x)'によって何が渡されますか? '&my_x'によって何が印刷されるのですか?あなたの忍耐のためにありがとう。 – KawaiKx

+0

それは(より多くのスペースを必要とすることを除いて)何の違いもありません。 – hmjd

+0

@hmjd:あなたのアドレス出力が16進形式でないのはなぜですか? – Jack

0

コンパイラは、関数を呼び出す前に、まずパラメータをスタックにプッシュしてから関数を呼び出します。 したがって、関数はスタックからパラメータを取得できます。

アドレスで渡されると、アドレスが関数に渡されます。 また、コンパイラは、パフォーマンスを向上させるために、 "メモリアラインメント"と呼ばれるパラメータメモリも処理します。 あなたの関数では、そのブロックを簡単に構造体に変換することができます。

コンパイラは、渡されたときにパラメータをコピーし、対応するパラメータアドレスを関数に渡します。

ちなみに、1つのプロセスでは、メモリアドレスは同じです。 どの機能でも使用できます。

関連する問題