dポイントプレゼントキャンペーン実施中!

もしかすると、ちょい前の質問(https://okauth.okwave.jp/qa4151232.html)と同じことを聞いているような気もしますが、気にせずポスト。

その質問を読んだ時に strchr() のマニュアルを見たわけなんですが、そのプロトタイプ宣言は

char* strchr(const char* s, int c);

なんですね。どうして第 2 引数の型が int なのでしょう?「文字」c を検索するんだから普通に考えれば char ではないかと思うのですが、誰か教えて下さい。

ソースはこんな感じだったので、int である必要はないように思えるのですがどうなんでしょうか?
負数を与えたときに「何らかの動作」を期待してのことなのでしょうか?

char* strchr(const char* s, int c)
{
 char ch;
 ch = c; /* <= 結局 char 型にしている */
 for ( ; ; ++s) {
  if ( *s == ch ) {
   return (char*)s;
  }
  if ( *s == '\0' ) {
   return NULL;
  }
 }
}

A 回答 (12件中11~12件)

 charが慣習的にintで表される由来はint getchar()でしょうね。

charはC言語において、「ターゲットとするプラットホームで扱う全ての文字を十分表現できる」大きさと規定されている(参照:プログラミング言語C第2版 pp.44)。ところで、EOFは文字ではない。つまり、getchar()が返す値群は、上で言った文字+EOF分の表現ができないといけない。charが7ビットである処理系(レアケースなんかじゃないですよ。その当時は普通に存在してたんですから。ちなみに「1バイト」とは「8ビット」ではありません。2008年現在でも、1バイトが9ビットなマシンなんかも当たり前のように存在します。)を考えてみると7ビットなので128文字。これにEOFを加えた129文字をgetchar()は表現できる必要がある。なのでcharではなくintになっています。そこから文字1つは慣習的にEOFを想定のうちに入れたintになってるんじゃないかね。EOFが絶対来ない様な場面でも。

> Cの場合は、charの値というのは書いた瞬間にintになりますので、関数の仮引数でchar型というのはあり得ません。
 あれ? そうだったかな・・・・? NEC版 MS-DOS 3.30C+LSI-C/86ではAXレジスタではなくALレジスタを使うコードを吐いていたような・・・・? たしかTurbo-C++ Ver.1.01も(こっちは違うかも)。K&R(いわゆるC言語バージョン0.9)の頃は確かに全てのcharをintに直して受け渡した後でcharに戻していたけど(というかK&Rの頃はプロトタイプ宣言そのものが無かった)、ANSI Cではcharを暗黙にint扱いしないはず(なのでK&Rを想定したソースをコンパイルするとアドレスに食い違いができて落ちる事もあった)。charはcharとしてスタックに積むはずだよ。そう(暗黙変換)なる処理系もきっとあるのでしょうが、いずれにせよコンパイラ依存ではないでしょうかね。

 ついでに言うと、標準Cライブラリのisalpha()などisxxxxx()系の関数のソースを見てみると面白い。きっと多くの処理系でASCIIを想定したビット(型は大体int)の配列になっていると思うんだけど、配列の大きさが256じゃなくて257なのよね。それで、実際に配列にアクセスする際に[charcode+1]を見る。これもEOF(=-1)が入ってくる事を想定した作りになっとるって訳。
    • good
    • 0
この回答へのお礼

早速の回答ありがとうございます。

>そこから文字1つは慣習的にEOFを想定のうちに入れたintになってるんじゃないかね。
>EOFが絶対来ない様な場面でも。
ふむ。getchar() が戻り値を int にしているのは単純に EOF を受けるためだと、お気楽に認識しておりました。

C の慣習なんですかねえ。個人的には、「EOF が有り得ない」と認識しているなら、それをコードに char 型として反映して欲しいところですが。

お礼日時:2008/07/05 00:28

CとC++で違いますが、Cの場合は、charの値というのは書いた瞬間にintになりますので、関数の仮引数でchar型というのはあり得ません。



Cでは 'A' はint型。
C++では 'A' はchar型。

この回答への補足

>Cの場合は、charの値というのは書いた瞬間にintになりますので
>関数の仮引数でchar型というのはあり得ません。

お手数ですが「書いた瞬間に int になる」というのをもう少し説明していただけますか?

int foo(int c)
{
 return c;
}



int foo(char c)
{
 return c;
}

からは「まったく同じ」オブジェクトが作成されるということですか?

補足日時:2008/07/05 00:08
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!