📜 ⬆️ ⬇️

Keep it simple, and people will reach out to you, or how to fall in love with C, keeping your sanity

I am self-taught in life: short of FORTRAN and PL / 1, which I was “taught” at the university (I hope it is clear how long it was?), I received most of my programming knowledge solely through self-education. I started, as usual, with Pascal and its logical continuation Delphi. As priorities changed, I mastered the 86th family assembler (MS DOS), and then, as I became interested in microcontrollers, I mastered ASM51 and AVR Assembler. All this was given to me quite simply, because All of the above is amenable to a very simple and, most importantly, clearly structured logical description - I mean the syntax and principles of the language.

The next step was naturally inevitable - the transition to C (let me emphasize - in my case, it’s about the programming of microcontrollers), and then, as they say, the process is stalled. Syntax C is one more thing, books on this language are a separate song. Even among the classics of K & R, from the very first chapter, a “working helloword” collapses on the fragile brain of a beginner, despite the fact that not a single word about syntax, operators, etc. it was not said! When I began to study the standard of the C language, I had a suicidal depressive state, because the concept of the standard, which had been settled in the brain before, was almost completely destroyed!

And so I prepared for myself some “rules of reduction to logically consistent definitions,” which allowed me to more or less easily master the C language and even sometimes (!) Teach other beginners.
It seems to me that beginners to master C will not prevent to learn at least about one such "rule".

I tried to use the existing sense of humor - I recommend not turning it off when reading.
')
For a start, it will be about the seemingly simplest: data types and the description of variables of these types.
Everyone knows that the description is int var; describes a var variable of type int , respectively, an extended description of int var1, var2, var3; already describes three variables of the same type. Common sense and life experience suggest that a description of a variable or several variables consists of two parts: the first place is the type identifier (int), and then, separated by a space, one or more (comma-separated list) variable identifiers .
All right, and so far everything is clear. But C allows us to add some prefixes to the description of variables, for example, const , meaning that the variable should not change its value. By the way, there are other prefixes, for example, auto , but it is not about them now. And surprisingly, the prefix can stand before the type and after it:
const int var1;
and
int const var1;
completely identical entries.

I do not know about you, but my brain starts to twist the curves with disgust, because It does not work out a clear rule for describing variables, as mentioned earlier (see highlighted text above). Something of the type is obtained: the variable description consists in the fact that before its identifier or list of identifiers separated by spaces may contain type identifiers and / or a prefix indicating the features of the use and use of the variable. Please note that I wrote can be located and used a union or - this is actually the case: the C language assumes the absence of a variable type identifier, in this case the default type is considered to be int . Those. The following entry is also allowed: const var;

We try to go smoothly to the signs.
const int * var; - pointer to a variable that can not change the value.
int const * var; - a pointer that cannot change its value to the variable int, which can ...

Your brain has not exploded yet? My survival was only due to the cooling compress: it just seemed that the type and prefix could be placed relative to each other in an arbitrary order, and now it turns out that the order significantly changes the meaning of the description! Yes, and the correct reading of the string int const * var; not from left to right, not from right to left, but with some kind of spiral: we start from the middle (pointer, i.e. *), then go left (const, i.e., the pointer does not change the value), then to the right (remember the variable identifier var ), and then left again (type of variable is int). Brrr ...

And now try to describe without errors the pointer, which does not change its value, to a pointer, which may change, indicating an immutable variable of type int ... What is that ?! I think at this stage a lot of beginners threw a book on C at the wall and went to drink beer.

And this we have not yet taken for pointers to functions, arrays of pointers, pointers to arrays of pointers to functions ...
In general, this terrible thing - the language of C! On the one hand, it requires clarity in expressing one’s thoughts from a programmer, on the other, one can use so many possibilities, assumptions, permissions and options, that it’s just difficult to retain this very clarity of thoughts ... And even the favorite occupation of most authors of C books is to list all of these (I’m Not all options and nuances mentioned!) Options with comments in the same spirit: C sets the following procedure ..., but if ..., it is allowed ..., although this ... the rule changes to ... - instead of dots, substitute the necessary e.

Of course, I understand that C is a tool of wide opportunities, and, probably, each of the possibilities and each of the nuances serve to achieve some truly important goals, but not everyone should be a guru! How to be an ordinary person for whom programming is a hobby?

I propose to use one of the possibilities of the C language, which, if correctly applied, will allow you to maintain your sanity and at the same time achieve the desired results, no matter how complex they are. This feature is called defining custom data types .

Proper use of this feature, from my point of view, lies in the simple observance of a single rule: avoid descriptions of types of two or more of the following key words (identifiers). Thus, you should aim for the only form of a variable definition: on the left is one type identifier, separated by a space to the right - an identifier or a list of variable identifiers. All other options allowed by the language we [humbly and voluntarily] are excluded from use.

In practice, it looks like this.
const int var ; - for the description it is necessary to use 2 identifiers, i.e. our case. We introduce a new type for this:
typedef const int const_int;
B definition of our variable turns into perfect
const_int var;
strictly according to our rule.

Such a record is read absolutely unequivocally, and the only thing that requires additional efforts is to view the definition of the const_int type. Obviously, with proper selection of the type identifier, its meaning becomes clear without comments, but even finding a string with the appropriate typedef will not put us in a dead end, because A string with typedef is read in the same simple and easy way. By the way, when entering a new type, it is also desirable to avoid too multi-story entries, but here as it already happens, there is no ideal in our world.

If we want to define a pointer to this new type, we can write
const_int * var; and it will be as simple and unambiguous, but we can also introduce a new type:
typedef const_int * const_int_ptr;
and get the "perfect" record
const_int_ptr var;

Now let us recall the description that entered into a stupor earlier: a pointer that does not change its value to a pointer that can change, indicating an immutable variable of type int. Taking into account what has just been done, it will turn out like this:
typedef const int const_int; // immutable variable int
typedef const_int * const_int_ptr; // pointer (changeable) to an immutable variable int
typedef const const_int_ptr * const_ptr; // unchangeable pointer to previous pointer
here you can stop, but you can continue:
const_ptr var; // this is the final variable description

Is it difficult to understand? As from my point of view, it is much easier than loading all these prefixes-suffixes into one line ... Entering new types will make life easier if you need to transfer data of these types as function parameters or return them as a result.

What am I calling for? Why, that's what: fellow programmers and those who want to become them! Keep it simple, do not boast your knowledge of the depths of C and do not dive into these depths unnecessarily, limit yourself to the simplest (both in recording and in perception) constructions to achieve your goals! And then people will reach out to you!

Source: https://habr.com/ru/post/264585/


All Articles