Introduction to C

From Applied Science
Revision as of 00:05, 15 April 2022 by Wikiadmin (talk | contribs)

Because the discipline is an introduction, the algorithms studied doesn't use the most advanced features of C. A lot of things aren't studied in this course, just the most elementary to understand how a program is executed. Due to the similarities between mathematics and even spoken language, you just have to read a code carefully to understand the order of the operations.


A short summary about the C language


  • Keywords. They are reserved words, have a fixed and unchangeable meaning. For example: a function or variable cannot be named 'while', because 'while' already has a fixed meaning. The exception is text, we can print the word 'while' on screen because in this case, the word is treated as a char sequence, not as a command. The same applies for symbols such as commas and semicolons, the meaning is fixed and it must be used as pre-determined by the language's syntax.
  • The assignment operation. In the very beginning, to read a = 2 as "a is equal to two" is ok, because the variable 'a' has the value two after the assignment. But when we do arithmetic operations, then we have to read the assignment operation properly: "the value two is assigned to the variable a".

    For example:
    a = b + c;

    This is read right to left, first the operation 'b + c' is processed, then the resulting value is assigned to the variable 'a.
  • Variable declaration. It would be boring to program having to memorize memory positions all the time. To provide a more comfortable way of using the computer's memory the programming language exposes for us the variable's names, much easier to understand and to memorize than numerical codes. The var needs a type, else it would be confusing to have all variables with just one type for all. An analogy: it'd be confusing to store liquids in boxes and it'd be a waste to use a very large box to store a very small object.

/* Variable declaration */
int var;
float var2;
double var3;

/* Variable declaration including assignment of some value */
int var = 2;
float var2 = 4.5;

/* Precision loss, the digits of the non integer part are lost */
int var = 2.5;

/* Mixing types. The type with the highest precision dominates the expression. In this example, float has preference over the integer 2. The result of this operation is 2.5 */
float a;
float b = 5;
int c = 2;
a = b/c;

/* Special case of dominance: even though the var "a" is float, the result is going to be 2.0 because the quotient operation is done first and with integers, the assignment operation is done later. */
float a;
int b = 5;
int c = 2;
a = b/c;

  • The comma ','. In the same way we separate examples of a list with commas, variables are separated with commas in a program. They are also used to separate parameters and arguments of a function. The compiler doesn't "see" blank spaces, therefore int a,b,c; declares 3 variables of the int type, the absence or not of blank spaces before or after the commas is a matter of readability.
  • The semicolon';'. It's used to end a line, a command.

Practical example:
a = c + 3
+ d - 2;

Visually, the command has two lines, but to the compiler, the arithmetic expression above ends only at the semicolon in the second line. A not uncommon error is to place a semicolon where there shouldn't be one, which results in a command being prematurely interrupted.

Example:
/* the command is never going to be executed */
if (conditional);
command;

Another example:

/* it's permitted to write this way, but it's much worse for reading */
command_1;
command_2;
command_3;

  • Parenthesis '( )'. In functions and arithmetic expressions, they have the same meaning as in mathematics. In flow control commands, such as if and loops, the conditional must be enclosed by a pair of them. Take notice that the compiler doesn't "see" blank spaces, use spaces to make your code easier to read, but there is no compilation or execution damage caused by not using spaces.
  • Conditionals. Commands such as if and loops can only be executed if the conditional is true. It's common to confuse the '==' operator (logic equality) with '=' (assignment) in the beginning. Check the C's docs to know all the available operators.

    There is a subtle difference between the assignment operation and the logic equality. In the first, what is to the right is evaluated first. Whereas in the second, what is to the left is evaluated first. That evaluation order can cause some confusion, nothing really serious though, because those don't change the behaviour of the algorithms studied. Check the language's docs to know the operators' precedence. Take notice that the conditional doesn't make sense if placed outside a command, a == 2; alone doesn't produce any effect.
  • Ternary or conditional operator '?:': Some 'if ... else' statements can be rewritten with the conditional operator as follows:

(conditional expression) ? (expression 1) : (expression 2)

Which is read "is the condition true?". If answer is positive, "expression 1" is run, else, "expression 2" is run. Parenthesis aren't required if the expression is straight forward, but in case there are other operations (assignment, relational, logic, arithmetic) it's a good idea to use them to avoid confusion or compilation errors.

Side note: every conditional is an expression, but not every expression is a condition for something.

  • The curly brackets pair '{ }'. They enclose blocks of commands. They are required in functions and in flow control structures that have more than one command to execute. For example:

if (conditional) {command_1; command_2;}

Another example:

for (counter; expression; increment) if (conditional) {command_1; command_2;}

In this case, the 'for' didn't require brackets because there is just one command nested in it, which is the 'if'. The two commands, 1 and 2, are nested directly under the 'if', not under the 'for'. That's why the brackets are part of the 'if' block, not the 'for' block. If we would've kept the brackets, the the 'if' block could have been written in the same line as the for command.

  • The '#' (sharp) symbol. At the program header lies #include <library.h> and #define. Functions such as printf() and scanf() are defined in header files. Without them we cannot use functions which are defined in libraries that we didn't include, unless we define those functions in our program. Header files are meant to organize groups of functions. Not every function is going to be used, that's why there isn't just one header for all. Functions defined in headers are meant to be reused with ease. Because the algorithms studied in this introduction are simple, complex and large programs are not made, this type of function management is not studied.

#define YES 1#define NO 0

With defines we can replace 1 and 0, respectively, with YES and NO, this way it becomes easier to read the code.

  • Placeholders. In arithmetic expressions '%' means the remainder operation (the remainder is always integer). In the function printf() it's the placeholder.

Example:
printf("variable's value is %d", variable);

The placeholder '%d' will be replaced by the variable's value when printed. That's how "dynamic" texts are generated, texts that vary what is going to be printed on screen depending on variables' values. Check the C's docs to know all the "placeholders" available. A common error is to print a variable's value with the wrong placeholder, which causes the output to be wrong, even though the calculations done could have been correctly done; this can bring in some serious headache...