0% found this document useful (0 votes)
31 views17 pages

1 BASICS FUNCTIONS Notes

Uploaded by

fitecek253
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
31 views17 pages

1 BASICS FUNCTIONS Notes

Uploaded by

fitecek253
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 17

PROGRAMMING BASICS

Basic Structure of “C” Program


A ‘C’ program is a group of building blocks called functions. A function is a subroutine
that may include one or more statements designed to perform a specific task. To write a C
program we first create functions and then put them together. Any C program may contain one or
more sections as shown in the figure.

Documentation Section

The documentation section consists of a set of comment lines giving the name of the
program, the author and other details, which the programmer would like to use later. There are
two types of comment lines.
1. Block comment lines /* */ and
2. Single line comment lines. //
Link Section

The link section provides instructions to the compiler to link functions from the system
library.
Ex: The statement #include<stdio.h> instructs the compiler to include the file “stdio.h” before
starting the compiling step.

Definition Section

It is used to define symbolic constants and to define macros. The preprocessor directive
#define is used for the purpose.

Ex: # define PI 3.14 assigns the symbolic name PI to the constant value 3.14

Global declaration Section

There are some variables that are used in more than one function. Such variables are
called global variables and are declared in the global declaration section that is outside of all the
functions. This section also declares all the user-defined functions.
Main( ) Function Section

The main( ) is a special function used by the C system to tell the computer where the
program starts. Every program must have exactly one main function. This section has two parts
a) Declaration part b) Execution part
a) Declaration part: It declares all the variables used in the executable part.
b) Executable part: There is at least one statement in the executable part.

These two parts must appear between the opening and closing braces. The program
execution begins at the opening brace and ends at the closing brace. The closing brace of the
main function is the logical end of the program. All statements in the declaration and executable
part end with a semicolon.

Subprogram Section

This section contains user defined functions that are used in the main function. User
defined functions are generally placed immediately after the main function. All Sections except
the main function section may be absent when they are not required.
1. For Example a ‘C’ program that prints welcome message:
/* A Sample C program */\\

#include<stdio.h>

int main( )

{ /* prints the string*/


printf(“Welcome to C Programming\n”);
}
Data types and Sizes
Data types are used to store various types of data that is processed by the program. Every
programming language has its own data types. For each variable we have to attach some data type.

The data type defines

a) The amount of storage allocated to variables.

b) The values that variables can accept.

c) The operations that can be performed on variables.

‘C’ language supports following data types.

Primary (Basic) data types

All C Compilers support the following primary (or fundamental or basic) data types namely
integer (int)
floating point (float)
character (char)
A type modifier (qualifier) such as short, long, signed and unsigned when applied to the above
basic types yields additional types.
1. Each of these modifiers (short, long, signed and unsigned) can be applied to the basic
data type int.
2. The modifier signed and unsigned can be applied to the basic data type char.
3. In addition, long can be applied to double.

Integer Data types

‘C’ offers three different integer data types. They are short int, int, long int in both signed
and unsigned forms. The difference between these three is the number of bytes to occupy and the
range of values. The size and range of data types on a 16-bit machine are given as follows.

Floating point types

Floating point numbers (real numbers) are defined in „C‟ by the keyword float. ‘C’ offers

different floating point data types. They are float, double and long double.
Character data types

A single character can be defined as a character (char) data type. ‘C’ offers two character
data types. They are signed char and unsigned char
The smallest to the largest data types with respect to size are given as follows:

C-Operators
One of the most important features of C is that it has a very rich set of built in operators
including arithmetic, relational, logical, and bitwise operators.

Assignment Operator
int x ;
x = 20 ;
Some common notation :- lvalue -- left hand side of an assignment operation
rvalue -- right hand side of an assignment operation

Type Conversions :- the value of the right hand side of an assignment is converted to the type
of the lvalue. This may sometimes yield compiler warnings if information is lost in the
conversion.
For Example :-
int x ;
char ch ;
float f ;

ch = x ; /* ch is assigned lower 8 bits of x, the remaining bits are discarded so we have a


possible information loss */
x=f; /* x is assigned non fractional part of f only within int range, information loss
possible */
f=x; /* value of x is converted to floating point */

Multiple assignments are possible to any degree in C, the assignment operator has right to left
associativity which means that the rightmost expression is evaluated first.

For Example :-
x = y = z = 100 ;
In this case the expression z = 100 is carried out first. This causes the value 100 to be placed in
z with the value of the whole expression being 100 also. This expression value is then taken and
assigned by the next assignment operator on the left i.e. x = y = ( z = 100 ) ;

Arithmetic Operators
+ - * / same rules as mathematics with * and / being evaluated before + and -.
% modulus / remainder operator

For Example :-
int a = 5, b = 2, x ;
float c = 5.0, d = 2.0, f ;

x=a/b; // integer division, x = 2.


f=c/d ; // floating point division, f = 2.5.
x=5%2; // remainder operator, x = 1.

x = 7 + 3 * 6 / 2 - 1 ;// x=15,* and / evaluated ahead of + and -.

Note that parentheses may be used to clarify or modify the evaluation of expressions of any
type in C in the same way as in normal arithmetic.

x=7+(3*6/2)-1; // clarifies order of evaluation without penalty


x=(7+3)*6/(2-1); // changes order of evaluation, x = 60 now.

Increment and Decrement Operators


There are two special unary operators in C, Increment ++, and Decrement -- , which cause the
variable they act on to be incremented or decremented by 1 respectively.

For Example :-
x++ ; /* equivalent to x=x+1; */

++ and -- can be used in prefix or postfix notation. In prefix notation the value of the variable is
either incremented or decremented and is then read while in postfix notation the value of the
variable is read first and is then incremented or decremented.

For Example :-
int i, j = 2 ;

i = ++ j ; /* prefix :- i has value 3, j has value 3 */


i = j++ ; /* postfix :- i has value 3, j has value 4 */

Special Assignment Operators


Many C operators can be combined with the assignment operator as shorthand notation
For Example :-
x = x + 10 ;
can be replaced by
x += 10 ;
Similarly for -=, *=, /=, %=, etc.

These shorthand operators improve the speed of execution as they require the expression, the
variable x in the above example, to be evaluated once rather than twice.

Relational Operators
The full set of relational operators are provided in shorthand notation
> >= < <= == !=

For Example :-
if ( x == 2 )
printf( “x is equal to 2\n” ) ;

Logical Operators
&& -- Logical AND
|| -- Logical OR
! -- Logical NOT

For Example :-
if ( x >= 0 && x < 10 )
printf( “ x is greater than or equal to zero and less than ten.\n” ) ;

Note : There is no Boolean type in C so TRUE and FALSE are deemed to have the following
meanings.
FALSE -- value zero
TRUE -- any non-zero value but 1 in the case of in-built relational operations

For Example :-
2>1 -- TRUE so expression has value 1
2>3 -- FALSE so expression has value 0
i=2>1 ; -- relation is TRUE -- has value 1, i is assigned value 1

Note : Every C expression has a value. Typically we regard expressions like 2 + 3 as the only
expressions with actual numeric values. However the relation 2 > 1 is an expression which
evaluates to TRUE so it has a value 1 in C. Likewise if we have an expression x = 10 this has a
value which in this case is 10 the value actually assigned.

Note : Beware of the following common source of error. If we want to test if a variable has a
particular value we would write for example

if ( x == 10 ) …
But if this is inadvertently written as

if ( x = 10 ) …

this will give no compilation error to warn us but will compile and assign a value 10 to x when
the condition is tested. As this value is non-zero the if condition is deemed true no matter what
value x had originally. Obviously this is possibly a serious logical flaw in a program.

Bitwise Operators
These are special operators that act on char or int arguments only. They allow the
programmer to get closer to the machine level by operating at bit-level in their arguments.

& Bitwise AND | Bitwise OR


^ Bitwise XOR ~ Ones Complement
>> Shift Right << Shift left

Recall that type char is one byte in size. This means it is made up of 8 distinct bits or binary
digits normally designated as illustrated below with Bit 0 being the Least Significant Bit (LSB)
and Bit 7 being the Most Significant Bit (MSB). The value represented below is 13 in decimal.

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0


0 0 0 0 1 1 0 1
An integer on a 16 bit OS is two bytes in size and so Bit 15 will be the MSB while on a 32 bit
system the integer is four bytes in size with Bit 31 as the MSB.
Bitwise AND, &

RULE : If any two bits in the same bit position are set then the resultant bit in that position is
set otherwise it is zero.

For Example :-
1011 0010 (178)
& 0011 1111 (63)
= 0011 0010 (50)

Bitwise OR, |
RULE : If either bit in corresponding positions are set the resultant bit in that position is set.

For Example :-
1011 0010 (178)
| 0000 1000 (63)
= 1011 1010 (186)

Bitwise XOR, ^
RULE : If the bits in corresponding positions are different then the resultant bit is set.

For Example :-
1011 0010 (178)
^ 0011 1100 (63)
= 1000 1110 (142)

Shift Operators, << and >>


RULE : These move all bits in the operand left or right by a specified number of places.

Syntax : variable << number of places


variable >> number of places

For Example :-
2 << 2 = 8
i.e.
0000 0010 becomes 0000 1000

Note : shift left by one place multiplies by 2


shift right by one place divides by 2

Ones Complement
RULE : Reverses the state of each bit.

For Example :-

1101 0011 becomes 0010 1100


Note : With all of the above bitwise operators we must work with decimal, octal, or
hexadecimal values as binary is not supported directly in C.
The bitwise operators are most commonly used in system level programming where individual
bits of an integer will represent certain real life entities which are either on or off, one or zero.

Implicit & Explicit Type Conversions


Normally in mixed type expressions all operands are converted temporarily up to the type of
the largest operand in the expression.

Normally this automatic or implicit casting of operands follows the following guidelines in
ascending order.

long double
double
float
unsigned long
long
unsigned int
signed int
For Example :-

int i ;
float f1, f2 ;
f1 = f2 + i ;

Since f2 is a floating point variable the value contained in the integer variable is temporarily
converted or cast to a floating point variable also to standardise the addition operation in this
case. However it is important to realise that no permanent modification is made to the integer
variable.

Explicit casting coerces the expression to be of specific type and is carried out by means of
the cast operator which has the following syntax.

Syntax : ( type ) expression

For Example if we have an integer x, and we wish to use floating point division in the
expression x/2 we might do the following
( float ) x / 2

which causes x to be temporarily cast to a floating point value and then implicit casting causes
the whole operation to be floating point division.

The same results could be achieved by stating the operation as


x / 2.0

which essentially does the same thing but the former is more obvious and descriptive of what is
happening.

Note : It should be noted that all of these casting operations, both implicit and explicit, require
processor time. Therefore for optimum efficiency the number of conversions should be kept to a
minimum.

Sizeof Operator
The sizeof operator gives the amount of storage, in bytes, associated with a variable or a type
(including aggregate types as we will see later on).

The expression is either an identifier or a type-cast expression (a type specifier enclosed in


parentheses).

Syntax : sizeof ( expression )

For Example :-
int x , size ;
size = sizeof ( x ) ;
printf(“The integer x requires %d bytes on this machine”, size);

printf( “Doubles take up %d bytes on this machine”, sizeof ( double ) ) ;


Operator precedence and associativity in C language:

Operato
Description Associativity
r
() Parentheses (function call) (see Note 1) left-to-right
[] Brackets (array subscript)
. Member selection via object name
-> Member selection via pointer
++ -- Postfix increment/decrement (see Note 2)
++ -- Prefix increment/decrement right-to-left
+- Unary plus/minus
!~ Logical negation/bitwise complement
Cast (convert value to temporary value of
(type) type)
* Dereference
& Address (of operand)
Determine size in bytes on this
sizeof implementation
* / % Multiplication/division/modulus left-to-right
+ - Addition/subtraction left-to-right
<< >> Bitwise shift left, Bitwise shift right left-to-right
< <= Relational less than/less than or equal to left-to-right
Relational greater than/greater than or
> >= equal to
== != Relational is equal to/is not equal to left-to-right
& Bitwise AND left-to-right
^ Bitwise exclusive OR left-to-right
| Bitwise inclusive OR left-to-right
&& Logical AND left-to-right
|| Logical OR left-to-right
?: Ternary conditional right-to-left
= Assignment right-to-left
+= -= Addition/subtraction assignment
*= /= Multiplication/division assignment
%= &= Modulus/bitwise AND assignment
Bitwise exclusive/inclusive OR
^= |= assignment
<<= >>= Bitwise shift left/right assignment
, Comma (separate expressions) left-to-right
FUNCTIONS

Definition:- A block of statements that specifies one or more actions to be performed for a
large program. In C, a program is made up of one or more functions, one and only one of
which must be called main. The execution always starts with main.

Example:-
void main() void tax_calculation()
{ {
----------------- …………..
tax_calculation(); }
-------------
}

Components of Function:
Declaration / Prototype
Function Parameters (Actual & Formal)
Function Definition
return Statement
Function call

RECURSION:
A function calling itself is called recursive function. Every recursive function must satisfy two
properties

 Base Criteria
 Recursive step

Base criteria: There must be certain criteria in recursive function called base criteria in which
the function does not call itself. This criteria is required to exit from that function.

Recursive step: In this condition, each time function call itself but the arguments of the function
must be closer to initial condition.

Example:
int factorial (int n)
{
if (n==0)
Return 1;
else
return (n* factorial(n-1));
}

Rules for Recursion:


 Only user defined functions can be involved in recursion.
 It is necessary to mention proper terminating statement.
 During recursion, at each recursive call new memory is allocated for all local variables
of function with same name.
Advantages:
 Recursion is flexible in Data structures
 Length of program can be reduced.
Disadvantages:
 It requires extra storage. For each recursive call, memory is allocated for all the
variables and stored on stack.
 When there is no exit condition, program will go into infinite calls and reach out of
memory.
 It is not efficient in execution speed and time.

Activation Records:
An activation record is another name for Stack Frame. It's the data structure that composes a
call stack. It is generally composed of:
 Locals to the collie
 Return address to the caller
 Parameters of the collie

The Call Stack is thus composed of any number of activation records that get added to the stack
as new subroutines are added, and removed from the stack (usually) as they return.
Activation records keep track of values as a program executes. More specifically, an activation
record has a set of names that are bound to values. We link activation records together in two
ways:
 with a control link
 with an access link

A control link from record A points to the previous record on the stack. The chain of control
links traces the dynamic execution of the program.

An access link from record A points to the record of the closest enclosing block in the program.
The chain of access links traces the static structure (think: scopes) of the program.

STORAGE CLASSES:
auto (default) register static extern
Storage Main memory CPU registers Main memory Main memory
Initial value Garbage Garbage Zero Zero
Keyword auto register static extern
scope Local to block in Local to block Local to the Entire program
which it is defined in which it is block in which it
defined is defined
Life time Till the control Till the control Throughout the Throughout the
remains within the remains within execution of execution of
block in which it the block in program program
is defined which it is
defined

Global and local variables:


A local variable is a variable that is declared inside a function. A global variable is a variable
that is declared outside all functions and it is automatically initialized to zero. A local variable
can only be used in the function where it is declared. A global variable can be used in all
functions.
If a local variable is given same name as that of global variable then preference is given to local
variable.
void main() void f1()
{ {
f1(); int i = 1; /* Line1 */
f1(); printf(“%d : “,i++);
} }

The output of the above program:


1 1 (Note: Result is same even if Line1 is replaced by register int i=1;)
If Line1 is replaced by static int i=1; then the output of the program is
1 2

PARAMETER PASSING TECHNIQUES:

Call by value:
In call-by-value, the argument expression is evaluated, and the resulting value is bound to the
corresponding variable in the function (frequently by copying the value into a new memory
region). In this mechanism a function's argument is evaluated before being passed to the
function.

NOTE: In Pascal, a parameter is passed by value unless the corresponding formal has the
keyword var. Expression can be passed by value but not by reference in Pascal.
In C, parameters are passed by value. If variable is preceded by &, then it is pass by reference.
Expression can be passed by value but not by reference in C.

Example:
procedure swap(x, y: integer);
var
temp: integer;
begin
temp := x;
x:= y;
y := temp;
end;
Call by reference:
In call-by-reference evaluation (also referred to as pass-by-reference), a function receives an
implicit reference to a variable used as argument, rather than a copy of its value. This typically
means that the function can modify the variable used as argument.

Example:
procedure swap(var x, y: integer);
var temp: integer;
begin
temp := x;
x:= y;
y := temp;
end;

NOTE: FORTRAN supports only call by reference. If an expression is passed, then it is


evaluated and kept in temporary location. The address of this temporary location is passed to
the procedure and this location will be changed by the procedure.

Call by copy-restore:
Call-by-copy-restore, copy-in copy-out, call-by-value-result or call-by-value-return is a special
case of call-by-reference. The formal parameter acts as a local variable which is initialized to
the value of the actual parameter. Within the routine, changes to the formal parameter only
affect the local copy. On returning from the routine the final value of the formal parameter is
assigned to the actual parameter.
The semantics of call-by-copy-restore also differ from those of call-by-reference where two or
more function arguments alias one another; that is, point to the same variable in the caller's
environment. Under call-by-reference, writing to one will affect the other; call-by-copy-restore
avoids this by giving the function distinct copies, but leaves the result in the caller's
environment undefined depending on which of the aliased arguments is copied back first.
The result of call by reference and call by copy-restore also differs when there is an exception
during execution of the function. When the reference is passed to the collie uninitialized, this
evaluation strategy may be called call-by-result.

Example:
int y;
procedure calling_procedure
begin
y = 10;
copy_restore(y); //l-value of y is passed
print y; //prints 99
end
procedure copy_restore(x: integer)
begin
x = 99; // y still has value 10 (unaffected)
y = 0; // y is now 0
end
Call by name:
The arguments to a function are not evaluated before the function is called — rather, they are
substituted directly into the function body and then left to be evaluated whenever they appear in
the function. If an argument is not used in the function body, the argument is never evaluated; if
it is used several times, it is re-evaluated each time it appears. If the values of variables in the
expression are changed, the change will be seen immediately (similar to call by reference).
Algol used call by name parameter passing mechanism.

Example:
var i: integer
procedure sum(i,j: integer) : integer
var sm:integer
begin
sm := 0;
for i := 1 to 100 do
sm := sm + j;
sum := sm
end;
begin
print(sum(i, i*10 ))
end

In this procedure 1*10, 2*10,3*10,....100*10 are added to sm variable which is returned to


calling environment and printed.

Call by need:
Call-by-need is a memorized version of call-by-name where, if the function argument is
evaluated, that value is stored for subsequent uses. In a "pure" (effect-free) setting, this
produces the same results as call-by-name; when the function argument is used two or more
times, call-by-need is almost always faster.

STATIC & DYNAMIC SCOPE of VARIABLES:

Static Scope:
Most languages, including Algol, Ada, C, Pascal, Scheme, and Haskell, are statically scoped. A
block defines a new scope. Variables can be declared in that scope, and aren't visible from the
outside. However, variables outside the scope -- in enclosing scopes -- are visible unless they
are overridden. Static scoping is also sometimes called lexical scoping.

Example:
integer m, n;
procedure hardy;
begin
print("in hardy -- n = ", n);
end;

procedure laurel(n: integer);


begin
print("in laurel -- m = ", m);
print("in laurel -- n = ", n);
hardy;
end;

begin
m := 50;
n := 100;
print("in main program -- n = ", n);
laurel(1);
hardy;
end;
The output is:
in main program -- n = 100
in laurel -- m = 50
in laurel -- n = 1
in hardy -- n = 100
in hardy -- n = 100

Dynamic Scope:
Using this scoping rule, we first look for a local definition of a variable. If it isn't found, we
look up the calling stack for a definition. If dynamic scoping were used, the output would be:
in main program -- n = 100
in laurel -- m = 50
in laurel -- n = 1
in hardy -- n = 1
in hardy -- n = 100

You might also like