“ADVANCED ‘C’ LANGUAGE”
Program is a set of instructions given to a computer to do particular task (OR) A Group of instructions is also called as program.
There are so many languages like c, c++, java etc..
Why there are so many languages?
There are so many types of applications and domains, according to the type of domain we will go for a language which is better for that application.
E.g.: java is most preferable for web applications. C++ is favour for windows graphics & system side programming and C is especially very favour to interact directly with hardware.
Languages are designed by some person. That person doesn’t bother about the compilation and executions. Some third party vendors will provides the compilers. Compilers will check only syntactical errors. Syntactical errors means weather the keywords (or) library functions exist (or) not. It will check that only it doesn’t bothers about the logical errors.
A logical error means e.g. c=a/b is a valid statement. By getting the values to a and b, consider if b as given “zero” and a is 5 then Compiler will not find that as a error because it was syntactically correct but logically incorrect. Debuggers will checks the logical errors. Any compiler can check the syntactical errors but Debugging tools can only finds logical errors.
Compilers are mainly TWO types:
1. IDE COMPILERS.
2. COMMAND LINE COMPILERS.
IDE - integrated development environment compilers e.g.: RIDE, KEIL. Etc
COMMAND LINE - Turbo, bollard, Etc
Source file is something which understands by the user. After compilation of source file we will get object file. Object file is raw binary.
We can get executables in two methods from object file.
1. Real mode (embedded mode)
2. Protected mode.
Real mode is nothing but directly interacting with CPU. There is no OS.
In protected mode there is a OS which could not understand the raw binary.
Here is a linker which converts the raw binary to understandable format for both OS and CPU.
Executable file is something which both OS and CPU can also understand
· Object file is CPU specific but OS independent
Q) We have (windows +32) bit object file. Can we run this object file on Linux + 32 bit platform to create executable.
A) Yes certainly because executables are platform dependent. Object file is CPU specific and OS independent.
Program is a collection of data and instructions. Once, after writing and giving a program to a CPU the following process will done.
If any program (or) application is loaded into system. By default that will be stored in the HARD DISK.
Once we start execution of program the stored program in HARD DISK is sends the particular file to RAM which we want to execute. Then RAM is having both data and instructions. By taking that data and instructions from the RAM, CPU will executes that data according to the instructions.
Data: - Nothing but raw supply
Instruction:- Is some thing what process has to be done with the data. (int a=10, b=20,c;- à data)
(c=a+b; à instruction)
Basically C follows 5 data types.
1. int
2. float
3. char
4. double
5. void.
Writing “C” programs on Linux platform.
Enter into Linux mode
Press Alt+F2, a small box will be open enter console and press enter it will opens an editor.
(Or)
Given a right click on mouse open a net terminal it also opens an editor. Next we can give an instruction (vim filename.c)
Directly we can’t write programs in that editor we have to enter into insert mode by pressing ‘’I’’ key on the key board (or) insert button on the key board. Then we can freely write programs. After completion of programs. Writing in that editor press escape button and press: wq write and quit (or) save and quit.
Next for compilation we have to give the following command
Gcc filename.c – output file name, then output file name given the output
Variable: is an identifier given to a piece of data.
Constants: In ‘C’: constant is a piece of data which can be of following type
Integer constant
Real number constant
Single char constant
Set of char constants.
Constants are identified (or) referred with some names called as variables (or) symbol names.
Syntax: data type variable name
Int a;
Float b;
Char c; etc.
After defining the variables only we can use those variables in the program.
Before making use of any variable in a ‘C’ program first we need to define the variable.
Variable definition will tells us TWO types
1. Name of the variable
2. What type of data is pointing to?
Int - 4 bytes
Float - 4 bytes
Double - 8 bytes
Char - 1 bytes
Float is single precision.
Double is double precision.
Combination of data and operators is called expression. In expressions we will have operands and operators here operands can be variables (or) constants.
A+b + is an operator, a, b are operands
10+50 + is an operator, 10, 50 are operands.
Operators are divided into 2 types depending upon the number of operands are required to operate on data.
1. Unary operators.
2. Binary operators.
Operator: operator is a special character whose behavior is predefined and which will always performs the given task on some operands.
Unary operators:- ++,--, size of (), logical not !.
‘C’ supports ++ and -- unary operators which can also be called as unary increment and unary decrement operators. These operators can be used in 2 phases. Depending upon how the operator appears with operands.
1. Post increment a++
2. Pre increment ++a
If operator appears after operand then it is called as post increment and it has the least priority.
If operator appears before operand then it is called as pre increment and it has the highest priority.
Same is applicable for decrement operator also.
Size of (int) ------- 4 bytes brackets after size of is purely optional.
! Logical not is also come under unary operator
Size of (expression) --------- expression can be a constant variable (or) keyword.
Binary operator:-
i) Arithmetic operators: +, - , * , / , % each and every operator returns (some value)
Each and every operator always works with the same type of data.
All operators can perform the given task on same type of data.
The return value of any operator depends upon the operator which we are using and the type of the operands.
Assignment is simply like (L value = R-value); here L value always must be a variable.
R-value may be constant, variable (or) expression.
II) Relational operator:- >, <, >=, <=, ==, !=, relational operators always returns 0(or)1.
a>b, a>c;
Pf (“a is big”);
a>b>c is not valid.(this is invalid statement)
III) Logical operator:-
&& - logical AND
|| - logical OR
! - Logical NOT
Logical AND Logical OR
Op1 op2 o/p op1 op2 o/p
0 0 0 0 0 0
0 1 0 0 1 1
1 0 0 1 0 1
1 1 1 1 1 1
Int a=10, b=20, c=30, d;
d= a>b&& a>c; valid
d= a&&b; valid
Syntax: op1 logical Operator op2
Here operands op1 and op2 are operands which can be constants (or) variables (or) expressions.
IV) Shorthand operator:- command assignment operators it can also be called as arithmetic assignment operators.
+=
-=
*=
/=
%=
Ø Compound assignment operators are always used as shorthand operators for arithmetical operations.
Ø Compound assignment operators always require 2 operands one on left side and the other one is on right side of the operator. The left operand should always be a variable of any type except strings.
Ø Compound assignment operators will take the rvalue applies on lvalue and result is again stored in lvalue.
Conditional operator:-
Syntax: exp1? exp2: exp2
Conditional operator is a very special and peculiar operator in “C”
There is no other operator in ”C” operates more than operands. 2
From the syntax esp1 will decides the output of the conditional operator.
Exp1 is true operator returns exp2, if exp1 is false exp3 returns.
Eg: int a=10, b=20, c;
C= b>a?, b:a;
In ‘C’ language any operator returns some value that value may be either ‘0’ or other than ‘zero’
In ‘c’ if an operator returns zero its always a false statement.
If an operator return other than zero that may e (1,-1,-0,-01) anything considered as a true statement.
E.g. int a=10,b=2;
B=a? a:b; valid statement and it return a value to b.
Depending upon the storage capacity data types are again divided into 2 types.
1. Single byte data
2. Multi byte data.
Single byte data – char, void.
Multi byte data - int, float, double
Weather the data is single byte or multi byte it will store in the memory by following the rule of byte order.
Byte order is nothing but how data is representing in memory cells.
Data type tells that how many bytes have to occupy byte order tells how to represent data in RAM.
Byte order is TWO types:
1. Little Endean.
2. Big Endean.
INTEL and AMD processors follow little Endean.
Motorola processors follow big Endean.
MODIFIERS: modifiers are mainly used to change (or) modify the properties of the data types these are special instructions given to data types.
Modifiers are mainly 2 types.
1. Signed modifiers.
2. Size modifiers.
Signed modifiers are again 2 types
1. Signed.
2. Unsigned
Signed modifier is the default modifier which will be applied to any variable definition if modifier is not specified. Signed modifiers will reserve one bit to tell weather the given number is positive or negative. This will be useful when we need operator on both +ve and –ve data. Max limit is 231 -1
Unsigned modifiers tell that we are going to use only +ve data. There is no need of signed bit representation in this . max limit is 232-1
Signed and unsigned are applicable for all types of data int, float, double, chat.
Size modifiers are again 2 types.
1. Short.
2. Long.
These are used to modify the size of the data short is the modifier which will always used with in tint reduces the size to 2 bytes.
Long is the modifier which can be used with both int and double.
Long int = 4 bytes
Long double = 12 bytes.
Short and long are not applicable for float because in ‘c’ it must be 4 bytes to represent a floating point data. So short is not applicable already double is there to represent floating points with 8 bytes. So there is no need for double also.
Printf(“ any characters (or) dummy representation”);
Printf(“conversion chars”, variable list);
Variable list separated by comma(,) operator.
In printf function escape characters (starts with \) and conversion char (or) format specifier (starts with %) having some special meaning other than these two anything will be written on the output device as it is.
Here when we are writing a printf with format strings we have to remember two things.
1. No. Of conversion chars must always be equal to no. of variables.
2. A variable has to write in the same order how the format strings are written in double quotes in printf.
Rules followed by “c” while evaluating arithmetic operator.
1. If any one of the operand in arithmetic expression is float the result is double.
2. If both operands are int the result is also int.
3. If any one of the operand is double result double.
4. If any one of the operand is long double the result is also long double.
5. If any one of the operand is long int the result is also long int.
6. If nay one of the operand is short(or) char the result is int.
We know that we have ALU inside CPU. This ALU will perform only integer expressed operations.
Q) Here we will have a question? Who will perform operations on float?
A) Inside processor we will have FPU. FPU will take care of the operations on floating point data.
In same 16 bit processors we don’t have FPU there we have some algorithms to perform floating operations.
Whenever we are doing operation on one int and one float, the FPU temporarily converts the int to float and floating operation will carries out
If we want to store a higher bytes data into lesser sized then we will get the overflow result.
Type casting operator: type casting operator is used to convert one data type to the other. We can convert any type of data type to the other type with type casting operator.
Syntax: (type) operand.
Type casting operator is purely unary operator as it works only on one operand.
Operands can be variables, constants (or) expressions.
E.g. int a=7, b=2;
I) Float(a);
II) Float(a/b);
III) Float (7);
E.g.: in second one float (a/b) a will be type casted as float. Compiler converts be to float. But a good programmer himself converts b also float.
So float (a)/float (b). By giving like this we can reduce the compilation time.
E.g.: float a=7.23, b=2.4
Int (a)/b gives float result only because any operand is float the result is a double so if we need output as int we have to write the above expression as
Int (a)/int(b).
Then we will get result also int.
Precedence of operator: in ‘C’ each and every operator is having precedence.
Precedence is nothing but priority of the operator which will have to evaluate first in the given expression.
Some operators in ‘c’ is having the same priority then what we should have to do?
E.g. *, /, % operators in ‘C’ are having the same priority.
In that case we will follow the associatively of the operator.
Associatively means when we are evaluating some expression contains the same priority operators more than once then associatively tells the evaluation from left to right (or) right to left.
++,--,type cast, size of R toL
*,/,% L to R
+,- L to R
=,>,>=,<,<= L to R
==,!= L to R
&&, !! L to R
?: R to L
+=,-=,*=,/=,%= R to L
, L to R
Block (or) compound statements: set of instructions inside one open curly brace and one closed curly brace is called a block (or) compound statements.
In “C” language variable definition must be at the beginning of the blocks. And does not allow the variables at the middle of the program.
In the above diagram we have totally 3 blocks. One parent block and 2 child blocks. Inside child blocks also we can define the variables. But child variables cannot be accessed by the parent block. Whereas parent block variables can be accessed by child blocks. Each and every variable in “C” is having the block scope.
The statement in “C” is divided into 2 types.
1. Compile time statements.
2. Run time statements.
The statement which executes at compile time and memory could not be occupied at any ware in memory are called
compile time statements in “C” language size of ( ) is the only operator which executes at compile time.
Reason: CPU knows all the operators except size of operator. Compiler only takes care of this size of operator;
One example is here to clarify your doubts regarding this size of operator.
· Main( )
{
Int a=5, b;
b = size of (++a);
Printf (“%d”b);
Printf (“%d”a);
}
The output of the above program is 4 and 5 only.
Here a will not incremented.
Note: except size of operator statements, remaining all statements in “C” are runtime statements.
another example to your clarification.
Main( )
{
Int a; double d;
A=5; d=10.5;
Printf(“%d”, size of (a+d));
}
Here the output will be 8.
Addition of int with double gives reset double. It will clear all your doubts when you are on practice.
Each and every compiler are having their own advantages and disvantages.
Depending upon the domain and platform we will have to select the compiler.
Gcc compilers supports long, long int, the size of this is 8 bytes.
Conditional operator needs 3 expressions. All three are mandatory in windows platform. But in Linux 2nd expression is optional. If expression 2 is not defined then result of exp1 will be the true value and the exp1 value only returns by that conditional operator.
{
Int a=10, b=20,c;
C=a? ; C;
Printf (“%d”, c);
}
Gcc compiler extensions: Gcc compiler provides short hand variable definitions when using modifiers if we want to define short int (or) long int we can define those in following format.
Short a;
Long b;
Control statements:
Conditional controlling structure:
In “C” programming each and every line executes line by line sequentially. Whenever means if we want to control the normal flow of a. C program then we will go for the above control statements. Control statements are 4 types given in the above.
In that four also we will use according to our applications wherever those are necessary.
If statements:
If is the statement takes the decision and it decides whether executes the if body or not.
If else is the another statement. Here also decision will be taken by if only but the execution statements will be either if body‘s (or) else body’s.
Here are 3 types of syntaxes in if condition.
Here the condition can be any expression variable, constant, assignment, comparison anything.
If always takes either 0 (or) non –zero. Whether condition is non-zero it is true if (zero) false.
Else is not at all an independent statement. Each and every else statement in “C” maps with the nearest if statements. If
nearest if is already mapped to another else then it go for the next nearest if statement.
Nested if conditions:
An if conditions inside another if condition is called nesting of if.
Eg: if (control exp)
{
Statement 1;
Statement 2;
Statement 3;
{
If (control exp)
{
Statement 4;
Statement 5;
}
Statement 6;
Statement 7;
}
In the above example if the first if condition is true control enters inside s1, s2 and s3 gets executed then if second if condition true s4, s5 also gets executed and next s6,s7 also executes. If second if condition is false s1, s2, s3, s6 and s7 only gets executed.
Eg: if(control exp)
If(control exp)
If (control exp)
Statement;
All if conditions have to true if statement needs to execute.
Eg:
1) If(control exp)
2) If(control exp)
3) If(control exp)
Statement1
Else
Statement2
In the above example we will get the dangling errors. We are expecting that the else if for 1st if condition but the compiler defaults maps the else to the nearest if statement. So else is assigned to the 3rd if condition.
Then we want get the expected results.
Eg: if (control exp)
Statement 1;
If(control exp)
Statement 2;
Statement 3;
//independent statement
Else
Statement 4;
The above example will raise the error. Dangling error because compiler does not allows any independent statements in between if body and else body in the above example s3 is independent statement.
So dangling error will occur at 2 types.
1. Not proper mapping of else with if condition
2. When independent statements appears between if and else.
Else if: in else if we won’t get dangling errors. Because each and every else immediately follows one if condition.
Switch: switch case is a versatile use when we need to check multiple conditions then we go for switch case.
Q) We can go multiple checks in else if also but why we prefer switch case?
A) we can get go if also to multiple checks but in if else we need to compare many times so we need ‘==’ operator so many times. To reduce writing. Long long comparisons we are using switch case. Whenever we are having multiple tasks to select a single condition with ‘==’ comparison operator we go for switch case.
Any statement ends with”:” in c language is called “LABLE”
Syntax: switch (exp)
{
Case constant 1:
____________
---------------------
---------------------
Case constant 2:
----------------------
----------------------
----------------------
Case constant 3:
-----------------------
-----------------------
------------------------
Default:
}
The actual syntax of the switch is given above.
In that exp can be any variable, constant (or) any expressions which returns integer. Switch case don’t know how to handle the values other than integers. Switch always takes only integer constants.
Switch may takes expression but case doesn’t support anything other than pure constants. which returns integers.
In the above statement if case constant 1 is satisfied the remaining two case constants also executes why?
Because case knows continuous execution from the satisfied case constant. If No case is satisfied what compiler will do?
To reduce this we will have a default: lable option.
And how to stop the switch when one satisfied case constant is appeared?
We have 3 types of statements to come out of the switch.
1. Break;
2. Go to;
3. Return;
So after changing each and every thing in the syntax. The perfect syntax would be
Switch (exp)
{
Case constant 1
----------------------
-----------------------
Break;
Case constant 2
--------------------
---------------------
Break;
Case constant 3
--------------------------
--------------------------
Break;
Default:
}
Break is always used as the end statement to each and every case constant.
· Break takes the control to exact out of the switch body.
· Return takes the control to out of main body.
· Go to takes the control wherever the program execution required.
Switch ( a )
{
Case a: ----------- variables are not allowed.
---------------------
---------------------
Break;
Case b:
---------------
-------------------
Break;
Default:
}
Switch (a>b)
{
Case (10>20):---- expressions allowed at case constant. With pure constant
Nits.
----------------------
-----------------------
Break;
Case 10:
--------------------
--------------------
Default:
}
Case constant must be as int (or) char like’A’.
If no statement needs to execute after switch body in a program then we go for return in place of break;
Order of labels is not mandatory in C language even default: also if should not lay at the end. It can be anywhere in the switch. It is other than at the end requires break (or) return.
No need to write break to the last label of a switch case. That last label may be a case constant (or) default.
LOOPS:
1) WHILE: Whenever we need to execute a statement or set of statements more than one time repeatedly. We will go for loops.
“C” supports 3 types of loops.
1. While
2. Do-while
3. For.
While loop is a iterative control statement. That allows the code to be executed repeatedly based on the given controlling expression. The while (controlling exp) consists of a single or Block of statements along with controlling exp.
The while loop first evaluates the controlling exp and if controlling exp returns true, statements present in the while body gets executed, it repeats this process until the controlling exp returns falls. Because the while loop checks the controlling exp before the body of the loop is executed, it is often called as “pre –test loop”
In “C” generally loops requires the basic following rules.
1. Loop counter definition
2. Controlling exp
3. Loop count increment or decrement.
Where loop counter is a variable use with loops and controlling exp tells when to come out of the loop. Controlling exp should be returning such a way that at some point it returns false value. If controlling exp always returns true then such loops are called as add loops (or) infinite loops which will never end.
DO-WHILE :
In do while loop irrespective of the control exp in while the do body will executes once. After executing the do body the controlling exp will checked. If controlling exp is true if again goes to do body if false if just terminates from the loop.
Do
{
Statement1;
Statement2;
Statement3;
} while (controlling exp);
In do while loop there must be semicolon at the end of while.
Q) We already have while loop then what is the purpose of going to for loops?
A) In for loop at the time of defining for itself we will give initialization, controlling exp and increment (or) decrement , so there is no chance of forgetting anyone in the loop. Where as in while loop we have to give the increment and decrement values. If we forget those in while body we may get infinite loop and sometimes serious problems also.
Q) How for loop will work?
A) In for loop control first comes to the initialization part. After initialization control goes to the next exp which is controlling expression, where the control checks the condition if the controlling exp is true then control enters into for body. After executing all statements in for body control goes to the next exp3. Which is increment and decrement? After incrementing or decrementing the value the control goes to the exp2, where the condition again checks. If the condition is true it enters into the body if fails our of the loop.
All three expressions in for loop are optional. The syntax exactly is given below to for loop.
For (init (opt, & multi); control exp (opt); increment (or) decrement (opt, multi))
For (; ;) infinite loop.
Unconditional controlling structure:
Break: the break statement terminates he execution of the nearest enclosing do, for while (or) switch statement in which it appears.
Control passes to the next immediate statement following the above mentioned statements.
Continue: continue statement passes the controller to the next iteration of the nearest enclosing does, for (or) while statement in which it appers.
Goto: the goto statement transfers the controller to a label. The given label must reside within the same function where you have used goto statements. Labels can appear after (or) before goto statements. It’s a good programming style to use break, continue (or) return statements instead of go to.
Goto is very useful and dangerous. It is architecture dependent. Whenever we need to portable that to one platform to another go to may behave differently.
As go to is unconditional statement we can take the controller in the (program) function by keeping a lable.
If we misplace a label we may get problems.
So as a good programmer maximum try to avoid go to in programs and check for alternatives.
Memory concept:
Text : the text section contains the code (or) instructions of the program as well as constants used by the program. The data stored in this section never changed this is read only section.
Stack: temporary data (or) local data is stored in stack section. All variable defined within a blocks will e part of stack section.
Physical memory: RAM is the physical memory available in sizes like 128,256,512 (MB) and 1 GB , 2 GB like that. In that each and every location is represented with one address which is also represented by the designer itself.
Whatever the address designed on the RAM is called physical memory.
Logical memory: logical address is something which doesn’t exist actually but appears to be existing. The “OS” uses manage the logical memory.
E.g. assume we have 512 MB RAM.
The logical addresses will generate for 512 MB RAM is 2512 locations.
CPU will generate logical addresses but the generated logical addresses will be managed by the “OS” to mapping the logical address to physical address.
Q) How logical memory will come?
A) With the help of MMU register inside the CPU; CPU will generate logical address.
Expiation for mapping:
Let us define a variable int a;
Int a; means that compiler is asking the CP that a need 4 bytes then “OS” come into picture and generates 4 bytes of logical memory to that. Here at int a it doesn’t store anywhere so here there is no topic of physical memory.
Int a=4;
Here 4 is assigned to a so it has to store. Some where that has to store that is physical memory.
While declaration of variable it assign’s some logical address. While initializing that to 4, that logical address is mapped to some physical address and gets stored at RAM’s physical memory.
Once the execution of the program is completed the memory mapping but logical and physical memories gets (evoperated) break.
Multi tasking : multi tasking is something we can work with many operations at a time. But CPU processes only one task at a time then how multi tasking is existing the reason is time sharing.
OS will shares the time for each and every process in equal amounts of time, but our eye can’t identify that speed.
Just assume we have 10 tasks. We open all. OS allots time to all processes. First process is running, if it completes within the shared time it is well and good. If within time it is not able to finish what will happens? That process stops and the process is stored into hard disk. Whenever its time comes back after all the shared remaining 9 tasks them again OS fleches the data from that hard disk and processes the data. The memory mapping logical addresses may vary in the second run of the process.
This is how the multi tasking will works.
For each and every process in the 10 processes each time of their time comes memory mapping will done. So each time with the process memory mapping will evoperates.
Q) if we not assigning values to variables, sometimes we will get garbage value why?
A) garbage is something which already existed in the physical memory stored by some other process previously. On evoperating memory mapping the values which stored in physical memory remain unchanged. Those values are garbage for the other programs
RAM contains a table to manage both logical and physical addresses for that time.
---------
FUNCTIONS: “C” programs needs minimum one function at least we can use ‘n’ number of functions in “C” there is no limit.
To use functions 2 things are necessary
1. Function body (or) function definition
2. Invoking the function.
DEF: function is a self set of instructions which always performs a particular task.
Q) why functions introduced in C?
A) the main purpose of functions used in C is REUSABILITY. Once a function is defined in “C” we can use that function anywhere in the program in many number of times.
A program contains only one function means that must be main ( ) function.
Q) When we go for functions?
A) Whenever we need a set of instructions at different , different places in a program then we go for functions.
Functions are of 2 types.
1. Pre defined functions.
2. User defined functions.
Predefined functions: the functions already defined and stored somewhere in the compiler are called predefined functions. “C” library is one which holds all these predefined functions.
“C” library contains all pre defined functions in OBJ format.
Eg: printf( ) , scanf( ) etc.
User defined functions: the functions who will be defined by the user and also used by the user.
The general format of “C” function definition.
Function name( )
Start print
{
Statement 1;
Statement 2;
Statement n;
} end point.
· Function names must be unique within the program.
Main ( ) is also user defined function. Except the name of the function.
Because as a user of main ( ) we only have to define the main function. So all the program have to perform will be given by OS only that’s how the main ( ) is user defined function.
Q) How to use functions?
In general if any functions we want to use. Means it should have to define first and it should has to invoked by some other function that may be predefined (or) user defined.
Main ( ) is the function which tells the compiler that from where to start the execution of the program.
The function which invokes by the other function is called, “called function”. The function which invokes that called function is called calling function.
Main ( )
{
----------
----------
----------
Demo ( ) ;
-------
-------
--------
}
In the above eg main( )is the calling function demo ( ) is the called function.
Add ( )
{
Int a=10, b=10;
Printf (“%d\n”, a+b);
}
Main( )
{
Add( );
----------
----------
----------
Add ( );
}
In the previous example in main we called add( ) function 2 times.
Two times if prints only 20. If we need both the times addition but not the same values than we go for sharing of values.
Add(int a, int b)
{
Int c;
C=a+b;
}
Main( )
{
Int d,e;
Add( 4, 6 ) (or) add (d,e) ;
Pf(“%d”, c);
}
In the example printf takes garbage value because “C” is local to called function. So if it want to return “C” to main function in “C” we should need another variable to catch the returned variable.(or) return value.
Called function always returns only one value to calling function.
So above eg: can be modified as
Add(int a, int b)
{
Int c;
C=a+b;
Return c;
}
Main( )
{
Int z,x,y;
Z=add(x,y); actual parameters
Printf(“%d”\n”, z);
}
In the above example main( ) is sharing the data with some called function. That called function processes the data and return that result to main.
By using parameters 2 things must be remember.
1. Num – ber of parameters passed by the calling function must be equal to the number of parameters in called function.
2. Data types sending with the calling function has to match with the received data types in called function.
Return single exp (or) var (or) constant;
Function names are also like variable name, but the difference is variables stores the data at some memory location.
Function also print to some memory location but where the self set of instructions will store.
Q) by default program will starts execution at main ( ) . According to ANSI standards someone has to invoke the function in “C” program. Then who is the one who invoke main ( )?
A) Shell is the one invokes the main( ) every program in “C” by default returns some value. Main returns the value to shell.
Main ( )
{
Int a;
A=disp ( ) pf(“%d”,a);
}
Disp ( )
{
Print(“’Good Day”);
}
The above program gives no error. Because there is no syntactical error. Though we avoid the return type default “C” takes int. and the above function returns 5. The number of charge in printf.
Each and every function has exit state, to main( ) we only have to give the exit state that is return o;
The exact “C” program is this
Int main ( )
{
--------
-------
---------
Return 0;
}.
The exact def of a function is
Type function name ( arguments if required)
{
-----------------------
-----------------------
----------------------
}
all instruction in main( ), disp ( ) and demo( ) will store at different, different locations in logical memory.
Whenever shell invokes main( ), the memory location where main( ) instruction are started execution sequentially. Whenever we encounter disp( ) and demo ( ) in main ( ), control goes to that memory location part where those are stored and geets executed.
After completion of the program execution the physical to logical memory chain breaks.
FUNCTION DECLARATION:
Function declaration tells the compiler that what is the return type of the function, function name and the types of the parameters and also no.of parameters.
Syntax: type function name (type, type, type------);
Once function declaration is done compiler rises error if we give wrong return type of the function (or) if number of arguments not match ( or ) if not type of arguments not match.
Header files holds all predefined function declarations, vardeclarations with extern keyword and macro definitions
|
Void is also a return of a function which should not return any value.
STORAGE CLASSES:
Storage classes tell us 3 things about a variable.
Scope
Lifetime
Where to store in memory.
The actual syntax to declare a variable is * storage class modifier type variable;
SCOPE:
Scope comes in to picture after declaring a variable in a program. After declaration of the variable scope tells that where to use that variable where not to use that variable. Again scope is fall under 5 categories.
Program scope
File scope
Function scope
Block scope
Function prototype scope
If a variable is having program scope we can use that variable anywhere in the program.
Variables are sued within that file.
Only lables in a “C” program are having function scope.
All local variables having block scope the variables which are having block scope will not be accessed outside that particular block.
Function prototype scope will be within that function declaration. i.e. any variable declared within the function prototype.
LIFE TIME:
How much time the value will bee preserved in the memory is life time of that variable. Scope and lifetime both are interrelated.
There are mainly 4 types of storage classes.
Automatic
Static
Register
Extern(or)global.
AUTO: scope of auto is local to block. Life time of auto is local to block. Auto variables always stored in stack memory section if we call a function 5 times each and every time it allocates new memory location.
STATIC: scope of static is local to block. Lifetime of static is till the program terminates. Static variables stores in BSS section. For static variables memory will store only once that too only at compile time. Default value for a static variable is ZERO.
In general the memory is allocated at runtime for local variables, whereas for static variables memory address location (logical memory) is allocated at compile time itself.
Eg: main()
{
Int a=10;
Static int b=a;
}
The above program gives the error because we could not assign any variable to static variable. For a static variable we have to assign a pure integer constant.
Eg: main()
{
Static int a=10;
Static int b=a;
}
The above program is also not valid because though both the variables are static we can’t assign any type of variable to static variable. In the above eg only memory is allocated at the time of compilation means that only addresses are allocated. At the time of run time only 10 is assigned to a, but a not assigned to b, because at run time it will not find any static variables definitions due to no physical memory is available.
NOTE: no formal arguments in any function could not use static variables, because static variables as parameters will not find at run time.
All static local variables have the entire program scope. Static variable definition gets executed only once at compile time.
Q) Advantages of defining static in main ()?
A) static variable defined inside the main() have no use as all local variables of main() will exists till the program terminates.
Q) What is the main use of static?
A) whenever we are invoking a function many times and all the times it needs to preserve that value for the next call then static is useful.
NOTE : for both auto and static scope is local to block where as comes to life time it differs, life time is also local to block for auto but for static it is entire program.
REGISTER: scope of register is local to block. Life time of register is also local to block. Register variables stores inside the CPU registers. By using register variables we can access the variables very fast, because there is no need to go to hard disk and fetched to RAM and then into CPU. Register variables are directly available in the CPU.
Register int a;
Register variables may or may not store inside the CPU. That will be decided by the compiler at the time of compile time. If it is not stored in the CPU registers means those will store in RAM’s stack memory section.
A variable defining as a register means we are telling to the CPU that the variable is using more frequently in the program. That we are telling through ‘C’ compiler. That compiler may be any. Any variable defined as a register have no address. So we can’t access the address of a register variable.
GLOBAL : scope is till the program terminates. Life time is also till the program terminates. Global variables stores in data section and BSS section. Any variable defined above all the blocks in the program is called as global or external variable.
NOTE : the global values initialized at the time of definition will store in data section and un-initialized global variables will store in BSS section.
All global values resolves at run time that means the memory will allocated at the time of compilation itself. The value of a global variable change in one function reflects the value in entire program. The default value for global is ZERO.
We can declare static also as global variables. As we know that storage classes will tell about 3 things, beyond these 3, storage classes tells about linkage also. Linkage is something which is used to create an executable from object files.
LINKAGE : linkage tells that after variable definition wheter that variable is used in same file or some other source file. LINKAGES ARE OF 3 TYPES
External linkage.
Internal linkage.
No linkage.
EXTERNAL LINKAGE: by default all global objects have external linkage. Global objects with external linkage will have program scope.
INTERNAL LINKAGE: global objects with static keyword have internal linkage. Static storage class with global and internal linkage will have file scope.
NO SCOPE: no linkage is also a type of linkage. All local variables have no linkage.
Q) what is program scope and what is file scope?
A) sharing a program among different persons or a program is divided as different modules and done all modules individually and combined to create an executable is called program scope. file is individual module scope.
NOTE : To create an executable from different files we need to take care that in all those files only one file has to be contained main().
Q) difference between definition and declaration?
A) variable definition asks for memory. Variable declaration will not asks for memory.
Extern in a; // declaration variable declaration tells the compiler that the variable ‘a’ is defined somewhere in the program externally. Whereas variable definition allocates memory for that variable.
We can access the global variables in some other source file by using declaration.
Ex:
1.c 2.c
Int a; //definition extern int a; //declaration
Main( ) a=10;
{
---------
Disp ( ) the value initialized in 2.c will
Reflects to all function in 1.c also
}
Note:
All functions in “C” by default have external scope and external linkage. Functions also have to declare in other source files if we need to access those in that file.
//function definition //function definition
Void disp( ) extern void disp( );
{
Printf(“have a nice day”);
}
In “C” language one variable can defined only once in the program and declarations can done at ‘n’ number of times in the program.
Q) how internally executable will generate in “C”?
Compiler will never see our source file, compiler have expanded source file as input.
IMP: compiler will look only one source file at a time where as linker will look all object files at a time and it links all the obj files to create an executable. Executable contains complete information about variables.
All global object definitions with external linkage will have two tables
Export
Import
There are some other tables also for time being these we take.
Export tables contains all definitions of global variable import tables contains all declaration of global variable.
Assume that we have given a command
Gcc 1.c 2.c 3.c
“a” is defined in 1.c and declared in 2.c and 3.c
First compiler sees 1.c it allocates memory to a ad creates an object file. Next compiler sees 2.c and assumed by looking the declaration that a is defined somewhere externally and creates object file in the same way for 3rd source file also, compiler creates an object file.
After creating all the object files linker comes into picture and links all the object files and creates an executable.
PRE PROCESSOR: pre processor processes our source file. After pre processing we will get translated unit code.
Pre processor is a separate language, it has its own instructions.
Each and everything in “C” programming, pre processor takes that as a token (or ) a string.
Eg: int a=10;
In the above eg preprocessor assumes that int is one word and a=10; is one string.
If we give int a=10;
Int, a, =,10, ; all are different, different words for preprocessor
Pre processor removes all comments in our source file comment won’t look by compiler.
\is the special char used to attach more than one line we come across in the source file.
Those all different lines also make as a single line by preprocessor does the source file to tokenization.
IMP: tokenization is something converting code one form to other.
all preprocessor instructions are called preprocessor directives. Each and every directive starts with # symbol.
#include< > is the header file which just copies all instructions of that herder file and past’s those into or program.
We have different directives
Defines some data directives.
Function directives.
Controlling directives.
IMP: pre processor variables are called “MACROS” macro is preprocessor variable name refer to some data. No memory will be allocated for macros.
Syntax : #define name definition
# define macro value.
#define a 10
“C’” preprocessor supports 2 types of macros
Object like macros.
Function like macros.
Preprocessor won’t touch the instructions which will understandable by compiler but not by preprocessor.
Preprocessor keeps those as it is .
Macros are nothing but symbolic constants.
Object like macros are defined like
# define Uint, unsigned int
Main( )
{
Uint a; (un signed int a);
--------------
---------------
----------------
}
Function type macros will define as
# define add(x , y) x+y
add(10,20);
add(10.5, 2.5);
add(‘a’, ‘b’);
add(“Veda”, “Anjali”);
all the above statements are valid for compiler and pre processor, but 4th statement is not valid for compiler.
#define name (arguments) definition
Eg: #defind max(x,y) x>y?x:y.
#define add(x,y) x+y
Main( )
{
Add(10,20);
Add (10.5 2.5);
Add(‘a’, ‘b’);
Add(“John”, “Mill”);
}
From the above eg: two strings we cannot add,
Drawback is function like macros is this only, that is we can’t restrict the user to give particular type of arguments because everything for preprocessor is a string. So the forth statement is not a valid statement for compiler.
Function like Macros may look like function invocation statement, but function like macros arguments can’t be defined for a specific type everything is a string for preprocessor.
So always we need to define the macros in such a way that after replacement it should be valid statement for “C” compiler.
The only difference between object like macros and functions like macro is arguments function like macros takes arguments object like “ “ No arguments.
Whenever we are working with macros up to some extent of the program we requires one value for the macro and later we require another value with the same name then we go for redefining a macro.
Redefining macros in 2 types
undefined the macro and redefine the macro with the same name.
eg: # define max 100.
Int main( )
{
-------
---------
#undef max
--------
---------
#define max 200
-----
------
}
we can directly redefine the macro without undefined the existed macro
#define max 100
Int main( )
{
-----------
------------
#define max 200
}
From the above eg we can say that undefined macro is optional.
Macros don’t have any scope and lifetime.
Header files contains only 3 things
Macro definitions
Predefined function prototypes
Variable declarations with extern keyword.
Macro will do just replacement.
There are some pre defined macro also. We have 3 types of predefined macros also.
Language specific macros way compiler is having language specific macros.
Compiler specific macros compiler designing people will define these macros.
System specific macros these macros will be designed by OS people
Linux compilers having version numbers major number, minimum number and path number.
All “C’” header files in Linux exists in /user/include.
We have to define the macros such that after preprocessing the source file, the generated translated unit must be valid input for the compiler
Eg; #define macro *Name Of Macro*
Main( )
{
Pf(“%s”, macro);
}
This is not valid for the compiler
#define macro “Name Of Macro” this is valid statement for compiler
If we want to pass a string as argument
#define macro(s) #s
Main( )
{
Pf(“%s”, ”Hello world”);
}
We can write any string in that printf here the #symbol before S is called stringification operator
Stringification:
whenever macro definition should act like a string constant for the compiler we will use # operator with their definitions # operator is called stringificatin operator which returns the given definition with in “ “.
Concatenation operator:
whenever we want to concatenate 2 arguments of a function like macro we will use double hass (##)
concatenation operator concatenates 2 strings of a function like macro arguments and returns as a single value.
#define STR (S1, S2) # (S1 ## S2)
Main ( )
{
STR ( Hello world)
Pf(“%s”, STR(Hello world));
}
The above gives Hello world
The # before (s1 ## s2 ) gives the entire concatenated string in double quotes.
# define STR (S1, S2) S ((S1 ## S2))
# define S (a) #a.
Preprocessing supports conditions compilation.
Conditional compilation is done according the conditions which we defined for preprocessor.
## def it always checks whether macro is defined or not.
# if n def this is exactly opposite to # if def, we will tell the preprocessor that if not defined do something.
# if this allows us to evaluate expression same like if.
# else
#el if
#end if
# if is also used to check whether a macro is defined or not by using the following statements.
# if defined macro
#define max 100
#define min 10
Int main( )
{
--------
--------
# if def max
-----------
------------
# end if
----------
-----------
#ifn def max
-------
--------
# end if
#if max >=100
-------
-------
# end if
#if defined max
------------
------------
# end if
# end if
}
#define max 0
Main( )
{
---------
---------
# if def max
Printf (“defined”);
#end if
# if max
Printf(“defined”);
#end if
---------
---------
#if defined max
Printf(“defined”);
#end if
}
Whenever we need to share function declarations and macros in different source files of a program we need to include files like.
Each and every compiler have its own default search path
#include default search path
#include “stdio.h” obsolete path
Compilation starts from the resent working directory and ends at default search path.
Q) if we include some header file multiple times what happens?
A) all the times it includes that file, it wastes so much memory.
Q) what should we have to do if by mistake we have a include a file multiple times?
A) to avoid recursive inclusion of header files we will define one macro within the header file and we check whether the macro is already defined or not? If that macro is defined header file no included, if not defined header file include. To accomplish this we will make use of conditional directives.
Eg: include<”my.h”>
Include<”my. h>
# if ndef my
Float add (int, int0;
Int demo (float)
#define my
#end if
Gcc –d positive ifdef.c
In general # include , like standard headerfile will follow this conditional directives only.
-D is the option of gcc command to define macros at command prompt while compilation.
Gcc –I/ demo’c
This command temerorily to default search path. Of the header file.
-I- for preprocessor
-L- for linker.
Varidic functions: veridical functions are very special functions, these are used whenever we don’t know the number of arguments has to pass and the type of the arguments to hold .
In general all printf and scanf functions are defined with varidic functions only because. Possing arguments and type of arguments to printf and scanf is varied from time to time according to the application requirementns.
Syntax of varidic function is type func-name(. . .)
If we find 3.s in any function it is a varidic function.
Varidic functions has the flexibility to take no.of arguments and the type of the arguments.
To handle varidic functions some set of macros are already predefined
Those are va-list int add(. . . );
Va_short. Add (2,10,20);
Va_arg. No.of arguments
Arguments to add
Va_list obj; if holds variable length arguments.
Va_start (obj, arguments )this arguments is fixed.
Any varidic function always must and should contain at least one fixed argument va_arg( , ),
Beyond function in “C” C99 supports inline functions.
Inline function:
all the time of function invocation if replaces the entire program at the definition itself we have to mansion that inline keyword.
Inline int add (intx, inty);
{
}
Inline functions are useful in small function definitions. It is not useful for large functions because those occupies more memory.
With the definition of the inline function we are telling the compiler that we are going to use this function frequently.
As like register storage class it may. Also treated as inline (or) ordinary functions.
Pointers
Pointer is a derived data type which allows us to define a variable which has the ability to store address of another variable.
Syntax: type * variable;
Type followed b ‘*” tells that variable is a pointer variable.
We can use pointer variables to any type.
Int * double * float * char * void *
Eg: int p=10; //value 10 store in p
Int *p=10; // address 10 stored in printer p
Each and every address is un signed. Because there is no address with –ve values.
Size of address is always equals to the word size of the architecture.
For any architecture .int =pointer = word size.
Pointers always deals with 2 special chars.
*
&
1.* ‘*’ is used to define a variable
‘*’ is used to dereference the pointer
2.* ‘&’ address operator.
These both are pure unary operators under pointers. Because both will operate on single operand.
We can initialize pointers in 3 types.
Int a=10, *p;
P= &a; 1
P= 0; 2
P =null 3
Null is a macro which already defined except these 3 forms we can’t assign any value to pointer variables
DEREFERENCEING:
Pointers are having the capacity to fetch the value present in the variable which address that pointer is stored. Is dereferencing .
To print the addresses of a pointer we use %p , % x, %u (conversion characters)
Null pointers are something which pointing to no where pointers stores logical addresses only.
The type of the pointer is telling that at the time f dereference how many bytes has to retrieve.
Pointers always deal with the similar type of variables.
Int a;
Char*p =&a // invalid.
Double b=10.5;
Int *p =&b // invalid.
We can’t perform addition, subtraction (or) any arithmetic operations on two pointers.
Int *p, *q
P+q //invalid;
We can use limited operations and limited operators on pointers.
++ increment
--decrement.
+ - with some restrictions.
We can use size of, relational and logical also.
We can use additions (or) subtraction with pointers is given below: pointer + variable (int, char) constant (“ ,”).
Int a,b,c,=10, *P;
B= p+a;
P+c;
P+10;
*,/,% we can’t operate on pointers.
Wild pointers:
The pointers which are defined but not initialized properly are called wild pointers. So we can’t use the pointers without proper initialization.
Sometimes wild pointers terminates our application. Because of wild pointers we will get some segmentation faults.
Memory violations are called segmentation faults segmentation faults are pure RUN TIME errors. Due to security purpose as will terminates the applications
Void pointer:
Void pointer is the one which can store any type of data. Void pointers are also called as generic pointers.
Void *p;
Int a p =&a;
Float b p= &b;
Double p =&d;
We can’t derefer the void pointers directly void pointers are dereferred by using type casting type casting temporarily changes the operations.
Int a=10;
Void *p; dereferencing through
*(int*) p; type casting
(4 bytes)
*p; 1 byte.
Beyond modifiers we have 2 specifiers.
Const
Volatile.
Const int a; const int a=10;
The state of the const variables voill no be change throughout the program.
Const keyword only have read only permissions const is a pure compile time statement.
Q) we can define constants through macros also, what is the difference between macro and const?
A) ma
RAM won’t have read only memory locations. RAM has read. Write memory locations.
Compiler will check the illegal operation on the const symbol compiler won’t allow any operations on censt variables. Compiler will try to remove all the statements which area trying to change const values.
Const variables has to initialized at the time of definition itself.
Macros won’t occupy memory.
Const occupies memory.
Const float pi; float c;
Pi; 3.14; //error
C= pi+1; initialization is not possible after definition of const variable.
Eg: const int a=10;
Int *p =&a;
*p =20; // valid.
From the above eg. We can tell that const values can also be changed by using pointers.
So by that we can tell that there is no security.
Q) Then how can we provide security for const variables while using pointers?
A) While using pointers we can provide security to const variable by applying const to pointer at the time of initializing address to the pointer.
Const int a=10;
Const int *p =&a ; (or) int const *p = &a;
This is printer pointing to constant.
Q) What to do if pointer itself is constant.
Int * const p // const is nearest to pointer const is the keyword it should bound its properties nearest to the type.
Const int * const p =&a;
Const pointer itself is pointing to a constant.
We can’t derefer a void pointer until and unless we type cast that.
Even we can’t perform any operations on void pointers gcc allows us to increment void pointers.
Invoking the function with their address is called call by reference. There is no need of return statement in called function.
Main ( )
{
Int a=10, b=20;
Swap (&a, &b);
Printf(“%d %d”, a,b);
}
Swap( int *a, int *b)
{
Int temp +*a;
*a = *b;
*b =temp;
}
Generic functions always written by void pointers.
ARRAY:
Array is a collection of sequential memory locations used to store similar type of data. Array is also a derived data type.
Derived data type are derived from primitive data type.
Whenever we need to store number constant with a single variable name then we go for arrays. Those constants may be, int, char, float, double etc.
Syntax: type name [size]
Int a[5];
INITIALIZING ARRAY:
Initialization of arrays is possible at the time of definition and also later like ordinary variables.
Int a[5] ={1,2,3,4,5}
(or)
A[0] = 1;
A[1] = 2;
A[2] = 3;
A[3] = 4;
A[4] = 5;
Offset always starts from 0 and ends with size -1.
Offset = index = suffix = subscript .
Array variable always gives the starting address of the array.
Size of array always pure. Int constant according to ANSI standards variable lenth arrays are not supported.
Int a=5;
Int b [a]; //ansi error but gcc allows.
Q) Variable length arrays are not initialized at the time of definition why?
A) Variables are resolved at run time. So without knowing the values how culd we assign the values to array. That’s why we don’t initialize the values to variable length arrays.
At compile time compiler will treat a[5] as a[ ], that’s all.
The size of array must always be pure int constant index is the one which used to manipulate individual elements of the array.
Pointers and arrays are inter related.
Eg: letus assume we have defined an array.
Int a[5];
Pf (“%U”, a) (&a or a)
By default it will display the starting address of the array. The type tells that , this array going to store interger type of data.
But internally it takes as a[b] address. Whenever we increment a value as a[0] to a[1] there inside the processor that increments 4(or)8 bytes according to the type because internally that array gets stroed as a pointer variable. A[0] =*(a+0), a[1] =* (a+1).
There is no difference in writing an array as a[5]; and 5[a] index is no was helpful at RUNTIME.
By using indexes only compiler manipulates dereference internally.
Logical addresses are sequential but not physical. Physical may (or) may not sequential.
Q) function always returns only one value then how could we return all array values?
When we are dealing with arrays by default it passes the starting address of the array while we call that function. That called function the format arguments catches this address and they act as a pointers. Because pointers stores addresses, and it takes 4 bytes that may be any type.
Int main( )
{
Int a[5] ={1,2,3,4,5,};
Add (a); call by reference
}
Void add ( int b[5] (or) (int *p) both are correct .
{
Int i-0;
For (;i<5 font="font" i="i">5>
b[i]+=1;
}
Array of pointers is also possible. Array of pointers stores addresses of similar type of values. Because whenever we are derefering those values we have to get the same number of bytes in each and every iteration.
Eg: int a=10,b=20,c=30;
Int *p[3] ={&a, &b, &c};
*p[1] =50; is also possible.
Command line arguments:
Passing arguments to a “C” program through command prompt.
Function pointers:
Pointers not only stores the address of a variable but also stores the address of functions also.
Each and every function has its own address.
Type (*pointer name) (arguments); // declaration
Int (*fp) (int,int); // of function pointers.
Int demo (int, int);
Int (*fp)(int,int); signature of both should match.
We can derefer the function pointers also here the dereferencing is nothing but executing the instructions of that function.
We can pass functions also as arguments. Function pointers is the only way to pass function as arguments to other function.
By using function pointers only we can implement polymorphism in C++;
Single object is having multiple behavior is called polymorphism.
Behavior of the function pointers is defined at run time.
*imp:
Function pointer con be derefered without “*” symbol also.
We can’t do arithmetical operations on functions pointers.
Array of function pointers :
Array of function pointers is also possible.
Type(* fp[5]) (arguments);
Q) how can we get the required function to be executed by invoking. Without using any switch (or) control loops?
A) by using function pointer array initialization.
STRING
Set of characters in double quotes is called a string we can manipulate strings in “C” is by using character arrays.
Character arrays are only read from the keyboard(or) write to the output device element by element (or) total string at a time.
Remaining all arrays we must and should have to read element by element only int a[5], float b[5], double d[5], all are only element by element.
There are two possible ways to initialize character arrays.
Char a[20]={‘h’,’e’,’l’,’l’,’o’};
(or)
Char a[20] =”hello”;
With all character array initializations (or) taking strings from keyboard. The last value must be ‘\o’, “null”.
‘\o’ is provided by compiler itself internally at the time of RUNTIME.
Char a[20] = “hello ctutorial”;
For (i=0;a[i]!=’\o’; i++)
Printf(“%c”, a[i]); (or)
Printf(“%s”, a);
It we initialize like char a[25] = { };
Like this, it will place all 25 values with null ‘\o’; this is called NULL STRING.
Scanf:
Scanf is also called as formatted input function.
Scanf is a function of call by reference.
Scanf is a pure variadic function.
Q) There is no need of giving ‘&’ in scanf for strings . why?
A) String is a character array. Passing an array is itself passing address of that array to the function.
“C” supports of 2 types of arrays
Static (memory) arrays.
Dynamic arrays.
For the static arrays we have to mansion the size at the time of definition itself. And also it. Will be allocated at compile time itself.
Dynamic memory:
Allocating and deal locating at runtime is called dynamic memory.
Whenever we don’t know the number of elements the user will enter, then we will go for dynamic memory. In dynamic memory we will have some functions to allocate and deal locate memory.
1)malloc ( ): void * malloc(int); default the return type of malloc is void pointer it takes only one argument that too pure int. malloc returns the starting address.
Eg: int n,*p;
Printf(“enter number of elements required”);
Scanf”%d”, &n);
P=( int *) malloc (n* (size of (int)));
For (i=0; i
P[i] =i++;
Is the above Eg: we are stroing te address returned by malloc function into a pointer variable p.
Here p will stores the starting address of the memory where malloc allotted and this p shores malloc’s address in stack section.
Assume n=10, p=1000 diagram
All dynamic memory will be stored in heap section.
Malloc allots memory as a single block. It space is not available as a single block in heap section then simply malloc assigns NULL to pointer p. so p=NULL;
By default the allotted space contains garbage in using malloc.
2)calloc( ); void *calloc (total no.of elements, size of each element);
Calloc( ) takes two arguments. By default calloc( ) initialize all values to zero. Calloc stores its data in multiple blocks. It also returns null if required space is not there in heap section.
Eg: int n,*p;
Calloc (10;4);
IQ: difference between malloc ( ) & calloc.
1)it takes one argument 1)it takes 2 arguments
2)by default initialized values 2)by default initialized values
Are garbage are zero.
3)stores as single blocked memory 3)stores as multiple blocked memory.
3) b Zero( ):
It is one function used to initialize all values in an array to zero.
Void * b zero (starting address, total size of elements);
This function can be used with static memory also.
P=(int*) malloc (40) int a[10]; int a[10]
B zero(p,40); bzero(a,40); bzero(&a, 4);
Bzero( ) initializes the data byte by byte.
The combination of malloc ( ) and bzero( ) is calloc ( ).
Memset ( ):
This also same like bzero but initialized the data with given values. And it takes 3 arguments.
Void * memset( void*s, intc, intn)
Starting add with what total no.of
From where value we want to Bytes to
Values has to initialize. Initialize.
Initialize.
Realloc ( ):
Realloc is another dynamic memor function used to alter the previously allocated memory by malloc (or) calloc.
Void* realloc (address of malloc (or) calloc, new size);
P=(int*) malloc (40);
Q=(int*) realloc(60);
Realloc searches for a new memory space for 60 bytes if no extra 20 bytes free at address “p” and values are copied if necessary and deallocates the previous memory.
Free ( ):
Free ( ) is one function deallocates memory allotted by malloc ,calloc, realloc .
Free (p), it takes only one argument that is address.
Eg: p=malloc (40);
------------
------------
P=malloc(80);
---------
---------
With our freeing previous memory will get memory link error. So .
P=malloc (40);
--------
---------
Free (p); p=null ; (imp);
p-malloc (80);
----------;
----------;
Q) after free (p) we have to initialize P with null why?
A) freeing memory means we can use that memory for another purpose in p we are storing starting address. If we call again p without initializing to null previous values it prints. So that is garbage to the next program.
IQ) how free( ) function knows howmany btes has to free?
Diagram
All dynamic memory allocation functions not only allocates required memory but also allocates some extra memory (8bytes) which is used to hole information about malloc,calloc, realloc, such as bytes allocated to these functions.
Magic number is managed by “OS” whenever we call free( ) function it goes back to 8 bytes from the starting address and fetches how many bytes has to free.
Q) p= realloc (null,40)
Equivalent to
Malloc (40)
IQ) malloc ( 0); this is purely library implementation dependent in general allocates 1 bytes in so many compilers.
Two dimensional arrays:
Two dimensional arrays are used to implement only matrix problems.
Type name [row] [column];
Inside memory two dimensional array elements will store sequentially
Int a[2] [3];
We can initialize two dimensional arrays in two types.
Int a[2] [3] ={1,2,3,4,5,6} (or) {{1,2,3,},{4,5,6,}};
For (i=0;i<2 font="font" i="i">2>
For(i=0;i<3 font="font" i="i">3>
Scanf (“%d”, &a[i][j]);
Inner loop paces all the elements inside the memory according t the columns numbers.
(a+1) means incrementing 3*4 =12 bytes.
A pointer increments a row size int double dimensional arrays.
(a+1)+1 means second row first column.
Multi dimensional arrays a[2] [2] [3] total no. of two dimensional matrixes.
Two dimensional strings.
Char str [10] [50]; this is definition to 10 strings with each size 50.
IQ) 1) char *p= “string” ; it will works.
2) char *p=’string”;
Char =’b’;pf(“%s”,P); this gives error.
Because any thing stored in “ “ is a constant all constants will store in text section we can’t change the text section data. That’s why it will give error. Text section is having only read permissions.
Q) const int a=10; can we change the value of 10?
A) exactly we can change the value of a; by using pointers.
Up to now we have seen all programs are interactive, now, we will look at non-interactive programs.
Arguments taking from direct control at the time of giving executable file itself. These type of programs will be written by passing arguments through main( );
Main is having the ability to take two types of arguments.
Int main (int, char * [ ])
Cahr *[ ] is a double dimensional string in general we will represent double dimensional string array as char * a[ ];
By sending arguments through command prompt it will counts executables also as one arguments.
In general main arguments given with the variables names (argu, argv)
Int main(int argc, char*argv [ ])
Argc –argument count;
Argv- argument value.
Int main (int argc, char * argv[ ])
{
Int a, b;
Scanf(“argv”, “%s,%d,%d”, &a,&b);
Printf(“%d”, a+b);
}
STRUCTURES :
Structures is a special type of user defined data type. Whenever we need to store different types of data with a single name we go for structures.
Structure definition
Struct tagname
{
Type member 1;
Type member 2;
Type member 3;
};
Structure definition won’t occupies any memory. Whenever we will create a variable for a structure then memory will be allocated for the structure. Here variable means object creation.
We can initialize structures in two ways.
Sturct student
{
Int rno;
Cahr name [40]; gender;
Char dob[15];
};
I)struct student s1,s2,s3; // objects creation.
Sl.rno =100;
Strcpu(sl.name, “walker”);
Sl.dob =”12-02-2008”;
II)method: struct student sl={100, “walker”,’V’, “12-02-2008”}
By initializing like this method we have to follow the same order in structure how the members are declared.
Sl.name [2] =’s’; we can do this type of definition itself.
Data of the structure is stored sequentially inside the memory.
Structure definition means creating our own data type with different primitive datatypes.
We can use any data type in structures including derived data types like arrays and pointers also.
Size of the structure is sum of the bytes occupied by all the members of the structures.
Eg: struct abc
{
Int a;
Float b;
Double c;
Char d;
}
In the above eg: without character the size of the structure is 16 bytes.
Q) where as with char the actual size is 17 but output get as 20; why?
A) processor always works with the word size of the architecture. For that reason compiler itself provides 3 extra bytes to process the date easily. This is one optimization providing by compilers this is called structure padding.
Multiple of word size of the architecture makes the execution fast. If compiler won’t provide this padding processor will do that but it takes some time.
To avoid structure padding in gcc we will have a command used with the members (or) at the end of the curly brace before semicolon.
Struct abc
{
Int a
Float b
Char c
}—attribute –(packed);
Type def: type def is an alias name given to any existing data types. That may be predefined or user defined.
Type def type aliasname;
Eg: 1) type def int integer
Integer;
2) type def interger [10];
Integer a;
Here in the above eg: a in the sense a is an array of 10 elements.
3)type def int pointer*;
Pointer b;
B=&add; etc;
4)type def float (*fp) (float, float)
5) type def struct
{
Int a;
Flaot b;
Char c;
}
Data;
//here data is not object name datais tagname.
While going to typedef using for structures we can type def in two ways. One is pevious eg: and the other follows
6)sturct student
{
Int rno;
Char gender;
Float height;
};
Type def struct student stu;
Stu obj;
Q) we con’t return array, where as we can return structures why?
A) arrays are not wrapped inside memory . but structures are wrapped inside memory.
We can define pointer for structures.
Eg: struct A
{
Int a;
Double d;
}
Obj,* poi;
Poi=&obj;
(*poi).a=100 (or) poi – a=100;
(*poi).b=10.5 (or) poi – b =10.5.
-- is called structure pointer dereference operator.
Q)how to allocate structe memory?
A) by using dynamic memory allocations.
Q) what is the main drawback of structures.?
A) as we know that each and every primitive data type is having composition and operation. Where as structures no body defined operations that’s why oops in c++ come in to picture.
(ADT) abstract datatype: using function pointer as member functions of a class is called ADT. Linux is designed using “C” language with these ADT that means oops principles.
BIT FIELDS: bit fields are used not to waste the memory bit fields are purely designed for structures.
Syntax: type name: no. of bits.
Even though we have mentioned type have it won’t take that much size of just occupies only the specified no.of bits.
Eg: struct date
{
Unsigned short day:5;
Unsigned short mon:4;
Unsigned short year:12;
};
Struct date d;
While using bit fields with structures, the size of the structure is rounded to neares multiple word size of the architecture.
While using attributes it rounds to the neares by multiple byte size.
We can initialize bit fields with only assignment operator. We can’t initialize directly. By taking temporary variables inside main we can do that.
We can’t declare bitfields for float (or) double.
The minimum no. of bits to represent signed bits is 2 because one is for sign another is for data. But for unsigned min is one bit.
Structure nesting:
A structure can hold another structure’s objects its member (or) another structure’s definition as its member is called nesting of structures.
Eg:
Struct abc
{
Int a, b, c;
Float d;
Struct def obj;
}
Obj1;
(or)
Struct a b c
{
Int a,b;
Float c;
Struct def
{
Char c;
}
Obj;
};
Whenever we are defining structure definition inside another structure definition better create object there itself at the end before semi colon.
UNION: union tag name
{
Int a;
Float b;
Char c;
Double;
};
Total representation of union is similar to structure only.
The main difference is structure allocates memory individually for element by element.
Where as for union structure allocates memory only the size of the highest member in the union definition.
And also we can’t implement operations all at time in union. Because the same memory is used by all the members.
zPadding is possible with union also. Because some times unions contains structures (or ) structures contains unions.
Libraries are collections of pre compiled function that have been written to be reusable.