C Fundamentals - Part 1

C Fundamentals - Part 1

Introduction to the most powerful low-level programming language - C.
This article sums up the basics of C and is intended for people who already know something about programming and want to start learning C, for people who want to refresh their memories of this programming language and for tech students.
cover

Covered subjects are:
Motivation | Hello World | Cheat Sheet | Control Statements | Input/Output

Why C? 

  • C is an universal and powerful low-level programming language
  • UNIX system, Linux and Windows Kernel are written in C
  • over 80% devices, embedded systems and IoT are programmed in C
  • C is known as the father of almost any modern programming language
  • many modern languages (PHP, Python, ...) are written in C and many other (C++, C#, Java, ...) are strongly influenced by C
  • C is one of the fastest and most powerful languages
  • most technical universities in the world teaches C
  • once you fully understand C, you will understand how computers works and you will be able to learn any other programming language in no time    

Before we start

 It's important to mention some pre-preparations and tools needed to write basic C programs, such as:     

  • text editor or IDE (recommended are Atom, Visual Studio Code or Code::Blocks), if you work on Windows platform, then Microsoft Visual Studio, Dev C/C++ or Code::Blocks.
  • compiler (gcc/g++, if you work on UNIX or Linux, these compilers should be already built-in), if you work on Windows platform, mentioned IDE should already contain some C compiler. If not, you can download gcc from here
    To compile our program just run gcc main.c in terminal
  • we will be using only Standard C library and Linux system in our examples, and so please note that we won't be using functions from conio.h nor any other Windows library if you are used to them

Hello World break down

After creating a C file (main.c) in our text editor (IDE), the very basic structure of a C code would look like this:      

#include <stdio.h>

int main ( void ) {

    printf("Hello world!\n");

    return 0;
}

Now let's break down each part of the code (non beginners are to skip this part):     

#include <stdio.h> // Header file - standard input/output

/**
 * Main function
 * This function is the first one to be called after executing our C program
 * @parameter is either void (can be left blank) or contains command line arguments
 * in that case it would look like:
 * int main(int argc, char *argv[])
**/
int main ( void ) {

    printf("Hello world!\n"); // Function (stored in stdio.h) to print a string into standard output, \n prints newline

    return 0; // int main() is a function, so it has to return an integer value
}

Cheat sheet

Cheat sheet, in other words, everything you need to know.

Data types

data type   |   description         |   range
-------------------------------------------
char        |   ASCII character     |   (signed) -128 to 127 or (unsigned) 0 to 255
short       |   2 bytes integer     |   (signed) -32 768 to 32 767 or (unsigned) 0 to 65 5635
int         |   2 or 4 bytes integer|   short or long (depends on compiler)
long        |   4 bytes integer     |   (signed) -2 174 483 648 to 2 147 483 647 or (unsigned) 0 to 4 294 967 295
long long   |   8 bytes integer     |   (signed) -2^63+1 to +2^63-1 (unsigned) 0 to +2^64-1
float       |   floating-point (4B) |   1.2*10^-38 to 3.4*10^+38 (6 decimal places)
double      |   floating-point (8B) |   2.3*10^-308 to 1.7*10^+308 (15 decimal places)
long double |   floating-point (10B)|   3.4*10^-4932 to 1.1*10^+4932 (19 decimal places)

Note: yes, C doesn't have string type. To create a string in C, you have to create an array of characters char*.

Also, short is the same as short int and is the same as signed short int. The same goes for long. If not defined, the type will be automatically signed.

Arithmetic operators

operator	|	description				|	example
------------------------------------------------------------
+			|	addition				|	i = 5 + 3; (i is 8)
-			|	subtraction				|	i = 5 - 3; (i is 2)
*			|	multiplication			|	i = 5 * 3; (i is 15)
/			|	division				|	i = 9 / 3; (i is 3)
%			|	modulation division		|	i = 5 % 2; (i is 1)
++			|	increment (i = i + 1)	| 	i = 0; i++; (i is 1)
--			|	decrement (i = i - 1)	| 	i = 5; i--; (i is 4)

Operators can be also used in a short way:

i += 5; // the same as i = i + 5;
i /= 5; // the same as i = i / 5;
...

Also, be careful when dividing. The result can be either integer or real number depending on data types you divide:

data types		|	result	|	example
-----------------------------------------------------
int/int			| 	int		|	int i = 10; int j = 3; 		i/j = 3
int/double 		|	real	|	int i = 10; double j = 3; 	i/j = 3.333...
double/double 	|	real	|	double i = 10; double j = 3; i/j = 3.333...
double/int 		|	real	|	double i = 10; int j = 3;	i/j = 3.333...

increment/decrement:

operator	|	description				|	example	
----------------------------------------------------------------------------
++i			|	increment before usage	|	i = 0; j = ++i; (i = 1 and j = 1)
i++			| 	increment after usage	|	i = 0; j = i++; (i = 1 and j = 0)
--i			|	decrement before usage	|	i = 5; j = --i; (i = 4 and j = 4)
i--			| 	decrement after usage	|	i = 5; j = i--; (i = 4 and j = 5)

Bitwise operators

operator	|	description				|	example
----------------------------------------------------------------------
<<			|	bit shift to the left	|	i = 5; i <<= 1; (i is 10)
>>			|	bit shift to the right	|	i = 10; i >>= 1; (i is 5)
&			|	bitwise AND				|	i = 1 & 2;	(i is 0) NOTE: & is different from && which is logical AND
|			|	bitwise OR				|	i = 1 | 2; 	(i is 3) NOTE: | is different from || which is logical OR
~			|	bitwise complement		|	i = ~5; (i is -6)

To work with bitwise operators, you need to understand binary first. 

Let's write a calculator

The best way to start is to write a simple calculator, don't you agree?

It will help us to learn working with the arithmetic operators and data types mentioned in the Cheat Sheets.      

int x = 50; 
int y = 30;

printf("The sum of %d and %d is %d\n", x, y, (x + y));

printf("The difference of %d and %d is %d\n", x, y, (x - y));

printf("The product of %d and %d is %d\n", x, y, (x * y));

if (y == 0) { // if second number is 0, we print error
    printf("Division by zero!\n");
}
else { // else, we print result as floating-point
    printf("The quotient of %d and %d is %lf\n", x, y, ((double)x / y)); // casted x to double for real number result
}

This is a simple "calculator" that will be improved later and the output would look like this:   

The sum of 50 and 30 is 80
The difference of 50 and 30 is 20
The product of 50 and 30 is 1500
The quotient of 50 and 30 is 1.666667

Looks confusing? Let me explain..    

The first argument of our printf() function is the string to be printed, however we can also print the values of our variables by inserting format specifier (%d) in the string and putting our wanted variable as the next argument - in this case an integer. In the case of division, I used %lf instead of %d, because I wanted to print the result as a floating-point (double in this case) whereas x and y are both integers. For the complete list of the format specifiers, please have a look at the following table:

specifier   |   description             |   data type           |   example
-------------------------------------------------------------------------------
%c          |   ASCII character         |   char                |   'a'
%s          |   string                  |   char*               |   "Hello, world!"
%hi         |   short signed int        |   short               |   -5000
%hu         |   short unsigned int      |   unsigned short      |   64000
%i or %d    |   signed integer          |   int                 |   5000000
%u          |   unsigned int            |   unsigned int        |   5000000
%li         |   long signed int         |   long                |   -2000000000
%lu         |   long unsigned int       |   unsigned long       |   4000000000
%lli        |   long long signed int    |   long long           |   -5000000000
%llu        |   long long unsigned int  |   unsigned long long  |   5000000000
%f or %F    |   digital notation        |   float               |   1.200000
%g or %G    |   scientifit notation     |   float               |   1.2
%e or %E    |   scientifit notation     |   float               |   1.200000e+00
%a or %A    |   scientifit notation     |   float               |   0x1.333334p+0
%lf or %lF  |   digital notation        |   double              |   1.200000
%lg or %lG  |   scientifit notation     |   double              |   1.2
%le or %lE  |   scientifit notation     |   double              |   1.200000e+00
%la or %lA  |   scientifit notation     |   double              |   0x1.3333333333333p+0
%x or %X    |   hexadecimal             |                       |   1A2C
%o          |   octal                   |                       |   065
%p          |   pointer address         |                       |   0x145484

To print a special character such as % in our output, we just need to backslash it:

printf("\n"); // prints newline
printf("\\n"); // prints "\n"
printf("%"); // throws warning, prints nothing
printf("\%"); // prints "%"
printf("\\"); // prints "\"

Control statements

These control statements are very similar or the same in any other programming language so if you are not a beginner, you are to skip this part as well. The statements are:

if | else if | else
switch
for
while
do while

With these statements we can control the flow of the program and execute certain part of it if a certain condition is met etc..

Let's demonstrate it on a quick example:

#include <stdio.h>

int main ( void ) {

    /* Some variable declarations */
    int temperature = 30; // outside temperature in °C
    double sunny = 0.3; // 0 - overcast, 1 - very sunny
    typedef enum { YES, MAYBE, NO } myBool; // C doesn't have boolean data type, so let's create our own
    myBool raining = NO; // is it raining?
    myBool willGoOutside = MAYBE; // will I go outside?
    myBool didIGetCandy = NO; // did I get a candy?

    /* IF-ELSE statements */
    if (temperature < 10) {
        willGoOutside = NO;
    } 
    else if (temperature >= 20 && temperature <= 30) {
        if (sunny < 0.5 || raining == NO) {
            willGoOutside = NO;
        }
        else {
            willGoOutside = YES;
        }
    }
    else {
        willGoOutside = MAYBE;
    }

    /* SWITCH statement */
    switch (willGoOutside) {
        case YES: printf("I will go outside.\n"); break;
        case MAYBE: printf("I don't know if I will go outside or not yet\n"); break;
        case NO: printf("I am not going outside.\n"); break;
        default: printf("Well... this won't happen."); // No need to put break; in last case
    }

    /* WHILE loop */
    while (didIGetCandy == NO) { // Endless loop
        printf("GIVE ME CANDY!\n");
    }

    /* DO-WHILE loop */
    do {
        printf("GIVE ME CANDY!\n");
    } while (didIGetCandy == NO); // This will print GIVE ME CANDY once even if didIGetCandy was YES

    /* FOR loop */
    for (int i = 0; i < 50; i++) { // Executes 50 times
        printf("Thank you!\n");
    }    

    return 0;
}

There is no real sense in this code so don't try to think about it much. It's just to demonstrate the usage of these statements.

If you don't know what is enum as I didn't mention it in the data types cheat sheet, enum is a custom data type that can contains only given constant values. In this case, I created a data type called myBool consisting only of values YES, MAYBE and NO. The keyword typedef is so I don't have to write they keyword enum before every myBool declaration. In other words, enum is our own defined data type.

Input

Reading and working with user's input.

getchar()

The easiest way of reading user's input is with getchar() function that reads the first character from standard input:

char c;

printf("Enter character: ");
c = getchar();
printf("Your character is %c\n", c);

results:

Enter character: a
Your character is a
Enter character: hello
Your character is h

As you can see, this function only reads the first and only one character of the input. To read the whole line, we will need to run this function in a loop until it meets the <Enter> key:

char c;

printf("Enter text: ");

while (c != '\n') { // \n represents newline
    c = getchar();
    printf("%c", c);
}

output of the above code:

Enter text: hello world!
hello world!

Now, let's improve our calculator with this function!

#include <stdio.h>

int main ( void ) {
    
    char c, op;
    int x = 0;
    int y = 0;

    printf("Enter first number: ");
    while (c != '\n') { // while reading the whole line
        c = getchar();
        if (c != '\n') { // if the character isn't a newline
            x = x * 10 + (c - '0'); // (c - '0') converts ASCII character to integer
            // this equation creates a single number from many inputted numbers
            // for example [1], [5] and [0]: 
            // 0 * 10 + 1 = 1
            // 1 * 10 + 5 = 15
            // 15 * 10 + 0 = 150
        }
    }

    printf("Enter operand (+, -, *, /): ");
    op = getchar(); // reads operand
    if (op != '+' && op != '-' && op != '*' && op != '/') { // If operand is not valid
        printf("Error: wrong operand\n");
        return 1; // exit program
    }
    getchar(); // get (and 'delete') the newline after the operand

    printf("Enter second number: ");
    do { // Using do-while here because c is still a newline
        c = getchar();
        if (c != '\n') {
            y = y * 10 + (c - '0');
        }
    } while (c != '\n');

    // Printing results
    switch (op) {
        case '+': printf("The sum of %d and %d is %d\n", x, y, (x + y));                break;
        case '-': printf("The difference between %d and %d is %d\n", x, y, (x - y));    break;
        case '*': printf("The product of %d and %d is %d\n", x, y, (x * y));            break;
        case '/': 
            if (y == 0) {
                printf("Division by zero!\n");
                break;
            } else {
                printf("The quotient of %d and %d is %lf\n", x, y, ((double)x / y)); 
                break;
            }
    }

    return 0;
}

Even though this code is not perfect (number validation etc..), it still looks promising and should work fine. Let's test it out:

Enter first number: 5 
Enter operand (+, -, *, /): +
Enter second number: 20
The sum of 5 and 20 is 25

Enter first number: 1243
Enter operand (+, -, *, /): -
Enter second number: 200
The difference of 1243 and 200 is 1043

Enter first number: 3
Enter operand (+, -, *, /): *
Enter second number: 100
The product of 3 and 100 is 300

Enter first number: 150
Enter operand (+, -, *, /): /
Enter second number: 6
The quotient of 150 and 6 is 25.000000

Enter first number: 13
Enter operand (+, -, *, /): /
Enter second number: 0
Division by zero!

Enter first number: 10
Enter operand (+, -, *, /): /
Enter second number: 3
The quotient of 10 and 3 is 3.333333

Enter first number: 10
Enter operand (+, -, *, /): what       
Error: wrong operand

Yes, it works just fine.

scanf()

Another way of reading user's input is with the scanf() function, which also allows us to read the input in a formatted way using the format specifiers.

int i;
scanf("%d", &i);

First argument of the scanf() function defines the format of the input we ant to read and following arguments are the addresses where to store the input (that's why it's important to use &i instead of just i). We can easily rewrite our simple calculator using this function:

#include <stdio.h>

int main ( void ) {
    
    char c;
    int x, y;

    scanf("%d %c %d", &x, &c, &y); // first number - operand - second number

    switch (c) {
        case '+': printf("The sum of %d and %d is %d\n", x, y, (x + y)); break;
        case '-': printf("The difference of %d and %d is %d\n", x, y, (x - y)); break;
        case '*': printf("The product of %d and %d is %d\n", x, y, (x * y)); break;
        case '/': 
            if (y == 0) printf("Division by zero!\n");
            else printf("The quotient of %d and %d is %lf\n", x, y, ((double)x / y));
            break;
        default: printf("Wrong operand.\n"); break;
    }

    return 0;
}

Looks better than the first one right? Let's check out the results:

5+20
The sum of 5 and 20 is 25

1243 - 200
The difference of 1243 and 200 is 1043

3*100
The product of 3 and 100 is 300

150/6
The quotient of 150 and 6 is 25.000000

13/0
Division by zero!

10/3
The quotient of 10 and 3 is 3.333333

10 what
Wrong operand!

In order to make sure the inputted text format is valid to the one we wanted, it's important to know that this function actually returns the number of successfully filled items in the argument list. In this case, we should check for 3 as we wanted to fill 3 variables in our scanf() function:

if (scanf("%d %c %d", &x, &c, &y) != 3) {
    printf("Invalid format.\n");
    return -1;
}

result:

hello+59
Invalid format.

You may ask why to use getchar() if we can use scanf() which seems to be more elegant and better in many ways. Why did we even bother with the getchar() example?

Well, both of these functions are different and can have a better use in different cases than the other. It's always up to the programmer to think of the best solution and choose the best methods to approach it. Remember that no information is useless. It's always about how you will use it and work with it.

 

If you have any questions or comments regarding this article, contact us directly via our facebook page.

Read next part ---->