2

重複の可能性:
getchは非推奨です

タイトルが言うように、これら2つの方法の違いは何ですか?私は新しいので、それらの使用法について混乱しています...

4

2 に答える 2

3

Microsoft の C コンパイラの非常に古い実装では、POSIX/UNIX の世界と同じ名前を使用する関数や、ユーザーの名前空間に違反する関数が提供されていました。これらのいくつかは、おそらく標準化が行われる前 (MS-DOS の時代) に行われた「侵害」であることに注意してください。

かなり前のある時点で、Microsoft は、これらの名前をコンパイラの実装用に予約された一連の名前に移動することを決定しました。厳密に言えば、そうする必要がなかったとしても、彼らは図書館の多くの名前に対してこれを行いました。彼らは、標準の C/C++ ではないすべてのライブラリ名に対してこれをほとんど行ったようです。これは SDK 内の名前には適用されないことに注意してください。SDK がコンパイラと共に配布されている場合でも、ヘッダーとライブラリのセットはコンパイラ実装ドメインの外部にあります。

古い名前 (アンダースコアのないもの) で書かれたプログラムとの互換性のために、Microsoft は古い名前 ( などgetch) を新しい名前 ( _getch) にリンクするエイリアスを実装するライブラリ oldnames.lib を提供しています。どちらの名前もまったく同じコードを指しています。したがって、物事が機能する限り、どちらの名前も使用できます (ただし、プロジェクトをリンクするように設定する必要がある場合がありますoldnames.lib)。

古い名前を使用する古い Windows コードを使用している場合は、リンクするだけで完了するのがおそらく最善だと思いますoldnames.lib

新しいコードの場合、新しい名前 (アンダースコアを使用し、oldnames.lib にリンクせずに) を使用する方がわずかに良いと思います。古い名前はマイクロソフトによって廃止されており、他のすべてが同じであれば、おそらくスケールが変わるはずです。また、コードを POSIX システムに移植したり、POSIX コードを Windows に移植したりする場合は、注意が必要な領域について警告を受ける可能性が高くなります。関数は POSIX バージョンと同じように見え、ほとんどの場合動作しますが、特にエラー処理において、わずかに異なる方法で使用する必要がある場合があります。

または、PDCurses のようなライブラリーを試すか、独自のラッパーを使用して移植性を提供することもできます。または、本当に Windows での POSIX 移植性が必要な場合は、Cygwin が選択肢になるかもしれません (Services for Unix はまだありますか?)。

同じ/類似した名前を持つ MSVC 関数と POSIX 関数の微妙な違いの例:

  • getch()Windows では、文字をエコーすることはなく、入力があるまで常にブロックされ、いくつかのキーを読み取るために複数回の呼び出しが必要であり、エラーを返すことはできません。これらの動作は POSIX とは異なります。
  • ungetch()Windows では、渡された文字またはEOFエラー時に文字を返します。POSIX では、OKまたはを返しますERR
于 2012-08-18T06:58:04.663 に答える
3

少なくとも私が認識している実装では、関数自体に違いはありません。実際、これらは通常、まったく同じ機能の 2 つの異なる名前です。

名前が 2 つある理由については、あまり良い名前がありません。マイクロソフトの誰かが、標準の要件をあまり注意深く読んでいないようで、誤解に基づいてかなり悪い決定を下したようです。

まず、getchは標準ヘッダーで宣言されていないため、名前を変更して1から始める必要はありません。第二に、名前を変更する必要があったとしても、_getchとにかく正しくありません。実装用に予約されている名前は、アンダースコアで始まり (彼らはその通りです)、その後に別のアンダースコアまたは大文字 (間違っていました) が続きます。 . 言い換えれば、彼らが名前を変更しようとしているなら、それは__getch、またはのいずれかであったはず_Getchですが、少なくとも標準が気にする限り、_getchプレーンと同じくらい悪いですgetch

それらのどちらかを選択する限り、私はそれを使用getchして終了します。を使用_getchすると、実際にはコードの移植性が (わずかに) 低下します。ほとんどの Unixesque システムで同じことを行うには、curses を使用します。これには、(ほぼ) 同じ作業を行う関数が含まれています。その名前はgetch. そのため、コードを移植する場合は、含めるヘッダーを変更する必要がありますが、名前getchは実際に引き続き機能する数少ないヘッダーの 1 つです。ただし、インタラクティブな I/O を頻繁に行う場合は、おそらく他のコードをかなり書き直す必要があります。


1まあ、そんなはずはない。16 ビット時代には、Microsoft のリンカ/noeには、追加のスイッチ ( ) または定義した名前の重複を渡す必要があり、リンクしているライブラリで定義された名前がエラーになるという小さな問題がありました。そのため、標準的な名前だけでなく、ライブラリ内の何かと同じ名前が使用されている場合、リンクするコードを取得するために追加のスイッチを渡す必要がありました。かなり古い歴史ですが。

于 2012-08-17T16:05:03.600 に答える