1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

//__________________________________________________________________
// ASSERT
//
// assert(▒) is a function-like macro that is used to verify that a program is working correctly.
// ∙ If the argument is false (or 0), then the program stops right away.
// ∙ Otherwise, the program continues normally.
//
// Rules for using assert(▒):
// ∙ #include <assert.h>
// ∙ Argument can be any condition i.e., anything you could use in an if(…) statement.
//   ∘ assert(n == 3)
//   ∘ assert(array[i] == 5)
//   ∘ assert(n < i)
//   ∘ assert(n % 2 == 2)
//   ∘ assert(is_n_prime)
// ∙ Condition must be true, if and only if your program is working correctly.
// ∙ Condition must not depend on anything external, including files, user input, or parameters
//   from someone else's code (e.g., our tester).
// ∙ Use in either your implementation file or your test file.
// ∙ You do not have to remove assertions at the end.
//   ∘ Simply compile with -DNDEBUG
//   ∘ Assertions will not slow your code.
// ∙ Assertions should have no side effects.
//   ∘ ✘ assert( write_file(…) )          // BAD!!!
//   ∘ ✘ assert( clean_up_directory(…) )  // BAD!!!
//
//
// BENEFIT:  FIND BUGS EARLY AND CLOSE TO THE SOURCE
//
// BENEFIT:  assert(…) lets you write code that tests itself.  (credit: Writing Solid Code (?))
//
// BENEFIT:  assertions document your code while also testing it.


//__________________________________________________________________
// BOOL
//
// bool is a type that can be true or false.
// ∙ true is essentially a constant that equals 1.
// ∙ false is essentially a constant that equals 0.
//
// Use bool not int whenever you are referring to a value (or flag) that must be either true or false.
// You must have #include <stdbool.h> at the top of your file to use bool, true, and false.

bool is_prime(int n) {
    //bool is_n_prime = (n % 2) == 0;

    bool is_n_prime = true;  // Assume n is prime unless we find that it is divisible by something
                             // other than 1 or itself.

    // Try 2
    if(n % 2 == 0) {         // If n is evenly divisible by 2
        is_n_prime = false;
    }

    // Try all ODD numbers from 3 to n/2
    if(is_n_prime) {
        for(int divisor = 3; divisor < n / 2; divisor += 2) {
            assert(divisor % 2 == 1);  // "I claim that divisor must be odd."
            if(n % divisor == 0) {
                is_n_prime = false;
                break;
            }
        }
    }

    // Check correctness from INSIDE implementation code.

    assert(n == 2 || n % 2 == 1 || is_n_prime == false);  // "I claim that n cannot be prime and even unless n is 2."

    assert(n == 2 || n % 2 == 1 || ! is_n_prime);         // "I claim that n cannot be prime and even unless n is 2."

    return is_n_prime;
}


int main(int argc, char* argv[]) {
    assert( is_prime(3) );
    assert( is_prime(5) );
    assert( is_prime(7) );
    assert( is_prime(11) );
    assert( is_prime(13) );
    assert( ! is_prime(14) );

    // Use assert(…) to check return value of a “public” function
    // ∙ a “public” function is one that may be called by someone else, i.e., not a helper function
    assert( is_prime(2) );    // Translation:  "I claim that is_prime(2) must be true."
                              // This assertion fails, that is a GOOD thing because 2 is prime.
                              // and our code above has a bug.

    return EXIT_SUCCESS;
}
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 noexpandtab: */

© Copyright 2021 Alexander J. Quinn         This content is protected and may not be shared, uploaded, or distributed.