Académique Documents
Professionnel Documents
Culture Documents
Contents -
8 Basic Data type defined by C are Character, Integer, Floating Point, Double
Floating Point, Valueless, Booledan, Complex &Imaginary. First 5 of these are
present in C89 while last three were added by new vesion of C99.Let discuss each of
them in brief -
1. Character - Implemented by char keyword. They are used to store ASCII character
and are always 1 byte long.
2. Integer - Implemented by int keyword. They are used to store integer value and are
always 4 byte long.
3. Floating Point - Implemented by float keyword. They are used to store decimal
values and are always 1 byte long.
4. Double Floating Point - Implemented by double keyword. They are also used to
store decimal values but with higher precision and are always 8 byte long.
6. Boolean - Implemented by _Bool keyword. They are used to store Boolean values
ie. True or False and are always 1 byte long.
One important point worth mentioing here is that C only stipulates the minimum
range of the data type and its size may vary according to system implementation. The
range may increase but will never get below the standard value. Also if you want your
program to be portable to maximum systems make use of compile type operator
sizeof in your program and allocate memmory dynamically instead of using default
memmory allocation.
2. Type Modifier
Type Modifiers are special keywords which can be applied to a data type to change
their meaning to more precisely fit the special needs they need to attain. There are 4
type modifiers define in C - signed,unsigned,long,short.Below we discuss each of
them one at a time.
signed - Can be applied to int and char. It changes the way the compiler interpret the
variable. 1st data bit is assumed to be a sign bit. Integer is signed by default but
character is unsigned. This modifier reduce the range to half of the maximum but
allows to implement some algorithms efficiently.
unsigned - Can be applied to int and char. It changes the way the compiler interpret
the variable. 1st data bit is assumed to be a data containg bit. Integer is signed by
default but character is unsigned. This modifier increase the range to maximum
(double of default) but cannot stored negative values.
short - Can be applied to int only. It enhances the portability of your program. Size of
int is 16 bits (2 b ytes) minimum but on some system it may become 32 and even 64
reducing portability of your program. To make sure you int is always 16 bits it is
recommended you use this modifier.
long - Can be applied to int and double. It enhances the portability of your program.
Size of int is 16 bits (2 b ytes) minimum but on some system it may become 32 and
even 64 reducing portability of your program. To make sure you int is always 32 bits
it is recommended you use this modifier. Also when applied to double it increase the
size from 64 bits to 128 bits, it doesnot increase the range but increase the digits of
precision. It is biggest size default data type though there is a experimental and
unstable data type in C99 long long double on 256 bytes but due to its implementation
limits it is highly recommend you dont use it. Long double is sufficient for even high
precision scientific values to large extent (unless you are calculation stars in the
universe).
It is important to note that modifier cannt be applied to void or float. Also you are not
permited to declare a void data type except generic pointers (which are internally int).
Also in case of int two different type modifiers can be simultaneously applied to
further enhance the meaning.
One more point worth mentioning is default to int rule exisitng in C. Its obsolete now
but some compilers do provide them to give backward comaptibility but its highly
recomended you dont use them in any of your program. For curosity and knowledge
sake it states that if a type modifier is written by itself then it will be assumed a
modifier to a type int. In other words it means that -
Once again though int is implied it is a common practice to mention them anyway for
sake of compatability.
3. Indentifier
Name of any user defined item item in c is called identifier such as functions, labels
and variables.
Identifiers are of two types internal and external. Internal identifiers are one which
have internal linkage meaning that they are known only internally in file such as local
variables and static global variables. External identifiers are one which have external
linkage meaning that they are known only outside their file such as function names
and global variables.
In C identifiers can have any number of character but not all of them are
significant.Significant characters are the character used to identify the identifier. For
an identifier to be unique it must have name different by atleast 1 character from all
other identifiers in the same scope. C89 specifies that atlest 6 characters of an external
specifier and 31 characters of an external identifier be significant. C99 further relaxes
this constraint stating that atlest 31 characters of external identifier and 63 characters
of internal identifier must be significant. Though generally compilers make sure that a
larger number of characters be significant but minimum number is always instated.
1. They may contain only alphabets, digits and underscore, example Hi!!!, I.Love.You
is incorrect.
3. They cannot be same as keywords because these are the words reserved from usage
by C.
One important point is that your identifier can have same name as the function in the
library but this may induce some serious error, especially if you include the header
file with similar name function. In this case whenerever you refrence the function it
will refer to your code function even when you desire to use the library function,
simplest way avoid this bug to give your functions a different name.
It should be noted that c is type sensitive language that its identifiers are case
dependent eg- C_ROCKS, C_rocks and c_rocks are all different identifiers in C.
Also it is recommended that you use a standard notation while naming the identifiers.
Famous ones are hungarian notation and camel case notation. These standards while
correctly applied can lead to many benefits such enhanced portability and
maintainability. These factor gain importance as the size of the project increases.
4. Variable Overview
Variable referes to a location in memmory that can be used to a value that can be
dynamically or statically modified by your program.
All variables must be declared before there are use, basic syntax is
Identifier used as variable name should comply with the rules stated above.
1. Local
2. Global
3. Parameter
Each type has its own scope, limitation and function as discussed below
5. Local Variables
Variables that are declared withn a function are local variable. They are also known as
automatic variables but the term is obsolete.
Earlier local variables were declare using keyword auto butnow this keyword is
implicitly applied as a result the use of this keyword in modern source code is
virtually non exsistent but do keep it in mind if you encounter it in earlier codees.
Local variables have property that they can be accesed only in the code they are
defined in. Code block starts with the { and ends with } ie. within a pair of curly
brackets the code block exist.
Life span of global variables is for the period in which code block is executing. They
get created when code block is entered and get destroyed when code block is left.
They are stored on stack of your compiler which is a dynamic data storage which is
the reason that local variables cannot retain their value. This property can be modified
by static keyowrd, this is discussed below.
It is a rule in C that you must declare a local variable before using it. Also in C89 its a
rule that all declaration of variables must be made before any executional statment of
the code block bbut in C99 (like C++) it can be declared any where prior to its first
refrence.
Note that two variables with same identifier (name) cannot be stored in same code
block and would reslut an error by compiler, but same name local variables can exist
in different code blocks and even aggregated code blocks (one inside another).
When the same name variables are used in different functions they bear no relation
and doesnt know nor depend on other's existence.
When the same name variables are used in an agrregated code block, ie. one variable
in outside code block and one in inside code block the inner one mask the outer one.
After ineer code block ends the outer variable again comes into existence.
Following C Source code will help you grasp the detail of the topic -
#include <stdio.h>
void f1 (){
int x = 10;
printf ("%d",x);// Outputs 10
}void f2 ()
{
int x =20;
printf ("%d",x); //Outputs 20
} int main (){
int x = 30;
{
int x = 40;
f1 ();
f2 ();
printf ("%d",x); //Outputs 40
}
printf ("%d",x); //Outputs 30
return 0;
}
6. Global Variable
Unlike local variable global variable are known throughout the program. They are
declared outside all function and conventionally just after the include statements.
They should be use carefully and only when there is a defetive gain in performance or
efficiency or they provide ease in programming. Most of the time they are used to stoe
shared data but beautifully crafted programs also used them to store control
information as control flags.
The major problem with global variables is that they lead to bugs which are very
difficult to debugg and very easy to occur because the value of a global value can be
easily modified by an undesirable side effect of your code. Also storage of global
variable is on a fixed memory region which is non volatile for program life period. As
a result a global variable always tend to bloack memory not only for a particular
function execution but for entire program execution time as a result large number of
global variables may overrun the memory allocated to your program leading to
serious trouble. So global variables must be used when there is an absolute must.
A special situatuion occurs when global variable and local variable has same name. In
this case the local variable mask the global variable and all refrences are made to it
within its scope.
#include <stdio.h>
void f1 ()
{
int x = 10; //Outputs 10
printf ("%d",x);
}void f2 ()
{
x =20;
printf ("%d",x); //Outputs 20
} int main ()
{
int x = 30;
f1 ();
f2 ();
printf ("%d",x); //Outputs 30
return 0;
}
7. Parameter Variable
Parameter variables are used for passing values between functions. Value maybe
control information or data.
They are very similar to local variables in a sense that they are dynamic and have life
span of that of local variable. Even though they recieve paramet value they can act
like a local variable and reassign values to the parameter variable.
Their main job is to get automatically intialize based upon the data passed.
#include <stdio.h>
void f1 (int x)
{
printf ("%d",x);//Outputs x
}int main ()
{
int x = 30;
f1 (x*5);//Outputs 150
f2 (x+10);//Outputs 40
printf ("%d",x); //Outputs 30
return 0;
}
8. C Scopes
2. File Scope - This scope is given to identifiers which are known only in the file they
are declared. Staic global variables come under this scope.
3. Block Scope - This scope is given to identifiers which are known only in the code
block they are declared. Local variables come under this scope.
4. Function Prototype Scope - This scope is given to identifiers which are known
through a function to which they are passed as parameter. Parameter variables come
under this scope.
5. Function Scope - This scope is given to identifiers which are known through
thefunction. Labels identifier use to target goto statement come under this category.
Also there are three type of linkage defined in C which is very similar to scope -
1. External Linkage - Same as Universal Scope and is applied to global variables and
function name.
2. Internal Linakge - Same as File scope and is applied to static global variables.
3.No Linkage - Combination of Block, Function and Function Prototype Scope and is
applicable to local variables, parameters and labels.
These are rarely used terms which are used when the task of making fine distinction
in identifier visibility is needed.
9. Type Qualifier
Type qualifiers in c are used to specify and contro the acess and modification of a
variable. There are 3 type Qualifiers in C - const, volatile and restrict. They must
precede the type name that they qualify. Each of type qualifier is discussed below in
detail.
1. const - It is a very usefull keyword available to a cprogrammer but its usage is not
that prevelant in comparison to potential and benefits its provides. const keyword
provides many utility applicable to situtation they are applied.
When its applied to a varaible then value of variable cannot be modified by your
program. They can be used as a constant. Also they can be intialized but after
intialization there value is not changable by any software means.
When its applied to a pointer then the object its pointing to cannot be modified by the
program. Though the value its pointing can be changed by other means but not by this
pointers.
Situations you should use this keywords are special. This keywords can prevent bugs
in your program by making sure that an essential constant value doesnot get modified
as a side effect leading to incorrect result. This keyowrd is also applicable in
situations in which you pass falue to a function by mean of pointers or in other terms
call by refrence. In this case the function has the ability to modify input data in the
original source. Now if you are pretty sure that you dont want this function to change
your intial values you can pass the pointer as a constant pointer making sure that
value pointed by that pointer cannot be modified.
For optimization purposes some compilers may also place the value in ROM so they
are absolutely unmodifiable.
One elegnat example of use of const keyword is seen in standard library functions
provided with C. All the parameter this function does not want to modify are declared
as const. You should use the same approach as it will save you a lot of headache when
the failure of your programs occur because of preventable bugs.
One very important point about const is that its value can be modified by hardware
means (sometime desired, most of time undesired). This can also lead to bugs but its a
very rare situatuion when some harware fault occurs such as memmory overflow etc.
But using const keywords prevents modification by any software mean.
Its also well known fact that const keywords enhanced security of you software and
also pose a mjor difficulty in reverse engineering processes.
2. volatile - This one of the rarest used C-Keyword and find special used in hardware
dependent programs such as drivers or system clock based code. Its specifies that the
variable can change without any implicit specification. In other words the variable
value can change even if doesnot assign a new value by program.
This is neccesary because in order to optimizse the code the compilers change the
order of evaluation or may even not check the new value of variable if they observe
that the variable does not occur on left in any assignment statement. This feature can
surely sabotage your hardware dependent code in which values changes automatically
also at very high frequency. Using volatile keyowrd prevents this optimization and
make sure complier check the value of the variable every time it is used.
Many programmers beleive that const and volatile are opposite of each other but in
relaity they point to entirely diffrenet aspects. You can even use them on same
variable, in this case it will specify the variable value changes dynamically but can
only be accesed by your code as constant.
3. restrict - This is one of the newest features added to C. It is only available in C99.
It states that a restrict pointer is the only mean by which the data pointed to that object
can be accesed. Data accesed from any other pointer is possible if and only if its based
on the first one.
The major functionality it provides is that it enables the compilers to produce highly
optimize code.
To programmers it provides a tool by which they can make sure that if a pointers is
restrict it provides the sole access method to the data it is pointing.
Also one important deduction that can be made out that if two pointers are restrict
they are pointing to entirely different data ie. the data they are pointing is non
overlapping.
Like const , restrict keyword is also extensively used by the library function and users
are recommended to use them to improve efficiency of their code.
#include <stdio.h>
int main ()
{
const int x = 30;
cont volatile int * port = (const volatile int *) 0X1E;
int *restrict point = &x;
printf ("%d %d %d",x, *point, *port); //Outputs 30, 30, 30
return 0;
}
Storage class specifier when applied to variable tells the compiler how to store that
variable. Storage class specifier always precede the varaible declaration. There are 4
storage class specifier defined in C. These are extern, static, register & typedef and
are discussed in detail below.
First , extern was once used before functions name to identicate the function has
global scope but since now all the functions are automatically put into global scope
this use is now virtually no existent.
Second use of extern is declaring that a global varible used in the file is from an
external file. Though global variables have global scope they may be masked by
variable of same identifier. Hence to make sure the global one is used we use external
specifier. Also generally such declarations are made into header files and are specially
usefull in programs splitted into many source files.
Third use of extern is most commonly used and enables a programmer to use a
variable without defining by marking its declaration as extern. Some users may be
confused by declaration and description so a brief description is appropriate. C
defines that a varaible can have any number of declaration but only 1 definition.
Declaration is the statement which tells the compiler what type of datat type that
varible is such as statement int i; this statement only declares the code but doesnot
define it. On other hand when you assign any value to a variable it get defined. In
other words when first memmory is allocated the varaible is getting declared. If you
intialize the variable while defining it you are declaring as well as defining in one
statement. Extern just specifies that declaration of the variable is present but not in the
same scope so compiler searches for it high and low for resolving this refrence.
The order in which refrence search is made is important.First the seacrch is made in
bloack scope then in function scope then in file scope and in last universal scope.
Compiler assumes that any definition which match the declaration first is the variable
being refered to. In other words if variable definition is found in functions scope then
C compiler doesnot search the file and universal scope. If no correct refrence is found
then linker flanks an error message.
When applied to global variables its scope is limited to file only ie. other files
included in the program has no clue of its existence. They provide a very powertool of
hiding data and creating stand alone function because of which they are also used in
library functions. The global variables of your stand alone function will be completely
usefull in that program but are shielded from external effects when combined in a big
program. The value of these variables can be modified only by the function in that
source file and not outside it preventing bugs, mishandling and probably unauthorize
access and program tempering.
When applied to local variables the variable is stored in global variable memmory
space and not on stack. Even though the varaible has functions scope it does not get
destroyed like local variable when function returns, instead it retains it value on next
call. Static local varaibles are intialised only once on the first function call. They
provide high functionality in certain algorithms. If they were not available global
variables have to be used for them but this makes program ureliable because it is
depending upon something thats outside it. In Software analysis term this increases
programs coupling (dependence on others) and decreases there cohesion (Capability
of work alone). It is just opposite of what we desire. Ideal module/subroutine is the
one which has minimum coupling and maximum cohesion.
#include <stdio.h>static int callfunction; void function (void) {static int a = 0;a++;
printf ("Function have been called %d time",a); }int main (){ callfunction = 10;for
(int i = 0; i<callfunction;i++) { function (); } return 0;}
A register variable is stored in CPU register instead of RAM and its a well known fact
that there is nothing that provides faster access than CPU register. This register is very
dynamic and also provided very very very limited space. Register are used by CPU
for addressing RAM memmory but a register declared variable is stored in CPU
register itself hence they prrovide very fast access to read and write.
Using a register keyword can make your program faster by many folds if properly
used. CPU register are so limited that only 1-2 live variables can placed on it that also
of non aggregate type (basic ones). So make sure you make only that variable register
which have an drastic impact on the program, loop variables make excellent choice.
Use register carefully keeping its limitation in mind at all times.
Also you dont have to worry about declaring too many variables register as compiler
manage them for you but it doesnot decide on basis of impact on program, its your job
and you have to tell compiler about them.
Also making a variable, a register variable is dependent upon many other constraints
such as size of CPU registers, number of free registers with CPU, access to CPU
register and much more so they are innately dependent on hardware and operating
enviroment.
#include <stdio.h>
}
return 0;
}
The name is not replacement but is addition and can be used again in a typedef
expression to once agian create a new data type name of the original data type.
1. It makes your code portable since you are using your own name for the code
generated by compiler for a particular enviorment, when you move to a new
enviorment all you have to do is to modify the typedef statements according to the
new enviorment and compile agian.
2. It creates a self documenting code, since new data names implies a closer meaning
to reader who is reading than a basic data type name. This makes code easier to
understand.
Read the C Source Code below to improve your understanding.
#include <stdio.h>
int a;
age b;
weight c;
return 0;
}// Here all three variables a, b and c are of type int.
Global variables and static local variables are intialized only once.
Local variables are intialized each time they are created or thier code block is entered.
Also unitialized static and local global variable are set to zero before thier prior use.
Uninitalize local variable contains undefined value (Random) before thier prior use.
Using an unitialized variable specially the local variables and pointers can lead to
intense bugs which are even capable of entire system crash. To prevent this some
compilers will indicate error but almost all of them will flank a warning to make sure
it is not by a mistake (Some special cases such destroying a enemy computer this may
find some good use but they are still unrelaible so study virus and trojan section, just
kidding).
12. Constants
Constants refer to fixed values which your program cannot modify. They are also
known as literals. You also make an varaible a constant by using const keyword as
describe above. There are different types of constants including the a type from every
basic data type. They can be broadly classified as data type constatns, base constants,
string constants and back slash constants (escape sequences). We discuss each
category below.
1. Basic Data Type Constants - All basic type have an constant associated with it. If
not explicitly specified the c compiler allocates the minimum size data type to it
capable of storing it but compiler also make sure it does not cross any type
boundaries. One exception to previous statment is that the floating point value by
default is double and not float even tough double has larger size. Below is all types of
basic data type constants defined in C.
character - 'c'
int - 101
double 101.01
The character following the constants is called type suffix in c and is case
independent.
2. Base Constants - As you probably knowing there are different number systems
other than decimal, most improtant one among them is Hexadecimal and Octal
Constants. Hexadecimal is a number system 0 - 16 while octal is number system 0-8.
It is some time easier to use these special number systems than decimal specially
while doing hardware programming through in which port values are Hexadecimal.
Also they are usefull when you use them constatnly for some calculation, in this case
you dont need to particulary feed equvalent decimal value to C because C provides
automatic to and fro base conversion calculation. This is where base constant comes
in telling compiler which base the value in the constant bleongs to a C then store its
equvalent value in any internal way it prefers.Diffrent base constant are -
Decimal - 420
\a alert or beep
\b Backspace
\f Formfeed
\r Carraige return
\n New Line
\t Horizontal Tab
\v Vertical Tab
// Backslash
\? Question mark
Operators is a symbol used to relate two operands. When one or more such relations
are combined we get an expression. C have highly developed and sophisticated set of
operators providing the ability to programmer to do anything with maximum
flexibility. Operators can be broadly classified into arithemtic, relational, logical,
bitwise and miscellaneous. All the operators defined in c are discuss in subsequent
topic in small related groups.
lvalue = rvalue;
Eg- x=y=z= 0; this statement assign value zero to three varibles simultaneously.
For eg -
X += Y is equivalent to X = X+Y
X -= Y is equivalent to X = X-Y
X *= Y is equivalent to X = X*Y
X /= Y is equivalent to X = X/Y
X %= Y is equivalent to X = X%Y
+ does addition Eg - 4 + 3 = 7
- does subtraction Eg - 4 - 3 = 1
* does multiplication Eg - 4 * 3 = 12
% does modulus Eg - 4 % 3 = 1
The result produce by these arithemetic operator is same as largest variable input ie.
4/3 = 1 , 4.0/3 = 1.33 , 4/3.0 = 1.33 & 4.0/3.0 is 1.33 . 4/3 is 1 because all constants in
expression are int while in all other atleast one or more operand operated by opertor is
float
These are special arithemetic operators which are used to increase or lower the
variable value by unity (1). Symbols for them are ++ (increment) and -- (decrement).
They should be used where possible because the code produce this way is more
optimized specialy in case of linearly incremented code.
Though ++x and x++ and similarly x-- and --x employs same equivalent circuit they
when used with assignment operator result into extremely diffrent result. The first
form is called prefix and other one is called postfix form.The main difference is when
assignment occurs with respect to increment or decrement.
They work on boolean data and produces boolean data. In C any 0 value is considered
flase and any non-zero value (generally 1) is consider to be true. C99 also defines a
data type _Bool which can store only two values true (1) or false (0).
Relational operators return 0 or 1 depending upon the validity of the condition they
are checking. Various realtional operators defined in C are -
== equal to
!= not equal to
|| Logical OR
! Logical NOT
Eg- ((3>4) && (2==1)) || ((4>3) && ~3 ) = ((0) && (0)) || (1 && 0) = 0
C was intially designed to replace the assembly language and used for system
programming such as driver designing and port maintainance. These devices innately
contains the job of working with smallest element of storag bits and bytes. Bitwise
operators defined in C provides this capability in which you can play with bits and
bytes.
Relational operators are applicable to only char and int types. Various types of
relational operator are -
& And, Used to logically and all the bits in the two operands and return the resultant
output.
| Or, , Used to logically or all the bits in the two operands and return the resultant
output.
^ XOR , Used to logically XOR all the bits in the two operands and return the
resultant output.
~ Complement , Used to logically complement all the bits in a operand. Also using
complement twice original result is produce.
<<n Shift lefy, Used to logically shift all the bits in the operands n postions left and
introduce zero from right and return the resultant output. The shift left bit is lost and
cannot be returned.
>>n Shift right, Used to logically shift the bits in the operands n postion right and
introduce zero from left and return the resultant output. The shift right bit is lost and
cannot be returned.
x y x^y
0 0 0
0 1 1
1 0 1
1 1 0
One important point to note about bit shifting is that if A = B>>n bits then its is
equivalent to B/n and if A = B<<n bits then its is equivalent to B*n as long as the bit
lost in the shifting procdure is 0. If bit loss is 1 then there is a loss of data and this
realtion does not hold true.
Question Mark as name sugests is symbolize by ?. This is the only ternary operators
in C. In other words this is the only operand which takes in three simulatenous inputs.
It means that Exp 1 is evaluated and if its true value of variable V is one obtained by
solving EXP2 & if its false value of variable V is one obtained by solving EXP3.
#include <stdio.h>
* is used to reterive value from a location assuming that variable it is applied to store
the memmory location to that value. It is also used in declaring pointers.
& is used to reterive adress of variable, it is used to retrieve the memmory location of
that variable and this address is used as a feed to the pointers.
Though pointers are discussed in very minute details in further sections what follows
is a C source code showing pointers in action -
#include <stdio.h>
int main (void)
{
int source, target;
int *pointer;
source = 100;
pointer = &source;
target = *pointer
printf ("%d", target);
return 0;
}
If sizeof is used efficeintly the object code produced by the compiler is precisely
targeted to the enviorment and also your source code is extensively portable.
It is a property of sizeof that its value is determined at compile time and is dependent
upon the hardware and operating system.
sizeof returns the size of the object passed to it as parameter in parenthesis. The value
of size it return is a of type size_t which is some type of unsigned integer capable to
returning maximum possible size.
As you know integer can be 16 or 32 or even 64 bit which can make your code very
unportable a solution to the problem is to allocate memmory to the int variable
dynamically depending upon the size of int variable in the enviorment usinf sizeof.
#include <stdio.h>
#include <alloc.h>
In comma operator all the expression on left evaluates to null and the rightmost
expression becomes the value of the entire comma seprated expression.
The use of comma operator may be clear from following C source code -
#include <stdio.h>
Both of these operators are used with union and structures which are discussed in
detail in further sections. For brief knowledge Union & Structures are user defined
aggregated data types. In strucutre each internal element has its own unique structure
while in union they share
Dot operator is use to access or modify data from structure and union directly.
Arrow operator is use to access or modify data from structure and union using
pointers.
Following C Source Code show the use of dot and arrow operator -
#include <stdio.h>
struct data
{
int value1;
int value2;
}
Square brackets is used to index Arrays. Arrays are discussed in details in further
sections. In breif, arrays is collection of similar data types stored in sequential
memmory locations of which each element can be accesed through an index.
Following C Source Code show the use of Square Bracket and Parethesis operator -
#include <stdio.h>
When compiler parse the code it does some operators calculation earlier than others if
order is different this may lead to a diffrent result to solve this problem compiler use a
precedence table to decide which operator has to be solved first. This order can
modified by parenthesis operator (( )) which has highest precedence. Higher
precedence operator will calculated before lower precedence operator. Operators on
same level can be solved either left to right or maybe reshuffled by compiler to
produce optimize ouput.
Highest :
( ) [ ] -> .
%/*
-+
<< >>
== !=
&
&&
||
= += -= *= /= %=
,(comma)
: Lowest
All subexpression that have to be solved on same level can be freely rearrange by
compiler in any order to optimize code efficiency and some employ parsing them left
to right but if you want a portable code you cannot make this assumption always true.
This rearranging can also lead to some hard to find bugs which are caused by
undesirable rearrangement and execution order. So as programmer it is your job to
make sure that your code does not rely upon the execution subexpression. Situation
can be described by the code below -
#include <stdio.h>
int f1 ()
{
input = input*5;
return input;
int f1 ()
{
input = input+ 10;
return input;
When variables and constatns of diffrent types are mixed in a single expression they
all converted to same type.
General rule follow by the compilers is that all variables and constants are promoted
to the largest type occuring in the expression this is called type promotion. Also result
is return in this largest variable type.
Largest variable types are listed in decreasing order. If any operand is of not the
largest type variable then next largest varible type is checked until the right one
occuring in realation is found and then all the trems in that expresssion is - long
double >> double >> float >> unsigned long int >> long int >>unsigned int >> int >>
short int >> char
Type conversion may some time lead to loss of data when a bigger size type casted
into smaller type the table shown below indicat possible cases for char.
In C type casting allows you to convert a varible, constant or data of any type from
any type. Casting leads to conversion atoccurs at binary level.
Its also a very dangerous things because when you do a unusal type casting you obtain
a value in a variable which was never built to handle and when you used this variable
there is on guessing what could happen. So be very very carefull while using type
casting.
The genral syntax for typing casting when you have to convert a type1 into type 2 is
This very essential for a expression. You can create a unformatted expression code
readable by compiler without any error but same code when read by somebody may
literally throw him off and confuse it beyond limit.
Also spacing and tabiing should be added to expression to make it more readable.
Contray to general belie formatting does not have any beneficial or negative effect on
your code. But proper formatiing can surely prevent headaches to you and anybody
else trying to figure out the significance and meaning of the code. These formating are
completely ignored by compiler. Some IDE also provides tool to automatically format
the source code to a readble format. These tools are also available in stand alone form.
For eg - What is easy to read for a human even though both expressions are same
A = X/4-34*Y+2/2-7*9;