Question: coders. I'm learning C programming language and found out such thing as `#define` directive that allows us to use *symbolic constants* (following Brain Kernigan). I know that this directives "insert" literals or expressions right into code. Their purpose, as I understood for now, to get rid of *magic numbers* in a code. Also I found out that `#define` directives also can't be accessed out of the scope they were declared. That fact makes their usage is very similar to classic variables. My questions to experienced programmers is "What and when should I use? What pros and cons of each mechanism?". At the first glance, I can use them interchangeably. Thank you.

Answer: 
You should never use the preprocessor to define symbolic constants. C has had the `const` keyword since C90, which does the same thing and makes your intent clearer. It also provides better scoping (preprocessor definitions always have file scope, while normal declarations have the scope you'd expect from their location).
Use "variables" (as `const` objects) when practical.

Better type control.

---

Use symbolic constants in select cases.

Examples:

**`*scanf()` width control**

Consider reading into a buffer of some fixed size via `*scanf()` to form a *string*. `"%s"` deserves a *width*, like `"%79s"` to prevent buffer overflow. Rather than a magic number in the format, derive the buffer size and width via a `#define STRING_LEN_MAX 79`.

```
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

#define STRING_LEN_MAX 79
char buffer[STRING_LEN_MAX + 1];

if (scanf("%" TOSTRING(STRING_LEN_MAX) "s", buffer) == 1) {
  puts("success");
}

```

**Values meant for macro processing**