0

私は次のような多くの機能を持っています:

void write(char* param, int len)
{
    //
}

&そして、引数に演算子を使用することはほとんどないことに気づきました。配列を渡すと:

char in[20];
write(in, 20);

私はそれを必要としませんが、私が単一の値を渡すとき:

write(5, 1);

私はそれを必要としないようです、そして私がポインターを渡すとき:

char* in = malloc(20);
write(in, 20);

私もそれを必要としません。それで、どのような状況で私は実際に電話する必要がありますか?

write(&in, 1);

私は混乱しているので:D

4

5 に答える 5

4

2番目のケースについてよろしいですか?それは私のためにコンパイルされないので、

char in = 5;
write(&in, 1);
于 2013-01-30T17:38:10.557 に答える
2

値が暗黙的にポインタに変換されるのはいつですか?

実際には、整数型はコンパイラーによって暗黙的にポインターに変換される場合があります。理論的には、これは違法であり、これを受け入れるコンパイラは通常、警告を発行します。

example.c:2:6: warning: incompatible integer to pointer conversion initializing
               'void *' with an expression of type 'int'

上記の例では:

char in = 5;
write(in, 20);

charは整数型であるため、コンパイラで許可されている場合は、C標準の一部ではなく、完全にコンパイラ固有ですが、暗黙的にポインタ型に変換される場合があります。

結果は実装定義ですが、キャストを使用して整数型をポインタ型に変換することは標準で許可されていることに注意してください。

char in = 5;
write((char *)in, 20);

0暗黙的な変換の唯一の許可されたケースは、nullポインターを示す整数定数の場合です。

write(0, 20);    // allowed

整数定数自体は許可されていますが、値を持つ整数型の変数は許可されていないことに注意してください0

char in = 0;
write(in, 20);   // not allowed

&他のものに関しては、ポインタを渡すとき、それはすでにポインタであるため、明らかに、は必要ありません。配列を渡すと、ポインターに減衰するため、そこにも必要&ありません。これらの両方の場合で、上記の関数はaを期待し、それぞれaとachar *が供給されるため、これを使用することは実際には違法です。char **char (*)[20]

于 2013-01-30T17:40:08.217 に答える
1

どういうわけか、関数'write'のプロトタイプを、この関数を呼び出すファイルに次のようにコピーします。

void write(char *in, int len);

void foo(int bar){
   char in=5;
   write(in, 1);
}

おそらく警告が表示されます。inはポインタではないため、5はアドレスになる可能性があります。プログラムが正常にコンパイルおよびリンクされている場合、実行時にクラッシュすると思います。

于 2013-01-30T17:46:40.620 に答える
1

使用して; return_type function_name(prim_data_type* param...) paramは、メモリ内のアドレスを指すポインタであり、そのアドレス内*paramの値です。答えはあなたがこれで何をしたいのかについてですparam

char in[20];

in」は最初の要素のアドレスです。したがって、関数呼び出しで:

write(in, 20);

最初の要素のアドレスを送信しているので、関数の実装では、最初の要素にアクセスしたり*param、2番目の要素にアクセスし*(param+1)たりできますparam[1]。混乱している場所は次のとおりです。

char in = 5;
write(in, 1);

inはアドレス5(00000005)であるため、関数の実装では、そこにある値にアクセスします。このように使用する場合は注意が必要です。

malloc操作の場合:

char* in = malloc(20);
write(in, 20);

incharの20要素を保持するアドレス(最初の要素のアドレス)へのポインタは、スペースを取ることができます。この関数では、paramポインターを使用してすべての要素にアクセスできます(*param最初の要素、*(param+7)またはparam[7]8.要素)

結論として、別の関数でプライマリデータ型の変数(int、float、char ..)を操作する場合は、;を使用する必要があります。

write(&in);

そうすることで、その書き込み関数の実装で、その変数にアクセスし、*param混乱することなく値を変更できます。

注:理解を深めるために、ここでは一部の説明を簡略化しています。ここで追加の警告を歓迎します。

于 2013-01-30T18:24:11.247 に答える
0

関数と配列は、コンテキストによってはポインターに減衰します。関数は関数へのポインターに崩壊する可能性があり、配列は配列の最初の要素へのポインターに崩壊する可能性があります。他のタイプはこのように動作しません。

この例:

char in = 5; 
write(in, 1);

しかし間違っています。その場合は間違いなく必要です&。本当にそのように機能しましたか?

于 2013-01-30T17:38:05.937 に答える