2012-03-03 16 views
1

私はちょうどgetchar()がどのように実装されているのだろうか?それは次のようなものですか?この方法では、1バイトを読むのは非常に非効率的です。それはいくつかのバッファリングを使用していますか?getchar()はどのように実装されていますか?

標準Cライブラリの実装の数を考えると
Pseudo code: 

int getchar(){ 

char buf[1]; 
int n = read(0,buf,1); 
if(n < 1) 
    printf("Read failed"); 

return buf[0]; 
} 
+1

'ungetc()'の存在は、* some * kindのバッファリングを使用する必要があることを確認する必要があります。 –

+0

見るべきあなたのための実装はたくさんあります。単にGoogle検索を離れているだけです。 –

答えて

2

、それは明確な答えを提供することはできませんが、最も一般的なものは、同じ一般的なガイドラインに従っているようです。

getchar()は、標準Cライブラリのストリームインフラストラクチャ、つまりFILEとそのフレンドリ関数を使用しています。最近のCライブラリの実装では、ファイルストリームはある程度バッファリングされ、バッファサイズと動作は通常setvbuf()で調整可能です。 fopen()に余分なオプションを介して - - メモリマッピングを介してアクセスすること(すなわちmmap())よりもむしろread()/write()ファイルは、任意に

Iは、少なくとも一つのケース(glibc)を認識しています。 scanf()のような上位レベル関数の呼び出しと混在した場合の問題を回避するには、は同じバッファリング構造を使用するようにしてください。

プロファイラからの情報がなければ、getchar()を使用するコードの構造上の複雑さは、その使用に起因するパフォーマンスの問題よりも心配です。

+1

'mmap'を使って' FILE * 'を実装することは不可能です。 glibcの 'mmap'サポートは、非標準のフラグを' fopen'関数に渡す場合にのみ使用されるオプションです。これは、マップが作成された後のファイルの切り捨ては、もはや存在しない部分にアクセスしようとすると 'SIGBUS'となるためです。 –

+0

@R ..:私はこの点をもっと明確にするために私の答えを編集しました。私はその部分にもっと注意を払っていたはずです。 – thkala

+1

カーネルが新しい ' 'SIGBUS'の代わりに代替信号を使用するための' mmap'フラグがあり、その信号がアプリケーションではなくユーザー空間の標準ライブラリの実装で使用するために予約されている場合(pthreadsで使用される内部信号とよく似ています) 'mmap'でstdioバッファを安全に実装する。しかし、私はそれが可能になるだろうすべての努力に比べてパフォーマンスのメリットが非常に残念だと思う。 –

0

非常に簡単な実装です。

int mygetchar(void) 
{ 
     static char buf[BUFSIZ]; 
     static char *bufp = buf; 
     static int i = 0; 

     if (i == 0) 
     { 
       i = read(0, buf, 1); 
       bufp = buf; 
     } 
     if (--i >= 0) 
     { 
       return *bufp++; 
     } 

     return EOF; 
} 
関連する問題