1

何をしますか

assert( scanf("%d", &t) == 1 ); 

assert( 1 <= t && t <= 10 ); 

戻る?

私の目標はt1から10までを含むことです。

4

6 に答える 6

7

ユーザー入力で assert を使用しないでください。Assert は、プログラムをクラッシュさせることによって (アサーションが失敗した場合に中止を呼び出すことによって) 論理エラーをキャッチするように設計されており、ユーザー入力によってプログラムがクラッシュすることはありません。

しかし、あなたの質問に答えるために、NDEBUG が定義されている場合、assert は何もしません。これが、プログラムが予期したとおりにクラッシュしない理由である可能性があります。

于 2012-10-14T21:53:52.267 に答える
7

assert は次のように宣言されていると想定できます。

/*!
 * Immediately crash the program if assumption is proven invalid.
 */
void assert (bool assumption);

tコードを書いたので、変数が [1, 10] の範囲外にならないことを「知っている」場合、コードが他の値を生成する方法がない場合は、そのステートメントをアサートするのが適切です。

明白なことを主張する

次のアサーションの使用を検討してください。

int t = 9;
assert (9 == t);   // A very valid assertion, if a little pedantic.

上記のコードは、明らかなことを述べているように見えるはずです。アサートされた式(明らかに) true ですが、さらに重要なことに、他の結果は insane になります。t != 9C++ がどのように機能するか、コンピューターがどのように計算を実行し、値を保存するか、人間が存在するかどうか、または意識が非常に多くの悪化した電子から形成された幻想にすぎないかどうかについてのすべての仮定を一掃する 学習.</p>

しかし、それがアサーションの価値です。

それでも、コンピュータはすべての実用的な目的で 100% 決定論的であり、「非常識な」こと起こります。それも珍しくありません。実際、コードにアサーションを明示的に記述して、これらの状況を検出し、何が起こったのかを把握する機会を与えています。ここで、常軌を逸した行動の実際の原因をいくつか考えてみましょう

「非常識」な行動の原因

アサーションでは、次のようなエラーを防ぐ 必要があります。</p>

  1. スレッドの同期が正しくありません。

    int t;
    
    // Thread 1
    t = 9;
    assert(t == 9);
    
    // Thread 2
    t = 3;
    assert(t == 3);
    
  2. 貧弱なメモリ管理。

    class X {
        void sayHello () {
            assert(this != NULL);   // An object that does not exist cannot say hello.
            std::cout << "Hello?" << std::endl;
        }
    };
    
    // Without the assertion, this code would actually run!
    X* x = NULL;
    x->sayHello();
    
  3. スタック (またはヒープ) の破損。

    (妥当な例については、C++ でのスタックの破損を参照してください。)

不便ではあるが正気ではない行動:

プログラムの実行パスを大幅に変更する可能性がありますが、これらはアサーションには不適切です。例外をスローし、エラーを出力し、プログラムを適切に閉じ、プログラムのリソースを責任を持ってクリーンアップします。これらの「失敗」に対して主張しないでください。

  1. ユーザーがばかげたことを入力します。

    int t;
    scanf("%d", &t);
    assert ( 0 <= t <= 10 );       // What, are you friends with this user?
                                   // You're going to let him crash your program?
    
  2. 一部の I/O デバイスに障害が発生しました。

    int s = socket();
    // blah blah connect blah blah
    
    char buffer[64];
    int bytes_received = recv(s, buffer, 64, NULL);
    assert (bytes_received > 0);   // Do you know how hard it is to send a packet
                                   // from Estonia to the US?!
    

このリストは不完全ですが、アサーションを適用する方法 (および適用しない方法) に関するより広範なガイドを提供するはずです。

于 2012-10-14T22:40:30.187 に答える
1

Assertは何も返しません。パラメータがfalseの場合、プログラムは終了します。アサートは、起こり得ないはずの状況を対象としています...しかし、誤解した場合などに備えてチェックします。

http://www.cplusplus.com/reference/clibrary/cassert/assert/

于 2012-10-14T21:51:07.400 に答える
1
assert( expression );​

assertが行うことはを評価することであり、評価するものが0 / falseと比較される場合、プログラムは終了します。

于 2012-10-14T21:51:51.313 に答える
1

これは私が期待する種類の答えです:

指定する

#include <assert.h> 

ソースファイルの先頭の別の行に。

これで、bool が true でないときはいつでも assert(bool) を使用してプログラムを終了できます。

(他の回答は、「アサートを適切に使用する方法」という質問に関するものです)

于 2014-10-30T10:41:21.627 に答える
0

問題の適切な解決策はscanf()、関数が何をしているのかを知っている関数にカプセル化することです。

int AskNumberOfWidgetFrobs() {
  int count = 0;
  for(;;) // Until we get a valid number
    scanf("%d", &count);
     if (count > 0 && count <= 10) {
       return count;
    } else {
       printf("%d is not a valid number of WidgetFrobs\n", count);
    }
  }
}
于 2012-10-15T08:20:23.710 に答える