0

Recently I found some code that is very interesting to me, but I can't properly understand it, so can someone please explain it to me?

It's Conway's Game of Life. I think this row can be like a question and 1 meaning true and 0 meaning false; is that correct? But why is there no bool?

void iterGen(int WIDTH, int HEIGHT, char curMap[WIDTH][HEIGHT])
{
    int i, j;
    char tempMap[WIDTH][HEIGHT];

    for (i = 0; i < WIDTH; i++)
    {
        for (j = 0; j < HEIGHT; j++)
        {
            int neighbors = 0;
            neighbors += curMap[i+1][j+1] == '*' ? 1 : 0;
            neighbors += curMap[i+1][j] == '*' ? 1 : 0;
            neighbors += curMap[i+1][j-1] == '*' ? 1 : 0;
            neighbors += curMap[i][j+1] == '*' ? 1 : 0;
            neighbors += curMap[i][j-1] == '*' ? 1 : 0;
            neighbors += curMap[i-1][j+1] == '*' ? 1 : 0;
            neighbors += curMap[i-1][j] == '*' ? 1 : 0;
            neighbors += curMap[i-1][j-1] == '*' ? 1 : 0;

            if (curMap[i][j] == ' ')
            {
                tempMap[i][j] = neighbors == 3 ? '*' : ' ';
            }
            else if (curMap[i][j] == '*')
            {
                tempMap[i][j] = neighbors < 2 || neighbors > 3 ? ' ' : '*';
            }
        }
    }

    for (i = 0; i < WIDTH; i++)
    {
        for (j = 0; j < HEIGHT; j++)
        {
            curMap[i][j] = tempMap[i][j];
        }
    }
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Stacy
  • 31
  • 1
  • 1
    You mean lines like `neighbors += curMap[i+1][j+1] == '*' ? 1 : 0;`? That's just counting, either adding 1 or 0 to a sum depending on the content of the array. Could be rewritten as `if (curMap[i+1][j+1] == '*') neighbors += 1;` – Retired Ninja Dec 09 '22 at 02:28
  • 2
    Because you're learning, learn this: That code accesses (reads from) memory "outside" the boundaries of the defined array... The code does not account for the edges of the array, and may not perform as desired... Don't "shortcut" processing to write compact but incorrect code. – Fe2O3 Dec 09 '22 at 02:33
  • @RetiredNinja thank you very muuch!! Can you please explain why do we use temporary variable (char tempMap)? – Stacy Dec 09 '22 at 02:38
  • 3
    C does have a bool type. – ikegami Dec 09 '22 at 02:40
  • 1
    The `tempMap` holds the map for the new setup, based on the old setup (`curMap`). You can't modify `curMap` in situ — you have to create a new version with the old one untouched, and then copy the new over the old. – Jonathan Leffler Dec 09 '22 at 02:41
  • [How do I use the conditional (ternary) operator?](https://stackoverflow.com/questions/392932/how-do-i-use-the-conditional-ternary-operator) may help if you didn't know what the `? :` thing was called. – Retired Ninja Dec 09 '22 at 02:46
  • @Retired Ninja, Re "*may help if you didn't know what the ? : thing was called.*", Does it? It doesn't exactly make it clear that it's named "conditional operator" seeing as the title refers to it as "the conditional (ternary) operator" and that the first answer refers to it as "the ternary operator". – ikegami Dec 09 '22 at 02:49
  • This code may have been written before the `bool` type was added to the C language (in the 1999 revision of the C standard). Or it may have been written well _after_ the `bool` type was added to the official definition of the standard, but by someone who was still using a compiler that did not implement it. (Such compilers are still tripping people up _today_, if the gnulib mailing list is to be believed.) – zwol Dec 09 '22 at 02:59
  • @ikegami I've always heard it referred to as ternary. I find that having a name for something that can be difficult to search for helps. *shrug* – Retired Ninja Dec 09 '22 at 03:14
  • @Retired Ninja, It is *a* ternary operator (it has three operands), just like `==` is *a* binary operator (it has two operands) and `!` is *a* unary operator (it has one operand). Some languages even have nullary operators (no operands). But that's not their names. They are the conditional operator, the equal to operator and the logical negation operator respectively. – ikegami Dec 09 '22 at 03:59
  • @zwol, Or by someone who didn't see the point of using the `_Bool` type after using `int` for a million years. – ikegami Dec 09 '22 at 04:01
  • Too many times I have seen bugs introduced due to the assumption that any non-zero value can be considered true. It is a habit that you should resist. Always be explicit in logical operations. Always test against `!= 0`, it only takes a compiler or project change to dictate that `true` is `1` and your code can fall down. – ChrisBD Dec 09 '22 at 09:26

2 Answers2

2

Just like in most other languages, in C any value that is not 0 can be considered as true.

if ( 20 ) {
    // true
}
if ( -1 ) {
    // true
}

if ( 'c' ) {
    // true
}

if ( "string" ) {
    // true
}

if ( 0 ) {
    // false
}

if ( '\0' ) { // null terminator, a char with a value of 0
    // false
}

if ( NULL ) { // value of a null pointer constant
    // false
}

Bool is just a way to make code more readable.

dnl
  • 95
  • 7
-1

First, a couple of comments.

neighbors += curMap[...][...] == '*' ? 1 : 0

is a redundant way of writing

neighbors += curMap[...][...] == '*'

since the comparison operators already return 1 or 0.

But neither are as clear as

if ( curMap[...][...] == '*' ) ++neighbors;

1 meaning true and 0 meaning false; is that correct? But why is there no bool?

Not quite. 0 is false (including 0 as a pointer, NULL). All other values are true.


Now, on to the question.

But why there is no bool?

But there is: _Bool.

stdbool.h provides bool as an alias, as well as the macros true and false.

#include <stdbool.h>
#include <stdio.h>

bool flag = true;

if ( flag )
   printf( "True\n" );
else
   printf( "False\n" );

Demo on Compiler Explorer

Note that none of the variables in the snippet you posted are booleans, so I have no idea why that code was included in your question.

ikegami
  • 367,544
  • 15
  • 269
  • 518