Anda di halaman 1dari 119

Eng.

Ahmed Assem

FORMAT OF A C PROGRAM
/* comment */
#include <Myfile.h>
<global variable declaration>
main()
{
<local variable declaration>
<C statements>

COMMENT

Starts with /* and ends with */


Programmers insert comments to document
programs and improve program readability.

Can be placed anywhere in the program.

Comments are ignored by the C compiler.

INCLUDE DIRECTIVE

Is the preprocessing
preprocessor.

directive

to

the

Lines beginning with # are processed by the


preprocessor before the program is compiled.
This tells the compiler what additional files are
needed before processing the actual program.
Contains the information needed by the program
to ensure correct operation of Cs standard
library functions.

INCLUDE DIRECTIVE

Example:
#include<stdio.h>

This specific line tells the preprocessor to include


the contents of the standard input/output header
file (stdio.h) in the program.

DATA TYPES

There are 4 basic data types in C language:


a) Character (char) used to hold whole number values
and ASCII characters.
b) Integer (int) used to hold whole number values
c) Floating Point (float) used to hold real numbers
d) Double Floating Point (double) - used to hold
numbers

real

Data Types :
Data Type

Size

Range

char

1 byte

-127 to 127

int

2 bytes

-32767 to 32767

float

4 bytes

-3.4E-32 to 3.4 E+38

double

8 bytes

-1.7E-308 to 1.7
E+308

Data Type Modifiers :


signed
By default all data types are declared as signed.
Signed means that the data type is capable of
storing negative values.
unsigned
To modify a data types behavior so that it can
only store positive values, we require to use the
data type unsigned.

Data Type Modifiers :


long
In order to store values beyond the storage
capacity of the basic data types, we use the data
type modifier long. This doubles the storage
capacity of the data type being used. E.g. long int
x will make the storage capacity of variable x to 4
bytes.
short
If long data type modifier doubles the size, short
on the other hand reduces the size of the data
type to half.

Data Type Modifiers :


Modifier

Data Type

Size

Range

signed

int

2 bytes

-32768 to 32767

unsigned

int

2 bytes

0 to 65536

long

int

4 bytes

-3.4E-32 to 3.4 E+38

short

int

2 bytes

-32768 to 32767

VARIABLES DEFINED

Variables are identifiers


changeable value.

that

can

store

Variables are important since they contain the


values needed for manipulation and evaluation of
data.

Variable names are stored in the computers


memory.

RULES FOR NAMING VARIABLES


1)

It must consist only of letters, digits and


underscore.

2)

It should not begin with a digit.

3)

An identifier defined in the C standard library


should not be redefined.

4)

It is case sensitive (uppercase is not equal to


lowercase letters).

5)

Do not include embedded blanks.

6)

Do not use any of the C language keywords as


identifiers/variables.

7)

Do not call your variable/identifier by the same


name as other functions.

KEYWORDS

Keywords are reserved words that have a special


meaning in a programming language.
auto
break
case
char
const
continue
default
do

double
else
enum
extern
float
for
goto
if

int
long
register
return
short
signed
sizeof
static

struct
switch
typedef
union
unsigned
void
volatile
while

VARIABLE DECLARATION

All variables must be declared before they may


be used.

Syntax:

type variable_list;
Where:
type
variable_list

is any valid data type


is 1 or more variable names
with comma separator

VARIABLE DECLARATION
Examples:
char name;
int x, y,z;
float number;

float n1, n2, sum;


double counter;

VARIABLE INITIALIZATION

Giving a value to a variable during the variables


declaration is called variable initialization.

Syntax:
type variable_name = value;
Example:
int count = 100;
float grade = 3.75;
char status = S;

Casting
You can force an expression to be of a specific
type by using a cast. The general form of a cast is
(type) expression
where type is a valid data type.
i.e.
int i;
for(i=l; i<=100; ++i)
printf(''%d / 2 is: %f\n", i, (float) i /2);

VARIABLE DECLARATION

This is the place where you declare the variables


that will be used in the program.

Types of variable declaration:


a) Global variable declaration
b) Local variable declaration

GLOBAL VS LOCAL VARIABLES

Global Variables
Variables that are declared outside a
function. They are known throughout the entire
program.
Local Variables
Variables that are declared inside a function.
They can only be referenced inside that function.
They are also called automatic variables.

GLOBAL VS LOCAL VARIABLES

Global Variables

#include <stdio.h>
int a,b,c, x,y,z;
main()
{
}

function()
{
}

Local Variables

#include <stdio.h>
main()
{
int a,b,c;
}
function()
{
int x,y,z;
}

MAIN()

Is a part of every C program.


The parenthesis after main indicate that main is
program building block called a function.
C programs contain one or more functions, one of
which must be main.

Every program in C begins executing at the


function main.

THE PRINTF() STATEMENT

This is used to display argument list on the monitor.

This an output function in Turbo C

Syntax 1:
printf (argument);
Examples:

printf (\t PI Technologies);


printf (Embedded Systems Diploma \n);
Note:
\n is an escape sequence for NEW LINE
\t is an escape sequence for TAB.

THE PRINTF() STATEMENT


Syntax 2:
printf (control string code, argument list);
Example:

a=100;
printf (%d, a);
printf (The value is %d, a);

The control string code contains the format command that


tells printf() how to display arguments and how many
arguments are on the list.

THE PRINTF() STATEMENT


Control String Code
%c
%d
%f

Data Type
character
integer
float/double

Notes:
1. Control string code and argument list should agree in type.
2. They should have a one-to-one correspondence.

THE PRINTF() STATEMENT


Example:
int x = 10;
int y = 25;
float z = 123.1234;
printf( x = %d and y = %d\n, x, y);
printf ( z = %f\n, z);
printf ( z = %.2f\n, z);

Output:
x = 10 and y = 25
z = 123.1234
z = 123.12

PUTCHAR Statement :
putchar(char mychar);
It is used to print a single character or the ASCII
code of a certain integer,

i.e.
putchar (A) ;
Output is A
putchar (65);
Output is A

THE SCANF STATEMENT

This is used to input a single character or sequence


of characters from the keyboard.

It needs the control string codes to be recognized.

Spaces are not accepted upon inputting.

Terminated by pressing spacebar.

This is an input function in C.

THE SCANF STATEMENT


Syntax:
scanf (format control string, &input list);
Examples:
int x,y;
float grade;
char letter;
scanf (%d, &x);
scanf (%f, &grade);
scanf (%c, &letter);
scanf (%d %d, &x, &y);

THE SCANF STATEMENT

The format control string indicates the type of data that should
be input by the user.
format control string

Data Type

%c
%d
%f
%lf

character
integer
float
double

The ampersand (&) is called the address operator in C. This is


placed before the variable name in a scanf() statement.
The address operator in C tells scanf() the location in memory in
which the variable will be stored. The computer then stores the
value of the variable at that location.

GETCHAR STATEMENT

getchar();
Last statement that will be placed before the
closing brace }
Used to input a single character from the
keyboard without echoing the character on the
monitor.
Causes delay in displaying the output once the
program is executed

THE ASSIGNMENT STATEMENT

This is used to assign a value to a variable.


This is used for computations needed in the
program.

Equal sign (=) is the assignment operator in


Turbo C.

Syntax:

variable_to_hold_value = expession;
Example:

sum = integer1 + integer2;

CS SHORTHAND

x = x + 5;

x+=5;

x = x - 7;

x-=7;

x = x * 12;

x*=12;

x = x / y;

x/=y;

SAMPLE C PROGRAM: ADDING 2 NUMBERS


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

/* Addition Program */
#include < stdio.h >
main( )
{
int integer1, integer2, sum;
printf ( Enter first integer : );
scanf ( %d, &integer1 );
printf ( Enter second integer: );
scanf ( %d, &integer2 );
sum = integer1 + integer2;
printf ( Sum is %d \n, sum );
system(PAUSE);
}

OPERATORS

Operator is a symbol that tells the compiler to


perform specific mathematical or logical
manipulations.

There are 3 classes of operators in C:


a) Arithmetic Operators
b) Relational & Logical Operators
c) Bitwise Operators

ARITHMETIC OPERATORS

Arithmetic operators are


arithmetic computations.
+
*
/
%
-++

used

to

perform

Addition
Subtraction
Multiplication
Division
Modulus Division (MOD)
Decrement
Increment

ARITHMETIC OPERATORS

When division (/) is applied to an integer, any remainder is


truncated.

% is only used on integer data type.

Any number preceded by - sign switches its sign.

The increment (++) operator adds one to its operand and


the decrement operator (--) subtracts one.

Both ++ and -- may either precede or follow the operand


(e.g. ++x or x++).

When an increment or decrement operator precedes it


operand, C performs the increment or decrement operation
prior to using the operands value. If it follows its operands,
C uses the operands value before incrementing or
decrementing it.

RELATIONAL & LOGICAL OPERATORS

Relational operators show the relationship values


have with one another.
Logical operators show the ways these
relationships can be connected together using
rules of formal logic.

The key to the concepts of true relationship


between relational and logical operators is the
idea of TRUE and FALSE. In turbo C, TRUE is
any value other than zero (0). FALSE is zero (0).

RELATIONAL & LOGICAL OPERATORS


A. Relational Operators
> greater than
>= greater than or equal
< less than
<= less than or equal
= = equal
!= not equal

B. Logical Operators
!
Not
&&
And
||
Or

RELATIONAL & LOGICAL OPERATORS


Truth Table
P Q

P && Q

P || Q

!P

0 0

0 1

1 1

1 0

BITWISE OPERATORS

Bitwise Operators are the testing, setting or


shifting of the actual bits in a byte or word, which
corresponds to Cs character and integer data
types and variants.
Bitwise operators cannot be used on type float,
double, long double, void or other complex types.

BITWISE OPERATORS

&
|
^
~
>>
<<

And
Or
Exclusive Or (XOR)
Ones Complement
Shift Right
Shift Left

BITWISE OPERATORS
1) & (and). Any bit of the operand is 0, the outcome is set to 0.
2) | (or). Any bit on the operand is 1, the outcome is 1
3) ^ (XOR). If exactly one of the operator is 1, the outcome is
one.
4) ~ (Ones complement). Reverse the state of each bit in the
specified variable. That is, all 1s are set to 0, and all 0s are
set to 1.
5) >> (Shift Right). Move all bits in a variable to the right.
6) << (Shift Left). Move all bits in a variable to the left.

BITWISE OPERATORS
1) & (and). Any of the operand is 0, the outcome is set to 0.
E.G 0101 & 0011 = 0001
2) | (or). Any bit on the operand is 1, the outcome is 1
E.G 0101 | 0011 = 0111
3) ^ (XOR). If exactly one of the operator is 1, the outcome is
one.
E.G 0101 & 0011 = 0110
4) ~ (Ones complement). Reverse the state of each bit in the
specified variable. That is, all 1s are set to 0, and all 0s are
set to 1.
E.G ~ 0011 = 1100
5) >> n (Shift Right). Move all bits in a variable n bits to the
right.
E.G ( 10011001 >> 2) = (00100110)
6) << n (Shift Left). Move all bits in a variable n bits to the left.
E.G (00100110 << 2) = (10011000)
Note : shift right means division of the variable by 2^n

The ? : Operator
Exp1 ? Exp2: Exp3;
It is the same as

if (Exp1)
Exp2;
else
Exp3;
i.e.
x = 10;
y = x>9 ? 100 : 200;
Then y will take the value 100

Flow of Control

Operator
Precedence

Meaning

>

greater than

>=
<

<=

greater than OR equal


less than

less than OR equal

2
2
2

==

equal

!=

not equal

Conditional if statements
if (condition1)
{
stmt 1;

//Executes if Condition1 is true

else if (condition2)
{
stmt 2;

//Executes if Condition2 is true

else
{
stmt 3;
false
}

//Executes if both conditions are

For loops

The syntax of for loop is


for (initialisation; condition checking ; Increment)
{
set of statements
}
Eg: Program to print Hello 10 times
for(I=0;I<10;I++)
{
printf(Hello);
}

While loop

The syntax for while loop

while(condition)
{
statements;
}
Eg:
a=10;
while(a != 0)
{
printf(%d,a);
a--;
}

Output: 10 9 8 7 6 5 4 3 2 1

Do While loop

The syntax of do while loop

do
{
set of statements
}while(condition);
Eg:
i=10;
do
{
printf(%d,i);
i--;
}while(i!=0)

Output:
10 9 8 7 6 5 4 3 2 1

Switch Case
switch(var)
{
case 1: //if var=1 this case executes
stmt;
break;
case 2: //if var=2 this case executes
stmt;
break;
default: //if var is something else this will execute
stmt;
}

Break and Continue statements

The break statement has two uses:


You can use it to terminate a case in the switch
statement .
You can also use it to force immediate termination of a
loop, bypassing the normal loop conditional test.

i.e.
int main (void)

{
int t;
for(t=0; t < 100; t++)
{
printf(''%d ", t);
if(t == 10) break;
}

return( 0 );
}

Break and Continue statements


The continue statement works somewhat like
the break statement. Instead of forcing
termination, however, continue forces the next
iteration of the loop to take place, skipping any
code in between.
For the for loop, continue causes the increment
and then the conditional test portions of the loop
to execute.
For the while and do-while loops, program
control passes to the conditional tests.

Break and Continue statements


void main (void)
{
char done, ch;
done = 0;
while(!done) {
ch = getchar();
if(ch == '$') {
done = 1;
continue;
}
putchar(ch+1); /* shift the alphabet one position higher */
}
}

EXPRESSIONS

Is any valid combination of operators, constants


and variables that evaluates to a value.
Operators Precedence
()
!, unary +, unary
*, /, %
Binary +, binary
<, <=, >, >=
==, !=
&&
||

Highest

Lowest

Functions
Functions are the building blocks of C
The general form of a function is

ret-type function-name(parameter list)


{
body of the function
}

The ret-type specifies the type of data that the


function returns.
The parameter list is a comma-separated list of
variable names and their associated types.

Functions
A function can be without parameters, in which
case the parameter list is empty.
An empty parameter list can be explicitly
specified as such by placing the keyword void
inside the parentheses.
Example :

f(int i, int k, int j) /* correct */


f(k, float j) /* wrong, k must have its own type
specifier */
f(void) /* function with no parameters */

The return statement has two important uses:

First, it causes an immediate exit from the function.


Second, it can be used to return a value.

Functions
#include <stdio.h>
int sqr(int x); /* prototype */
int main(void)
{
int t=10;
printf("%d %d", sqr(t), t);
return 0;

}
int sqr(int x)
{
x = x*x;
return(x);

Arrays
An array is a collection of variables of the same
type that are referred to through a common
name.
A specific element in an array is accessed by an
index.

Single-Dimension Arrays
The general form for declaring a singledimension array is
type var_name[size];
double balance[100];
An element is accessed by indexing the array
name. This is done by placing the index of the
element within square brackets after the name of
the array. For example,
balance[3] = 12.23;
The highest index here is 99 and the lowest is 0

Single-Dimension Arrays
#include <stdio.h>
int main(void)
{
int x[100]; /* this declares a 100-integer array */
int t;
/* load x with values 0 through 99 */
for(t=0; t<100; x[t] = t , t++);
/* display contents of x */
for(t=0; t<100; ++t) printf(''%d ", x[t]);
return 0;

Single-Dimension Arrays

The amount of storage required to hold an array


is directly related to its type and size. For a
single dimension array, the total size in bytes is
computed as shown here:
total bytes = sizeof(base type) length of array

C has no bounds checking on arrays.


Array can be initialized as follows :
int x [5] = {12,100,50,9,250};

Strings
The most common use for the one-dimensional
array is as a character string.
In C, a string is a null-terminated character
array
i.e.
char str [11] ={A,H,M,E,D,A,S,S,E,M,\0};
Or
Char str[11] = AHMEDASSEM

Strings
gets(); reads a string from the user
puts(str) ; writes a string on the screen
strcpy(s1, s2) Copies s2 into s1
strcat(s1, s2) Concatenates s2 onto the end of s1
strlen(s1) Returns the length of s1
strcmp(s1,s2)
Returns 0 if s1 and s2 are the same; less than 0 if
s1<s2; greater than 0 if s1>s2
strchr(s1, ch) Returns a pointer to the first
occurrence of ch in s1
strstr(s1, s2) Returns a pointer to the first
occurrence of s2 in s1

Two-Dimensional Arrays
A two -dimensional array is, essentially, an array
of one-dimensional arrays
It is declared as follows :

int num [t][i];

Two-Dimensional Arrays

2D array can be initialized as follows :


month_days[2][12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,
30, 31, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int month_days[2][12] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30,
31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };
int month_days[4][4] = { { 31, 28, 31, 30},{ 31, 30, 31, 31},{
30, 31, 30, 31 }, { 31, 29, 31, 30} };

Structures
A structure is a collection of variables referenced
under one name, providing a convenient means of
keeping related information together
It is declared as follows :

struct addr
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;

};

Structures

To declare a variable (that is, a physical object) of


type addr, write :

struct addr addr_info;

You can also declare one or more objects when


you declare a structure. For example,

struct addr {
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;

} addr_info, binfo, cinfo;

Accessing Structure Members


Individual members of a structure are accessed
through the use of the . operator (usually called
the dot operator).
Example :

addr_info.zip = 12345;
gets(addr_info.name)

Structure Assignments

The information contained in one structure can


be assigned to another structure of the same type
using a single assignment statement.
int main(void)
{
struct {
int a;
int b;
} x, y;
x.a = 10;
y = x; /* assign one structure to another */
printf("%d", y.a);
return 0;
}

Arrays of Structures
To declare an array of structures, you must first
define a structure and then declare an array
variable of that type.
Example :

struct addr addr_list[100];

To access a specific structure, index the array


name.
For example, to print the ZIP code of structure 3,
write

printf("%lu", addr_list[2].zip);

Unions
A union is a memory location that is shared by
two or more different types of variables.
Declaring a union is similar to declaring a
structure. Its general form is

union tag {
type member-name;
type member-name;
type member-name;
} union-variables;
Example :
union u_type {
int i;
char ch;
};

Bit-Fields

A bit-field, allows you to access a single bit. Bitfields can be useful for a number of reasons, such
as:
If storage is limited, you can store several Boolean
(true/false) variables in one byte.
Certain devices transmit status information encoded
into one or more bits within a byte.
Certain encryption routines need to access the bits
within a byte.

A bit-field must be a member of a structure or


union. It defines how long, in bits, the field is to
be.
The general form of a bit-field definition is

type name: length;

Bit-Fields

You can represent the information in a status


byte using the following bit-field:
struct status_type {
unsigned delta_cts: 1;
unsigned delta_dsr: 1;
unsigned tr_edge: 1;
unsigned delta_rec: 1;
unsigned cts: 1;
unsigned dsr: 1;
unsigned ring: 1;
unsigned rec_line: 1;
} status;

Enumerations
An enumeration is a set of named integer
constants.
Enumerations are common in everyday life. For
example, an enumeration of the coins used in the
United States is

penny, nickel, dime, quarter, half-dollar, dollar

Enumerations are defined much like structures;


the keyword enum signals the start of an
enumeration type.
The general form for enumerations is

enum tag { enumeration list } variable_list;

Enumerations
Example
enum coin { penny, nickel, dime, quarter=100,
half_dollar, dollar} money ;

char name[][12]={
"penny",
"nickel",
"dime",
"quarter",
"half_dollar",
"dollar"
};
printf("%s", name[money]);

Enumerations

Example
switch(money) {
case penny: printf("penny");
break;
case nickel: printf("nickel");
break;
case dime: printf("dime");
break;
case quarter: printf("quarter");
break;
case half_dollar: printf(''half_dollar");
break;
case dollar: printf("dollar");
}

Pointers

Pointers are variables that contain memory


addresses as their values.
A variable name directly references a value.

A pointer indirectly references a value.


Referencing a value through a pointer is called
indirection.
A pointer variable must be declared before it can
be used.

Concept of Address and Pointers


Memory can be
conceptualized as a
linear set of data
locations.
Variables reference the
contents of a locations
Pointers have a value of
the address of a given
location

ADDR1
ADDR2
ADDR3
ADDR4
ADDR5
ADDR6

Contents1

*
*
*
ADDR11

Contents11

*
*
ADDR16

Contents16

Pointers

Examples of pointer declarations:


int *a;
float *b;
char *c;
The asterisk, when used as above in the
declaration, tells the compiler that the variable is
to be a pointer, and the type of data that the
pointer points to, but NOT the name of the variable
pointed to.

Pointer Operations in C

Creation
& variable

Dereference
* pointer

Returns contents stored at address

Indirect assignment
* pointer = val

Returns variables memory address

Stores value at address

Assignment
pointer = ptr

Stores pointer in another variable

Using Pointers
int i1;
int i2;
int *ptr1;
int *ptr2;

0x1014

0x1010

ptr2:

i1 = 1;
i2 = 2;

0x100C

0x1008

ptr1:

ptr1 = &i1;
ptr2 = ptr1;

0x1004

i2:

2
3

0x1000

i1:

3
1

*ptr1 = 3;
i2 = *ptr2;

0x1000

0x1000

Arithmetic and Logical Operations


on Pointers

A pointer may be incremented or decremented


An integer may be added to or subtracted from a
pointer.
Pointer variables may be subtracted from one
another.
Pointer variables can be used in comparisons, but
usually only in a comparison to NULL.

Pointer Arithmetic
pointer + number

pointer number

E.g., pointer + 1

adds 1 something to a pointer

char
char
char

*p;
a;
b;

p = &a;
p += 1;

int
int
int

In each, p now points to b


(Assuming compiler doesnt
reorder variables in memory)

Adds 1*sizeof(char) to
the memory address

*p;
a;
b;

p = &a;
p += 1;

Adds 1*sizeof(int) to
the memory address

Pointer arithmetic should be used cautiously

The Simplest Pointer in C

Special constant pointer NULL


Points to no data
Dereferencing illegal causes segmentation fault

To define, include <stdlib.h> or <stdio.h>

Generic Pointers

void *: a pointer to anything


type cast: tells the compiler to
void
*p;
int
i;
char
c;
p = (void *)&i;
p = (void *)&c;

change an objects type (for type


checking purposes does not modify
the object in any way)
Dangerous! Sometimes necessary

Lose all information about what type of thing is


pointed to
Reduces effectiveness of type-checking
Cant use pointer arithmetic

Useful in limited circumstances

Pass-by-Reference
void
set_x_and_y(int *x,
int *y)
{
*x = 1001;
*y = 1002;
}
void
f(void)
{
int a = 1;
int b = 2;
set_x_and_y(&a,&b);
}

1001
1

1002
2

x
y

Pass-by-Reference
#include <stdio.h>
void swap ( int *a, int *b ) ;
int main ( )
{
int a = 5, b = 6;
printf("a=%d b=%d\n",a,b) ;
swap (&a, &b) ;
printf("a=%d b=%d\n",a,b) ;
return 0 ;
}

void swap( int *a, int *b )


{
int temp;
temp= *a; *a= *b; *b = temp
;
printf ("a=%d b=%d\n", *a,
*b);
}
Results:
a=5 b=6
a=6 b=5
a=6 b=5

Arrays and Pointers

Dirty secret:
Array pointer to the initial (0th)
array element

a[i]

*(a+i)

An array is passed to a function as a


pointer

The array size is lost!

Usually bad style to interchange


arrays and pointers

Avoid pointer arithmetic!

Passing arrays:
Really int *array

Must explicitly
pass the size

int
foo(int array[],
unsigned int size)
{
array[size - 1]
}
int
main(void)
{
int a[10], b[5];
foo(a, 10) foo(b, 5)
}

Arrays and Pointers


int
foo(int array[],
unsigned int size)
{

printf(%d\n, sizeof(array));
}
int
main(void)
{
int a[10], b[5];
foo(a, 10) foo(b, 5)
printf(%d\n, sizeof(a));
}

What does this print?

... because array is really


a pointer

What does this print?

40

Arrays and Pointers

int
int

i;
array[10];

for (i = 0; i < 10; i++)


{
array[i] = ;
}

int *p;
int array[10];
for (p = array; p < &array[10]; p++)
{
*p = ;
}

Data Structure

What is a stack?

A stack is a data structure


that keeps objects in LastIn-First-Out (LIFO) order
Objects are added to the
top of the stack
Only the top of the stack
can be accessed

Visualize this like a stack


of paper (or plates)
Example: track characters
entered on a command line
What methods does a stack
need?

AHMED1
Top

1
D
E
M

H
A

What methods are needed for a stack?


Create a stack
Determine whether a stack is empty (or how
many items are on it)
Add an object to the top of the stack (push)
Remove an object from the top of the stack (pop)

Remove all of the objects from the stack

Does this return the object removed?

Can be done by repeatedly calling pop until the stack


is empty

Retrieve the object from the top of the stack


(peek)

STACK (Last in First Out [LIFO])


int isFull(void);
int isEmpty(void);
void Push(data);
int Pop(void);

Pop side
Push side

Stack (Last in First Out [LIFO])


PUSH to stack

Data Link

NULL

Head

Data Link

NULL

Head
Data Link

Head
Data Link

NULL

Data Link

Data Link

Stack (Last in First Out [LIFO])


POP from stack
NULL

Head

Data Link

Data Link

Data Link

NULL

Head

Head
Data Link

NULL

Data Link

Data Link

Stack applications

Matching braces and parentheses


Goal: make sure left and right braces and
parentheses match
This cant be solved with simple counting
{ (x) } is OK, but { (x} ) isnt

Rule: { ok string } is OK
Rule: ( ok string ) is OK
Use a stack
Place left braces and parentheses on stack
When a right brace / paren is read, pop the
left off stack
If none there, report an error (no match)

Stack applications

Reversing Data: We can use stacks to reverse data.


(example: files, strings)
Very useful for finding palindromes.

Consider the following pseudocode:


1)
2)

3)

read (data)
loop (data not EOF and stack not full)
1) push (data)
2) read (data)
Loop (while stack notEmpty)
1) pop (data)
2) print (data)

Queue (First in First Out [FIFO])


int isFull(void);
int isEmpty(void);
void Add(data);
int Extract(void);

Addition side

Extraction Side

Queue (First in First Out [FIFO])


Add Queue
Head

Data Link

Head
Data Link

ptr
Data Link

Data Link

Head
Data Link

ptr
Data Link

Data Link

Data Link

NULL

Data Link

ptr

NULL

Head

NULL

Data Link

NULL

Queue (First in First Out [FIFO])


Extract Queue

Data Link

Head
Data Link

Data Link
ptr

Data Link
Head
Data Link

Data Link

NULL

Data Link

ptr
Data Link

NULL

Data Link

NULL

ptr

Head

Head

Data Link

NULL

Assignment
1)

Implement Stack or Queue with Linked Lists.

* Trace the program below of Queue linked list


* Transform the program below from Queue to stack form of
linked list.

Preprocessor
Directives

Macro definitions
#define
To define preprocessor macros we can use #define.
Its format is:
#define identifier replacement
#undef
This commands undefined a macro. A macro must
be undefined before being redefined to a different
value

Conditional inclusions
#ifdef
Allows a section of a program to be compiled only if the macro
that is specified as the parameter has been defined, no matter
which its value is
#endif
End the if section
#ifndef
Serves for the exact opposite: the code between #ifndef and
#endif directives is only compiled if the specified identifier has
not been previously defined.
#if, #else and #elif
Serve to specify some condition to be met in order for the
portion of code they surround to be compiled. The condition
that follows #if or #elif can only evaluate constant expressions,
including macro expressions

Other directives
Error directive (#error)
This directive aborts the compilation process when it is found,
generating a compilation the error that can be specified as its
parameter:
Source file inclusion (#include)
This directive includes a file into code.
It has two possible forms:
#include <file> or #include ``file''
<file> tells the compiler to look where system include files are
held.
``file'' looks for a file in the current directory (where program
was run from)
Included files usually contain C prototypes and declarations
from header files and not (algorithmic) C code #ifndef
Serves for the exact opposite: the code between #ifndef and #endif
directives is only compiled if the specified identifier has not been
previously defined.

Other directives
Pragma directive (#pragma)
This directive is used to specify diverse options to the compiler. These options
are specific for the platform and the compiler you use. Consult the manual or
the reference of your compiler for more information on the possible
parameters that you can define with #pragma.

Predefined macro names


__LINE__Integer
Value representing the current line in the source code file being compiled.
__FILE__A
String literal containing the presumed name of the source file being compiled.
__DATE__A
String literal in the form "Mmm dd yyyy" containing the date in which the
compilation process began.
__TIME__A
String literal in the form "hh:mm:ss" containing the time at which the
compilation process began.
__cplusplus
An integer value. All C++ compilers have this constant defined to some value.
If the compiler is fully compliant with the C++ standard its value is equal or
greater than 199711L depending on the version of the standard they comply.

Some Embedded
Systems Concepts

Synchronous vs. Asynchronous


Functions
Synchronous

functions:
will return control to caller only after
finishing its task

Asynchronous functions:
will just start its task and return control to
caller, while
its task is continue in the
background

Reentrant vs. Non-reentrant


Functions
Reentrant function allow multiple concurrent invocations
from different context that do not interfere with each other.
For function to be reentrant:
Doesnt call non-reentrant functions
Ensure mutual exclusion of shared hardware and
software resources
The following functions must be reentrant:
Functions shared between different tasks in a
multitasking system.
Functions shared between ISR and background task.
Function shared between different ISRs with different
priorities, when nesting is enabled.

Recursive Functions
Recursive function is function that call itself.

Recursion is not recommended in embedded software:


High stack consumption, because each call requires
allocation of a new
copy of local variables.
The execution time needed for the allocation and deallocation, and for
the storage of those parameters and local
variables can be costly.
The recursive code is hard to test and hard to read.
Precautions need to be taken to ensure that the recursive
routine will
terminate, otherwise the run-time stack will overflow.

Inline vs. Macro Functions


Inline function is defined by using the keyword inline.
The complier replaces function call by the function code,
as the same as macro.
Macros are supported by all compilers, while inline is not
supported by all compilers.
Inline function performs type checking, while macro
performs no type checking.
Inline function could be traced, while macro function
cant be traced.
Some compilers disable inline feature when the function
is large or called frequently.

Bit Manipulation Using Bit


Masks
Set bit to 1
REG = REG | BIT_MASK
Clear bit to 0
REG = REG & (~BIT_MASK)
Toggle bit
REG = REG ^ BIT_MASK
Check if bit is set to 1
if((REG | BIT_MASK) != 0x00) {//Do}
Check if bit is cleared to 0
if((REG | BIT_MASK) == 0x00) {//Do}
Write group of bits
Var = (REG & (~BIT_GROUP_MASK))| (Value << START_BIT_POS)
Read group of bits
Var = (REG & BIT_GROUP_MASK) >> START_BIT_POS

Bit Manipulation Using BitFields


Set bit to 1
BitField. Bitx = 1
Clear bit to 0
BitField. Bitx = 0
Toggle bit
BitField. Bitx = ~ BitField.bitx
Check if bit is set to 1
if (BitField. Bitx==1) {//Do}
Check if bit is cleared to 0
if (BitField. Bitx==0) {//Do}
Write group of bits
BitField.BitGroupx = Value
Read group of bits
Var = BitField.BitGroupx

Software Timeout
Timeout mechanism is used to release the CPU while waiting for an
event when this event does not triggered within the specified timeout
period.
To implement Timeout:
Timeout period is determined from the nature of the event
Timeout can be implemented by hardware timer or by software
depending on available resources and needed accuracy
Actions to be performed when timeout expired

Critical Section
A critical section of code, also called a critical region, is code
that once starts executing, it must not be interrupted.
To ensure this, interrupts are typically disabled before the
critical code is executed and enabled when the critical code is
finished.

Byte Ordering
Big-endian:
Store most significant byte in low address and least significant byte in
high address (Freescale)

Little-endian:
Store least significant byte in low address and most significant
byte in high address (Intel)
Bi-endian:
Can be configured to efficiently handle both big and little endian
(PowerPC).

Byte Ordering

References :

McGraw-Hill - C - The Complete Reference, 4th


Ed (H.Schildt)(2000)

Anda mungkin juga menyukai