[C language] C Control Statements: Branching and Jumping (Chapter 7)


The seventh chapter in Stephen Prata’s C Primer Plus. I want to start with a suitable divisors.c program

For a given integer, you need to print all the integers by which the given number is divisible without a remainder; if there are no such divisors, a message should be displayed stating that the number is prime.

A prime number (prime) has exactly two different divisors: one and itself;
If there are more divisors - this is a composite number (composite).

The first version of the program is looking for prime numbers in the forehead, by enumeration of divisors:

 #include <stdio.h>

 int main(void)
 {

 int x;
 int n;
 int prime = 1;

 printf("Enter a number\n");

 while (scanf ("%d", &x) == 1)
        {
        for (n=2, prime=1; n <= x; n++)
                {
                 if (x % n == 0)
                        {
                        printf("%d divided by %d\n", x, n);
                        prime = 0;
                        }
                }
        if (prime == 1)
                 printf("%d is a prime number\n", x);

        printf("Enter another number or 'q' to quit\n");
        }


 return 0;
 }

Let’s improve it now: knowing that prime numbers can be calculated by brute force to the square root of n, we optimize the heart of the program. To better see the enumeration of values, we display the process of finding prime numbers (this will slow down the enumeration, but it will help us figure it out):

#include <stdio.h>

 int main(void)
 {

 int x;
 int n;
 int prime = 1;

 printf("Enter a number\n");

 while (scanf ("%d", &x) == 1)
        {
        for (n=2, prime=1; n*n <= x; n++)
                {
                printf("Trying %d*%d=%d\n", n, n, n*n);
                 if (x % n == 0)
                        {
                        printf("Ding! %d divided by %d and %d\n",
                                x, n, x/n);
                        prime = 0;
                        }
                }
        if (prime == 1)
                 printf("Nope. %d is a prime number\n", x);

        printf("Enter another number or 'q' to quit\n");
        }

 return 0;
 }

Output:

Enter a number
144
Trying 2*2=4
Ding! 144 divided by 2 and 72
Trying 3*3=9
Ding! 144 divided by 3 and 48
Trying 4*4=16
Ding! 144 divided by 4 and 36
Trying 5*5=25
Trying 6*6=36
Ding! 144 divided by 6 and 24
Trying 7*7=49
Trying 8*8=64
Ding! 144 divided by 8 and 18
Trying 9*9=81
Ding! 144 divided by 9 and 16
Trying 10*10=100
Trying 11*11=121
Trying 12*12=144
Ding! 144 divided by 12 and 12
Enter another number or 'q' to quit
15
Trying 2*2=4
Trying 3*3=9
Ding! 15 divided by 3 and 5
Enter another number or 'q' to quit

Hooray! Now it became clear what prime numbers are and how to find them 🙂

Well, the final touch – we will make sure that the line from the previous output “Ding! 144 divided by 12 and 12” does not duplicate the square of the desired number. To do this, add a fork to the operator:

                 if (x % n == 0)
                        {
                        if ( n * n != x)
                           printf("Ding! %d divided by %d and %d\n",
                           x, n, x/n);
                        else
                                printf("Ding! %d divided by %d\n",
                                x, n);
                        prime = 0;
                        }

That’s all! 🙂 Long live prime numbers!

Next.. The following program, which caused me some difficulties in compiling it, seems to be elementary. Count the number of words, what could be easier? But it was not there. In this program, I smoked for a long time how to work with flags. At first I made a program, without flags, but it actually counted spaces, not words.. Here is the correct version:

#include <stdio.h>
#include <ctype.h>

 int main(void)
 {

 int symbol = 0;
 int line = 0;
 int word = 0;
 char ch;
 int flag = 0;

 printf("Enter text for analysis (or | to exit)\n");

 while ((ch = getchar()) != '|')
        {
        symbol++;
        if (ch == '\n')
                line++;
        if (!isspace(ch) && flag==0) // not space and no flag
                {
                word++;              // count word
                flag=1;              // assign flag (checked!)
                }
        if (isspace(ch) && flag==1) // if space and got flag
                flag=0;             // remove flag

        }
 printf("Symbols: %d; Lines: %d; words: %d\n", symbol, line, word);


 return 0;
 }
Enter text for analysis (or | to exit)
Beliy sneg
Seriy led
192.168.0.1
|
Symbols: 33; Lines: 3; words: 5

I didn’t put getchars at the bottom, because. ran it in the console.

I understood the essence of the flags in this program – this is a kind of “tick”, a checkpoint – like “passed” or “done”. I somehow perceived the flags the other way around before. It probably doesn’t matter how they are perceived, in principle … But with my initial approach, the program had to be started already flagged in 1; which is not good from the point of view of logic. Learn to think differently 🙂

Now the program for painting works, hehe.

How many cans of paint are needed to cover a given number of square feet of surface. The basic algorithm is simple: divide the total number of square feet by the number of square feet that can be dyed with the contents of one can. However, let’s assume the answer is 1.7 cans. You can only buy full cans in the store, not partially filled cans, so you have to purchase two cans…

#include <stdio.h>

 int main(void)
 {

 int can;
 int area;
 int rate = 15; // one can used for 15m2 of wall

 printf("Enter how much meters do you need to paint\n");

 while (scanf ("%d", &area) == 1) // enter m2
        {
        can = area / rate;
        // how much cans do we need to paint it

        can += ((area % rate == 0 )) ? 0 : 1;
        // we can't leave part of wall unpainted

        printf("To paint %d m2 you need %d %s\n",
                area, can,can == 1 ? "can" : "cans");
        printf("Enter another area value (or 'q' to quit)\n");
        }

 getchar(); getchar();
 return 0;
 }
Enter how much meters do you need to paint
121
To paint 121 m2 you need 9 cans
Enter another area value (or 'q' to quit)
994
To paint 994 m2 you need 67 cans
Enter another area value (or 'q' to quit)
4
To paint 4 m2 you need 1 can
Enter another area value (or 'q' to quit)

Painted!

Now the scoring program, which also intelligently searches for the minimum and maximum value.

#include <stdio.h>
#define MIN 0.0f
#define MAX 100.0f

 int main(void)
 {

 float score;
 float total = 0.0f;
 int n = 0;
 float min = MAX;
 float max = MIN;

 printf("Enter results:\n");

 while (scanf("%f", &score) == 1)
 {
        if (score < MIN || score > MAX)
        {
                printf("%0.1f - wrong value\n", score);
                continue;
        }
 printf("Getting %0.1f\n", score);
 min = (score < min)? score: min; 
 max = (score > max)? score: max; 
 total +=score;
 n++;
 }
 if (n>0)
 {      printf("Average value for %d results is %0.1f\n",
                n, total/n);
        printf("Low = %0.1f, high = %0.1f\n", min, max);
 }
 else
        printf("Correct results weren't entered\n");


 getchar(); getchar();  getchar(); 
 return 0;
 }
Enter results:
32
Getting 32.0
96
Getting 96.0
11
Getting 11.0
123
123.0 - wrong value
491
491.0 - wrong value
1
Getting 1.0
Average value for 4 results is 35.0
Low = 1.0, high = 96.0

The tricky part here is the initial conditions (and not the ‘continue’ operator itself, to which this program is dedicated). The conditions are:

float min = MAX;
float max = MIN;

When I see this, I have a humanitarian cognitive dissonance. In fact, this is necessary in order to find the minimum and maximum values – so that the first comparison of min’imum is compared with the maximum value (suddenly you enter 99), and it hits exactly. The same applies to max.

The following program reads a letter and responds with the name of the animal,
which starts with this letter:

#include <stdio.h>
#include <ctype.h>

int main(void)
{

 char ch;

 printf("Please enter lowercase letter (a-e):\n");

 while ((ch = getchar()) != '#')
 {
    if (islower(ch))
        switch (ch)
        {
            case 'a' :
                printf("antelope, wild african deer\n");
                break;
            case 'b' :
                printf("beaver, big water rodent\n");
                break;
            case 'c' :
                printf("cat, got pawns, tail and whiskers\n");
                break;
            case 'd' :
                printf("dog, domesticated wolf\n");
                break;
            case 'e' :
                printf("elephant, biggest land mammal\n");
                break;
            default :
                printf("Donno such animal yet..\n");
        }
    else
        printf("I know only lowercase letters\n");
 while (getchar() != '\n')
    continue;
 printf("Please enter another letter or # to quit\n");
 }
 printf("Bye!");


getchar(); getchar();
return 0;
}
Please enter lowercase letter (a-e):
a
antelope, wild african deer
Please enter another letter or # to quit
b
beaver, big water rodent
Please enter another letter or # to quit
q
Donno such animal yet..
Please enter another letter or # to quit
B
I know only lowercase letters
Please enter another letter or # to quit
d
dog, domesticated wolf
Please enter another letter or # to quit
#
Bye!

In this program, in addition to switch, case and while (getchar() != '\n') continue; interesting is the function (islower(ch)). Initially, when I wrote this program, I used (islower(ch))==1 and it didn’t work. Using the printf output, I realized that (islower(ch)) outputs 2 if the input is a lowercase letter and 0 if an uppercase letter is entered; i.e true in this function is not 1 (well, 2 is also true when checking the function). Curious 🙂

[catlist]


This entry was posted in C language (en). Bookmark the permalink.

Leave a Reply

🇬🇧 Attention! Comments with URLs are not allowed.
🇷🇺 Комментарии со ссылками удаляются автоматически.