2017-01-30 1 views
3

私はC言語を学んでいますが、なぜ、C関数がint、char、doubleなどの引数が与えられたときに呼び出されたときにこれらの引数の値を変更しないのですが、配列要素を変更します。例えばC関数が配列を自動的に変更するのはなぜですか?

:あなたが宣言しint array[1] = {1}int m = 1を初期化すると

void conversion(int array[]) 
{ 
    array[0] = 0; 
} 

void numeric(int m) 
{ 
    m = 0; 
} 

、これらの引数を持つ関数を呼び出し、array[0]が変更されますが、int mはしていません。配列の引数が変更されても、intの引数は変わらない理由はありますか?ポインタとは何か?

+1

配列要素を変更するときには、配列変数自体を変更しないでください。 – neoaggelos

+3

コードをインデントしてください。 –

+0

必要な方法で助けを得るために完全なコードを共有してください:) –

答えて

3

void numeric(int m) 
{ 
    m = 0; 
} 

は、次のコードスニペット

void numeric(int *m_ptr) 
{ 
    *m_ptr = 0; 
} 

//... 

int m = 1; 

numeric(&m); 

を検討してください。

今度は、配列

int m[1] = 1; 

numeric(&m[0]); 

そして、この場合にはオブジェクトm[0]は、関数内で変更されますと同じ機能を使ってみましょう。配列型を有するとして宣言されたパラメータをポインタに調整されているので、ここでこの機能

void numeric(int *m_ptr) 
{ 
    *m_ptr = 0; 
} 

void numeric(int m_ptr[]) 
{ 
    *m_ptr = 0; 
} 

のように書き換えることができる

。例えば、これらの関数宣言は

void numeric(int m_ptr[1]); 
void numeric(int m_ptr[10]); 
void numeric(int m_ptr[100]); 
void numeric(int m_ptr[]); 

は互いに等価であり、今度は関数宣言

void numeric(int *m_ptr); 

と同様の機能を宣言に相当します。これらすべての宣言を1つのコンパイル単位に含めることができます。

一方、関数に渡された配列は、最初の要素へのポインタに暗黙的に変換されます。そう

numeric(&m[0]); 

上記の関数の呼び出しは、このように、配列をパラメータとして、それに応じて要素が渡さので、その要素を変化させることができる引数として使用されるコール

numeric(m); 

と等価です参照によって機能する。上記の最初のコードスニペットの例に示されているように、単一のオブジェクトを参照渡しする場合は、そのオブジェクトも変更されます。

したがって、関数が引数を参照または値で受け入れるかどうかは異なります。配列が使用される場合、それらの要素は実際には参照によって関数に渡されるため、関数内で変更することができます。

3

Cは関数の引き数渡しに値渡しを使用するため、配列以外の型変数の場合、呼び出された関数から値を変更することはできません。呼び出された関数の内部ではのコピーが渡されます。したがって、呼び出された関数のパラメータに加えられた変更はではなく、を呼び出し元の引数に反映します。

しかし、配列を関数に渡している間は、配列の最初の要素へのポインタに減衰し、の内容が呼び出された関数から変更されます。そのため、あなたのケースでは、array[0]への変更が発信者に反映されますが、array自身が値渡しされているため、arrayへの変更は永続化されません。

+0

downvoteの理由? –

1

配列は、関数に渡されるときにポインタに崩壊します。配列は変更せず、配列の内容を変更します。

これら二つの機能

は等価です: http://c-faq.com/aryptr/

は多くの微妙な違いがあります。

int foo(int arr[]); 

int bar(int *arr); 

非公式C-FAQは、配列とポインタが異なるおよび/または類似した方法についてのより多くの情報を持っています。あなたは、変数mは、関数内で変更されます見ることができるようにする代わりに、この機能の

+0

''配列がポインタに崩壊する '..適切なコンテキストがないと、これは間違っています。例: 'sizeof'演算子。 –

+0

@SouravGhosh正しい。配列は、関数に渡されるときにポインタに崩壊します。 – Leandros

+2

@Leandros - 関数に渡されたときだけでなく、ほとんどが一般的に渡されます。例外が発生しない場合はほとんどありません(また、sizeofがその中にあります)。 – StoryTeller

関連する問題