1

做什么

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

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

返回?

我的目标是包含t1 到 10 个。

4

6 回答 6

7

不要将断言与用户输入一起使用。Assert 旨在通过使您的程序崩溃来捕获逻辑错误(如果断言失败,则通过调用 abort),并且用户输入不应使您的程序崩溃。

但是要回答您的问题,如果定义了 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.

上面的代码看起来应该是显而易见的。断言的表达式(显然)正确的,但更重要的是,任何其他结果都是 insane。学习这t != 9将消除你对 C++ 如何工作、计算机如何执行数学和存储值、我们是否存在或意识是否只是由如此多的加重电子形成的幻觉的所有假设......</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

这是我期望的答案:

指定

#include <assert.h> 

在源文件开头的单独行中。

现在,只要 bool 不为真,您就可以使用 assert(bool) 来终止您的程序。

(其他答案是关于这个问题:“如何正确使用断言”)

于 2014-10-30T10:41:21.627 回答
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 回答
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 回答