Introduction to C programming

 c tutorials |  Admin

What is C

C is a computer programming language developed at AT & T’s Bell Laboratories of USA in 1972.

C was invented by Dennis Ritchie on a DEC PDP-11 (a 16 bit mini-computer that used the UNIX operating system).

There are three levels of programming and these are High-level, Middle level (also called Machine level) and low level (also called assembly). C has nearly both features of High-level and low level so it is basically a Middle level language.   

C is also called systems programming language because it is used for creating operating systems and a portion of the operating system of the computer or its support utilities.

How C works

Basically most programming languages uses a compiler to reads the entire program (source code or block of script) and converts it into object code (also called as binary code or machine code). Once a program is compiled, it can be executed directly without use of the source code. C compiler reads the entire source code of C language and translates it in object code then from the object code an executable file is created according to the system (e.g. operating system and processor architecture) by a program called as Linker.


Linker is a computer program that takes one or more object files generated by compiler as an input and combines them into a single executable file.

[Note: An interpreter reads one line at a time of the source code by performing the specific instructions contained in that line while a compiler reads entire source code.]


Keywords are already defined (reserved) words that a programming language uses or its compiler uses for some specific meanings. Here reserved means we cannot use Keywords for identifying an object (or simply for an identifier).

Below is the list of c keywords:

































Identifier Names & Variables

 c tutorials |  Admin

Identifier Names:

Names of variables, functions, labels, and other user-defined objects are called Identifiers. Length of an Identifier can be one to many characters.

Here first character of the identifier must be an alphabet or underscore, and subsequent characters must be either alphabets or digits or underscores or mix of them.


For example:











correct and incorrect identifier names


[Note: A Keyword cannot be used as an identifier, or we can say an identifier cannot be same as a Keyword. Because Keywords are reserved for other purposes.]



A variable is a named memory location and used to store a value that can be modified in the program.


A variable can be used only if it is declared. So it is necessary in C language to first declare all the variables before using them in the code.


A variable (named as var) is declared by following syntax: 

type var;

where type is the valid data type (e.g. int, float, char etc.).


For example:

int i, j, k;

short int si;

unsigned int ui;

double d,val;

Variable Types:

    1) Local variables

    2) Variables as formal parameters

    3) Global variables

Local variables: Variables that are declared inside a function.

Variables as formal parameters: Variables that are parameters of a function.

Global variables: Variables that are declared out-side of all functions in a file.

[Note: see variable`s scope]

For example:

Variable Initialization and Constants

 c tutorials |  Admin

A variable is assigned (or initialized) by assignment operator =.


type var = Constant;


Global and static local variables are initialized only at the start of program.


Local variables (excluding static local variables) are initialized each time in the block in which they are declared.


If a local variable is not initialized or assigned to a value (constant), it will have unknown value.


global and static local variables  that are not initialized  automatically set to zero or null value.


Constant :

Sometimes also called as literals. Constant can be a value of any basic data type.

For example:

Integer constants – any integer number, e.g. 0, 1, 5, 17,30 etc.


Float constant- any fractional number, e.g. 12.235, 3.141529, 2.714, 3.14e-10 etc.

[Note: C also allows to use scientific notation for floating-point constants.]


Character constant – any single character (excluding Backslash Character) enclosed in single quotes, e.g. ‘a’,’4’, ‘%’ etc.


[Note: To get a Backslash Character we use double Backslash in single quotes e.g. ‘\\’. See escape sequences.]


For assigning a character variable to null character, we use either ‘\0’ or simply 0.


char x = ‘\0’;


char x = 0;


For assigning a character variable to backslash character we use ‘\\’.


char x = ‘\\’;


Compiler optimizes a numeric constant into the smallest compatible data type that can hold it. For example: If integer is of 16 bit, 34 is int by default, but 23453453 is a long int, even though the value 34 could fit into a character type, the compiler will not cross type boundaries (excluding in the case of floating point constants where a float constant is assumed to be doubles).


We can use a suffix to specify a constant precisely, see below list.


Data Type



2,  -4, 345 etc.

long int

2L, -4L, 3456789L, 67l, -41l etc.

long long

323434LL, 5657567ll, -5656ll etc.

unsigned int

2U, 4U, 876U, 7u, 768u etc.

unsigned long long

18446744073709551615ULL, 546ull etc.


34.34456F, -3.14256f, 2.6e-10f etc.


3.0,234.50, -9.765544545 etc.

long double

112324.45L,34534534645.455l etc.


Hexadecimal and Octal integer Constants:

An octal constant begins with a 0 and hexadecimal constant begins with 0x,

for example:


int octa = 0123;

/* 83 in decimal */

int hexa = 0x123;

/* 291 in decimal */


[Note: In GNU GCC compiler, we can also use 0b or 0B for binary constants.]


String Constants:

string is a set of characters enclosed in double quotes.


For example: 

“this is a string”, “a”, “1234”, “3.1415926”, “#$a12” etc.


[Note: C does not have a basic datatype of string but we can define string constant. To store the value of string constant into a string variable, we require a character array or character pointer. See arrays and pointers.]


[Note: `a` and “a” both are different here. `a` is a character constant while “a” is a string constant.]

The Basic Data Types

 c tutorials |  Admin


Data type`s keyword

Data type








double floating-point



Five foundational data types of C language:


These types are the basic data types in C language. The size and range of these datatype depends on processor and compiler used.

For example: In 16 bit environments, such as DOS or Windows 3.1, an int is 16 bits. For most 32-bit environments, such as Windows 95/98/NT/2000, an int is 32 bits.

[Note: C99 and above versions also have three more datatype: _Bool, _Complex, and _Imaginary.]



Type Modifiers in C language:

Type Modifiers are of 4 types:

 1) signed

 2) unsigned

 3) long

 4) short

These type modifiers can be used with the basic datatype to make a new type with modified size/range.

For example: unsigned char, unsigned int, long float etc.

unsigned char has same size (1 byte) as char but range starts with 0 and ends with 255 while char starts with -128 and end with 127.

Note that some combinations are not allowed as they have not any meaning. For example, long and short cannot be used with char. Similarly signed and unsigned cannot be used with float and double. Also short cannot be used with float and double but long can be used.

When a type modifier is used by itself alone (means when it does not precede a basic type), then it is assumed as int. See below table.



Same As


signed int


unsigned int


long int


short int


Here a simple code is given to print data type`s size and range.  Right shift is used for calculating powers of 2 to get range and `sizeof` operator is used for calculation of size. 

Type Qualifiers

 c tutorials |  Admin

A type qualifier is applied just before a type to make a new qualified type.

For example before int, if we add const (a type qualifier) the type const int will represent a constant integer datatype. And so an object defined with type const int can only initialized but may not be changed throughout the program.

Type qualifiers is used to controls the variable in a manner that how it is accessed or modified.

Type qualifiers have 3 types:

 1) const

 2) volatile

 3) restrict

[Note: third one (restrict) is available in only c99 and above compiler versions.]


As before discussed variable of const type may not be changed throughout the program. These variable stored in Read Only Memory. Also we must initialize with the definition.

For example:

const float pi = 3.1415; is OK

but we cannot write

const float pi;

pi = 3.1415;

is wrong because pi is redefined here. When we declare a variable it automatically assigned with some garbage value.

More examples:

const char exp = ‘E’;

const int ten = 10;



This qualifier indicates that the value of a variable of volatile type may be changed between different accesses, even if it is not modified in the program.




A volatile type variable’s value may be changed in a way not explicitly specified by the program.


For example, if 0x56 is assumed to be the value of a port that can be changed by external conditions only, then below declaration would prevent any possibility of accidental side effects:

const volatile char *port = (const volatile char *)  0x56;



restrict keyword basically used with pointers declaration.

restrict keyword says to compiler that only the pointer itself or a value directly derived from it, will be used to access the object to which it points.


Storage Class Specifiers

 c tutorials |  Admin

There are 4 types of storage classes.

 1) extern

 2) static

 3) register

 4) auto

These are used to tell the compiler that how to store a variable in memory.

Syntax:           storageClass type var;


“The meaning of extern keyword is that an object is defined with external linkage elsewhere in the program. “


There are 3 types of linkage,

 1) external

 2) internal

 3) none


Global variables and functions have external linkage. They can be accessed from all files throughout a program. 


While global variables and functions declared as static have internal linkage. These can only be accessed within the file in which they are declared.


Local variables are the examples of none type linkage because they exist only in the block in which they are defined.


For example:

//example using extern
#include <stdio.h>
int main(void)
extern int var1, var2; /* use global vars */

            printf("%d %d", var1, var2);

return 0;
/*global definition of first and last */
int var1 = 100, var2 =200;

In the above example, variables var1, var2 are used with
external keyword to show the compiler that these are global variables and defined elsewhere in the program. Here elsewhere means either they may be defined in the same file or may be in another file.


It means extern keyword can also be used to declare a variable without defining it. But if it is not defined anywhere else in program compiler can show error. So it is also need to keep in mind that we must define the variable.


extern can also be applied to a function declaration, but doing so is redundant, because all functions are by default extern.   


Another Example using extern:

int ig1,ig2;
char ic;
int main(void)
            /* . . . */
void func1(void)

        ig1 = 123;

// file2.c
extern int ig1, ig2;
extern char ic;
void func2(void)

  ig1 = ig2 / 10;
void func3(void)

  ig2 = 10;

In the above example global variables ig1,ig2 and ic are used in another file using extern keyword.



As discussed earlier, static variables and static functions are examples of internal linkage. They can’t be accessed outside of the file or block in which they are defined, also they keep their existence in their file or block.


For example, static global variables can be used in a file to protect it from changing its value from another file throughout the program.



// example using static Local

int func(void)


            static int static_num = 0;

            static_num = static_num + 10;

            return static_num;



#include <stdio.h>

int main()


            int s1 = func();

            int s2 = func();


            printf("%d %d", s1, s2);


            return 0;



// example using static Global

#include <stdio.h>

static float static_pi = 3.1415;

float getCircleArea(float radius);


float getCircleArea(float radius)


            float area = static_pi*radius*radius;

            return area;



int main()


            float a1 = getCircleArea(1.5);

            float a2 = getCircleArea(1.6);

            float a3 = getCircleArea(1.7);

            printf("%f %f %f", a1, a2, a3);

            return 0;



In above the example first shows a program using static local variable (static_num), used in the function func and this function is called 2 times in the program with storing its return value to s1 and s2 integer variables. In the first call of function func static integer local variable (static_num) is initialized with a zero value and then it is incremented with the value 10. On time of second call it will not defined and initialized again with zero because it is used as static (it is already in the memory that is permanent until the program stop) and so it will jump to next statement and again incremented with value 10. So the output will be 10 20.


In the second, the value of mathematical constant pi is taken into a static float global variable (static_pi) and used to calculate area of a circle of given radius. We can use this variable in this file anywhere but cannot use it in any other file.



The register specifier specifies that the variable is stored in the register of the CPU not in the memory, where normal variables are stored. So operations on a register variable can be much faster than on a normal variable because the register variable was actually held in the CPU and did not require a memory access to determine or modify its value.


This keyword mostly used with of type int, char or pointer type. 



List of operators in C

 c tutorials |  Admin

Arithmetic operators

Operator Name


Basic assignment

a = b


a + b


a - b

Unary plus


Unary minus



a * b


a / b

Modulo (integer remainder)

a % b

Increment (Prefix)


Increment (Postfix)


Decrement (Prefix)


Decrement (Postfix)


Comparison operators/relational operators

Operator Name


Equal to

a == b

Not equal to

a != b

Greater than

a > b

Less than

a < b

Greater than or equal to

a >= b

Less than or equal to

a <= b

Logical operators

Operator Name


Logical negation (NOT)


Logical AND

a && b

Logical OR

a || b

Bitwise operators

Operator Name


Bitwise NOT


Bitwise AND

a & b

Bitwise OR

a | b

Bitwise XOR

a ^ b

Bitwise left shift

a << b

Bitwise right shift

a >> b

Compound assignment operators

Operator Name


Addition assignment

a += b

Subtraction assignment

a -= b

Multiplication assignment

a *= b

Division assignment

a /= b

Modulo assignment

a %= b

Bitwise AND assignment

a &= b

Bitwise OR assignment

a |= b

Bitwise XOR assignment

a ^= b

Bitwise left shift assignment

a <<= b

Bitwise right shift assignment

a >>= b

Member and pointer operators

Operator Name




Indirection("object pointed to by a")


Address-of ("address of a")


Structure dereference("member b of object pointed to by a")


Structure reference ("member b of object a")


Other operators

Operator Name


Function call

a(a1, a2)


a, b

Ternary conditional

a ? b : c


sizeof(a) or sizeof(type)

Alignof (since C++11)

alignof(type) or or _Alignof(type)

Conversion (C-style cast)



Operators in C

 c tutorials |  Admin

There are four main classes of operators:






In addition, there are some special operators, such as the assignment operator, for particular tasks.


Assignment Operator (In Short):


Syntax:             variable_name = expression;


Arithmetic Operators:




Addition, also unary plus


Subtraction, also unary minus







++, --

Increment & Decrement


//example using arithmatic operators

#include <stdio.h>

int main()


     int a = 20, b = 10;


     int add = a + b;

     int sub = a - b;

     int mul = a * b;

     int div = a / b;

     int rem = a % b;


     int u_plus = +a;

     int u_minus = -a;


     printf(" + result: %d\n", add);

     printf(" - result: %d\n", sub);

     printf(" * result: %d\n", mul);

     printf(" / result: %d\n", div);

     printf(" %% result: %d\n", rem);

     printf(" unary + result: %d\n", u_plus);

     printf(" unary - result: %d\n", u_minus);



     return 0;




Increment and Decrement Operators:

There are two useful operators that simplify two common operations. These are the increment and decrement operators, ++ and --.

x = x+1; is the same as ++x;

x = x–1; is the same as --x;

Both the increment and decrement operators may either precede (prefix) or follow (postfix) the operand.


For example,

x = x+1; can be written ++x; or x++;


Difference between prefix & postfix increment or decrement operators:

When an increment or decrement operator precedes its operand, the increment or decrement operation is performed before obtaining the value of the operand for use in the expression.


If the operator follows its operand, the value of the operand is obtained before incrementing or decrementing it.


For example:

int x, y;


x = 10; y = ++x;

//sets x to 11 and y to 11. But,


x = 10; y = x++;

//sets x to 11 and y to 10.


Precedence of the arithmetic operators:


++     --


unary plus     unary minus


*     /     %    


+     -


We can use parentheses() to alter the order of evaluation. Parentheses force an operation, or set of operations, to have a higher level of precedence.


Relational and Logical Operators:

Relational Operators:



Greater than


Greater than or equal

Less than


Less than or equal




Not equal


Logical Operators:









All relational and logical expressions produce a result of either true or false (1 or 0).



// example using relational operators

#include <stdio.h>

void print(int val)


     printf(" %d\n"val);


int main()


     print(2 > 1);

     print(2 < 1);

     print(2 >= 1);

     print(2 <= 2);

     print(2 == 0);

     print(2 != 1);


     return 0;