To fully define variable one needs to mention not only its ‘type’ but also storage class. A storage class defines the scope (visibility) and life time of variables and/or functions within a C Program. These specifiers precede the type that they modify.
From C compiler’s point of view, a variable name identifies some physical location within the computer where the string of bits representing the variable’s value is stored. There are basically two kinds of locations in a computer where such a value may be kept— Memory and CPU registers. It is the variable’s storage class that determines in which of these two locations the value is stored.
Variable’s storage class tell us about: -
There are four storage classes in C
(a) Automatic storage class (auto)
(b) Register storage class (register)
(c) Static storage class (static)
(d) External storage class (extern)
Let us examine these storage classes one by one
(a) The auto Storage Class
The auto storage class is the default storage class for all local variables.
Property |
Description |
Storage |
Memory |
Default Initial Value |
Garbage |
Scope |
Local to block in which it is defined. |
Life |
Till control remains in block in which it is defined. |
E.g.
{
int no_of_student;
auto int no_of_student;
}
The example above defines two variables with the same storage class, auto can only be used within functions, i.e. local variables.
(b) The register Storage Class
The register storage class is used to define local variables that should be stored in a register instead of RAM. This means that the variable has a maximum size equal to the register size (usually one word) and can't have the unary '&' operator applied to it (as it does not have a memory location).
Property |
Description |
Storage |
CPU Registers |
Default Initial Value |
Garbage Value |
Scope |
Local to block in which it is defined. |
Life |
Till control remains in block in which it is defined. |
A value stored in a CPU register can always be accessed faster than the one that is stored in memory. Therefore, if a variable is used at many places in a program it is better to declare its storage class as register.
A good example where register variable is frequently used is loop counters.
(c) The static Storage Class
The static storage class instructs the compiler to keep a local variable in existence during the lifetime of the program instead of creating and destroying it each time it comes into and goes out of scope. Therefore, making local variables static allows them to maintain their values between function calls.
Property |
Description |
Storage |
Memory |
Default Initial Value |
Zero |
Scope |
Local to block in which it is defined. |
Life |
Value of variable persists between different function calls. |
The static modifier may also be applied to global variables. When this is done, it causes that variable's scope to be restricted to the file in which it is declared.
In C programming, when static is used on a class data member, it causes only one copy of that member to be shared by all objects of its class. All this having been said, a word of advice—avoid using static variables unless you really need them. Because their values are kept in memory when the variables are not active, which means they take up space in memory that could otherwise be used by other variables
In the above example value of static integer variable i persists between different function call.
Output: -
Static -> 5 :::: Auto -> 5
Static -> 6 :::: Auto -> 5
Static -> 7 :::: Auto -> 5
(d) The extern Storage Class
The extern storage class is used to give a reference of a global variable that is visible to ALL the program files. External variables are declared outside all functions, yet are available to all functions that care to use them. When we use 'extern' the variable cannot be initialized as all it does is point the variable name at a storage location that has been previously defined.
Property |
Description |
Storage |
Memory |
Default Initial Value |
Zero |
Scope |
Global |
Life |
As long as program’s execution doesn’t come to an end. |
Example: -
First File: main.c
Second File: write.c
Here extern keyword is being used to declare count in the second file where as it has its definition in the first file main.c
Output:- 5
OPERATOR PRECEDENCE AND ASSOCIATIVITY IN C
Operator precedence determines the grouping and evaulation of terms in an expression. It decided which part or group of expression is evaulated first. Certain operators have higher precedence than others.
Consider Following Example.
expression = 8 * 2 + 3 * ( 2 + 3 ) / 5 + 3 / 2 * 5;
In above expression first (2 + 3 ) is evaulated as () has higher precedence, then 8 * 2. Then either 3 is multiplied with 5 (2 + 3) or 5(2 + 3) is divided by 5. Result of this is then added to 16 (8 * 2) Now for third group multiplication and division has same precedence, to solve ambiguity associativity is used.
When an expression contains two operators of equal priority the tie between them is settled using the associativity of the operators. Associativity can be of two types—Left to Right or Right to Left. Left to Right associativity means that the left operand must be unambiguous. Unambiguous means it must not be involved in evaluation of any other sub-expression. Similarly, in case of Right to Left associativity the right operand must be unambiguous.
For third group with operators of same precedence, left to right associativity is used. Refer table below for associativity. So first 3 will be divided by 2 and then multiplied by 5.
Following table shows list of operators with their precedence in descending order and associativity. Higher precedence operator is evaulated first.
Category | Operator | Associativity |
Postfix |
() [] -> . ++ - - |
Left to right |
Unary |
+ - ! ~ ++ - - (type)* & sizeof |
Right to left |
Multiplicative |
* / % |
Left to right |
Additive |
+ - |
Left to right |
Shift |
<< >> |
Left to right |
Relation |
< <= > >= |
Left to right |
Equality |
== != |
Left to right |
Bitwise AND |
& |
Left to right |
Bitwise XOR |
^ |
Left to right |
Bitwise OR |
| |
Left to right |
Logical AND |
&& |
Left to right |
Logical OR |
|| |
Left to right |
Conditional |
?: |
Right to left |
Assignment |
= += -= *= /= %=>>= <<= &= ^= |= |
Right to left |
Comma |
, |
Left to right |