1

int配列を引数として取る関数があります。配列はint文字列を表していますが、含むことができる必要があるEOFため、型にすることはできませんchar[]。私の関数は次のようになります。

_Bool fun(int str[]) {
  // does something involving checking elements for EOF, e.g.:
  return (str[0]==EOF);
}

テスト目的で、文字列リテラルで呼び出したいと思いますfun(ただし、文字列リテラルは型char[]であり、を含めることはできませんEOF)。

fun("test");

これはコンパイルされますが、引数の型が間違っているという警告が表示されます。文字列リテラルはchar[]であり、引数は であるため、これは予期されることですint[]

私はこれを行うことができます:

fun( (int*) "test");

これはおそらく同等です。キャストを明示的に行っているだけで、同じコンパイル警告が表示されます。

char*へのキャストが機能することint*が保証されていないことを読んでいます(リンク)。intこれは一般的なケースでは当然のことです。大きなをに書き込もうとするとstr[some_index]、収まらない可能性があるためです。str[some_index]メモリは a に割り当てられているだけcharです (ここで間違っている場合は教えてください)。

しかし、私はそのような書き込みを行うのではなく、単に比較するだけなので (char と int の比較は問題ないはずです)、上記のいずれかで問題ありませんか? その場合、コンパイル警告を取り除くにはどうすればよいですか? または、これを解決する最善の方法は何でしょうか?

charもちろん、文字列リテラルが与える配列を値ごとに値としてコピーする単純な関数を作成することもできintますが、もっと良い方法があるはずです。このようなソリューションは、メモリも浪費します。

(ちなみに、 でテストするときはEOF、次のようにします。

int str[] = {'t', 'e', 's', 't', EOF};
fun(str);

これは正常に動作するはずです。)

4

3 に答える 3

5

あなたが提案したキャストは、コンパイラが(正当に)それについて不平を言っていることを除けば、災害です。

リトルエンディアン (Intel) マシンを使用していると仮定すると、関数は次のようなメモリ レイアウトを想定しています (空白の四角形にはすべてのビット 0 が含まれます)。

+---+---+---+---+
| t |   |   |   |
+---+---+---+---+
| e |   |   |   |
+---+---+---+---+
| s |   |   |   |
+---+---+---+---+
| t |   |   |   |
+---+---+---+---+
|EOF|EOF|EOF|EOF|
+---+---+---+---+

あなたが渡しているのは、次のようなメモリ レイアウトです。

+---+---+---+---+
| t | e | s | t |
+---+---+---+---+
| \0| 
+---+

これはまったく同じではありません。これは、考えられるアライメントの問題を完全に無視しています。文字列の末尾をマークする EOF マーカーなしで、5 バイトのデータを渡しています。

簡潔に言えば、それをしないでください!

于 2012-12-30T00:54:25.200 に答える
0

OK、要約:

暗黙的または明示的なキャスト (fun("test")およびfun( (int*) "test")それぞれ) は、私が望むことを行いませ(詳細については、Jonathan Lefflers の回答を参照してください)。

ここでの方法は、おそらく、文字列リテラルをEOF値と組み合わせてすべてを として返すカスタム関数を作成することint[]です。

于 2013-01-01T10:54:50.833 に答える
-1

EOF は 0 の定義であり、同等の文字は '\0' であるため、0 と比較してみてください。

于 2012-12-30T00:52:44.397 に答える