Embedded C Programming in a Nutshell
Embedded C Programming in a Nutshell
Embedded C
Data Types
Operators
Expressions
7 Arrays
8 Functions
Refresher on C
: LED
: Resistor
: Ground
: Power (Vcc/Vdd)
: Transistor
: 7 Segment Display
: Button/Switch
Memory Layout
Command Line
Arguments
• Memory representation of a typical C
Stack
program will have the following
Hole
sections:
Heap
• Code Segment
• Data Segment (Initialized/Uninitialized)
Data Segment • Dynamic Heap
• Stack
Text Segment
Program
Sections
Code Segment (Text Segment)
• Contain simple text part of the code containing
the executable instruction
Command Line
Arguments
Stack
• ‘Read-only’ memory, to avoid the instruction
Hole
modification
• Generally, below heaps and stack, so that
Heap overflow will not have any overwrite on the
code segment
Data Segment
Text Segment
Program
Sections
Initialized Data Segment
• Initialized global variables will be stored in this memory location
• This segment can be further classified into read-only section and read-write area
• Example: char s[ ] = “Hello World” Command Line Command Line
Arguments Arguments
• Character literal will be stored in initialized read-only area Stack Stack
• Character pointer variable in the initialized read-write data Hole
Hole
• Global variables and static variables are stored in this segment Text Segment Text Segment
Program Program
Sections Sections
Stack
• A typical stack frame will contain
• Memory space for arguments
Command Line
Arguments • Space for local variables
Stack
• Return location
Hole
• Stack is usually managed by compiler, One
Heap
stack frame is created at each function call
• Usually, a stack frame is destroyed during
Data Segment
every function exit
Text Segment • Will have dedicated register to keep track
Program
of push and pop
Sections
• May contain one or more stack frames
based on the application, n number of
functions create n number stack frames
• Stack ‘Issues’
Heap
• Variables that are required for a long-term
storage and that requires to persist across
Command Line
Arguments multiple function calls are stored in ‘Heap
Stack
Memory’
Hole
• All dynamically allocated memory (i.e
Heap
memory allocated in runtime) are
allocated in the ‘Heap’ memory
Data Segment
• Programmer has to explicitly deallocate
Text Segment
the allocated memory
Program
Sections
GCC Command
• size <name.exe>
• Display the different memory segment with size
Storage Class
Local auto Block Between function / block entry and exit Stack No
Example Code 1
#include <stdio.h>
int inc(int n) {
int res;
Stac
k
res = n + 1; n=0 Stack
return addr to caller Frame
return res; of main()
res = ?
} Stack
return addr to main Frame
n=0 of inc()
int main() {
int n = 0;
printf(“%d\n”, inc(n));
return 0;
}
Storage - Automatic
Class
Example Code 1
#include <stdio.h>
int inc(int n) {
int res;
Stac
k
res = n + 1; n=0 Stack
return addr to caller Frame
return res; of main()
res = 1
} Stack
return addr to main Frame
n=0 of inc()
int main() {
int n = 0;
printf(“%d\n”, inc(n));
return 0;
}
int main()
{
int i = 0; Stac
// int i = 0; // One Definition Rule k
i=0
I = 10 Stack
{ Frame
j=0
int i = 10; of main()
return addr to caller
int j = 0;
return 0;
}
#include <stdio.h>
int main()
{
register int i = 0;
// int *p = &i;
// scanf(“%d”, &i);
printf(“i is %d\n”, i);
return 0;
}
int main()
{
register int i = 0; Stack
// int *p = &i; Stack
return addr to caller Frame
// scanf(“%d”, &i); of main()
printf(“i is %d\n”, i);
return 0;
} CPU CPU
Register
i=0
Local register Block Between function / block entry and exit Register / Stack No
int event_tracker(void) {
int event_cnt = 0;
return ++event_cnt;
}
int main() {
while (1) {
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
return ++event_cnt;
}
int main() {
while (1) {
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 0 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // 1st Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 1 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // 1st Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 0 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // 2nd Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 1 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // 2nd Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 0 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // nth Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
int event_cnt = 0; Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
event_count = 1 Stack Frame
return ++event_cnt; of
return addr to main
} event_tracker()
int main() {
while (1) { // nth Iteration
printf(“%d\n”, event_tracker());
sleep(1);
}
return 0;
}
int event_tracker(void) {
static int event_cnt = 0;
// Compile
time
// Some operation to be done
return ++event_cnt;
}
int main() {
while (1) { Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 0
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
return ++event_cnt;
}
int main() {
while (1) { Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 0
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // 1st Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 0
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // 1st Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 1
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stac
k Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // 2nd Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 1
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stac
k Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // 2nd Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 2
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stac
k Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // nth Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = 2
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int event_tracker(void) {
static int event_cnt = 0; // Compile time Stack
Stack
// Some operation to be done return addr to caller Frame
of main()
Stack Frame
return addr to main of
return ++event_cnt;
event_tracker()
}
int main() {
while (1) { // nth Iteration Data Segment
(.bss)
printf(“%d\n”, event_tracker()); event_count = n
sleep(1); Part of .o file, will be
} allocated
while the program loaded
return 0;
}
int updated_count(void) {
int current_val;
// Get the event val for other function
return current_val;
}
int event_tracker(void) {
static int event_cnt = updated_count();
// Some operation to be done
return ++event_cnt;
}
int main() {
// Some logic similar to previous example
return 0;
}
int event_tracker(void) {
static int event_cnt = updated_count();
// Some operation to be done
return ++event_cnt;
}
int main() {
// Some logic similar to previous example
return 0;
}
int updated_count(void) {
int current_val;
// Get the event val for other function
return current_val;
}
int event_tracker(void) {
static int event_cnt;
event_cnt = updated_count();
// Some operation to be done
return ++event_cnt;
}
int main() {
// Some logic similar to previous example
return 0;
}
Local register Block Between function / block entry and exit Register / Stack No
Global extern Program Between program entry and exit Data Segment Internal / External
Storage
Class
Sample Code
#include <stdio.h>
void timer_isr(void) {
int overflow_cnt;
if (overflow_cnt == 1000)
secs++;
overflow_cnt++;
}
int main() {
if (secs == 60)
// Required Operation to be done
return 0;
}
Storage - Problem
Class
Sample Code
#include <stdio.h>
void timer_isr(void) {
Note: ISR Function neither
int overflow_cnt;
accepts nor return any thing.
<ex>
if (overflow_cnt == 1000)
secs++; “secs” - variable
overflow_cnt++;
}
int main() {
if (secs == 60)
// Required Operation to be done
return 0;
}
Storage - Global - Solution
Class
Sample Code
#include <stdio.h>
int secs;
void timer_isr(void) {
int overflow_cnt;
if (overflow_cnt == 1000)
secs++;
overflow_cnt++;
}
int main() {
if (secs == 60)
// Required Operation to be done
return 0;
}
Storage - Global
Class
Example Code 8
#include <stdio.h>
int x;
void foo(void) {
x++;
}
int main() {
foo();
printf(“%d\n”, x);
return 0;
}
Storage - Global - Multifile
Class
Example Code 9 – main.c bar.c
#include <stdio.h> #include <stdio.h>
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); 1
printf(“%d\n”, x); 2
return 0;
}
Storage - Global - Multifile
Class
Example Code 10 – main.c bar.c
#include <stdio.h> #include <stdio.h>
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); 11
printf(“%d\n”, x); 12
return 0;
}
Storage - Global - Multifile
Class
Example Code 11 – main.c bar.c
#include <stdio.h> #include <stdio.h>
void foo(void) {
x++; void bar(void) {
} x++;
}
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); Error: 2 Defined Same
printf(“%d\n”, x); Global Variable cannot be
placed in same memory
return 0;
}
Storage - Global - Multifile
Class
Example Code 12 – main.c bar.c
#include <stdio.h> #include <stdio.h>
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); 11
printf(“%d\n”, x); 12
return 0;
}
Storage - Memory Layout
Class
Local register Block Between function / block entry and exit Register / Stack No
extern Program Between program entry and exit Data Segment Internal / External
Global
static File Between program entry and exit Data Segment Internal
Storage - Global - Multifile - Problem
Class
Example Code 13 – main.c bar.c
#include <stdio.h> #include <stdio.h>
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); Error: In main.c int x
printf(“%d\n”, x); becomes file scope, so
extern int x cannot be
return 0; linked
}
Storage - Global - Multifile - Problem
Class
Example Code 14 – main.c bar.c
#include <stdio.h> #include <stdio.h>
int main() {
foo();
printf(“%d\n”, x);
Output:
bar(); Error: In bar.c Function
printf(“%d\n”, x); bar() is a file scope so
cannot be linked with
return 0; main.c
}
Storage - Global
Class
Example Code 15
#include <stdio.h>
int i = 10;
void foo(void) {
extern int i;
printf(“%d\n”, i);
}
int main() {
int i; Output:
10
foo(); 0
printf(“%d\n”, i); Extern int i is linked with
global variable I bcoz
return 0; “extern” says go outside
} of my scope and find the
definition
Storage - Global
Class
Example Code 16
#include <stdio.h>
void foo(void) {
extern int i;
printf(“%d\n”, i);
}
int main() {
int i; Output:
Error: initially I is defined
foo(); as extern but later is
printf(“%d\n”, i); limited as file scope
which throws error
return 0;
}
Storage - Global
Class
Example Code 16
#include <stdio.h>
static int i = 10; // allowed!!
void foo(void) {
extern int i;
printf(“%d\n”, i);
}
int main() {
int i; Output:
10
foo(); 0
printf(“%d\n”, i);
return 0;
}
Thank You !
Applied C – Operators
Bitwise
Operators - Bitwise
While working Low Level System Programming or Embedded System
Programming we may have to deal with accessing bit of Registers /
Variable
So in any case if you want deal with bits of data, C provides us Bitwise
Operators
They performs operations on bits
All the operands will be treated as Integers
The result of the evaluation will be Integers
Operators - Bitwise
6 operators
& - AND
Can be used to get bit(s) from the operand
Can be used to clear bit(s) of the operand
| - OR
Used to set bit(s) of the operand
^ - XOR
Used to toggle bit(s) of the operand
~ - Compliment
Used to invert bits of the operand
Operators - Bitwise
6 operators
<< - Left Shift
Shift bits towards left side of the operand
>> - Right Shift
Shift bits towards right side of the operand
Operators – Bitwise
• 6 Operators
• Binary Operator (&, |, ^, << and >>)
• Need 2 Operators
• Unary Operator (~)
• Need Single Operand
• Works just like Logic Gates
Operators - Bitwise
A 0 0 1 1 A 0 0 1 1 A 0 0 1 1 A 0 0 1 1
B 0 1 0 1 B 0 1 0 1 B 0 1 0 1
O 0 0 0 1 O 0 1 1 1 O 0 1 1 0 O 1 1 0 0
Operators - Bitwise
Left Right
Shift Shift
Ideal Sign Bit
Case Fill
A 1 0 0 1 A 1 0 0 1 A 1 0 0 1 A 0 1 0 1
1 0 0 1 << 1 0 0 1 >> 1 0 0 1 >> 0 1 0 1 >>
0 0 0 0
0 0 1 0 << 0 1 0 0 >> 1 1 0 0 >> 0 0 1 0 >>
1 1 1 1
0 1 0 0 << 0 0 1 0 >> 1 1 1 0 >> 0 0 0 1 >>
2 2 2 2
1 0 0 0 << 0 0 0 1 >> 1 1 1 1 >> 0 0 0 0 >>
3 3 3 3
0 0 0 0 << 0 0 0 0 >> 1 1 1 1 >> 0 0 0 0 >>
4 4 4 4
Operators -
Bitwise
What is the easiest way painting the below number on a wall on
multiple locations?
Operators - Bitwise
Mask
A cover that protect certain region
Or, A cover that exposes certain region
Operators - Bitwise
Mask
A cover that protect certain region
Or, A cover that exposes certain region
Stencil
Operators - Bitwise
Mask
A cover that protect certain region
Or, A cover that exposes certain region
Stencil
Operators - Bitwise
Mask
A cover that protect certain region
Or, A cover that exposes certain region
So technically, masking is exposing certain bit so that we can operate
on them like
Get Bit(s)
Set Bit(s)
Clear Bit(s)
...
Operators - Bitwise
7 6 5 4 3 2 1 0 Bit Position
7 6 5 4 3 2 1 0 Bit Position
| 1 1 1 1 0 1 1 0 Bit 4 is set to 1
off=0,low=10,medium=100,high=1000
}; Output:
enum Switch_State
Motor1_State,Motor2_State; Motor2_State is High
typedef enum Switch_State STATE; Motor1_State = 0
STATE Motor3_State; Motor3_State = 100
Motor1_State=off;
Motor2_State=high;
Motor3_State=medium;
if(Motor2_State==high)
printf("\n Motor2_State is High");
printf("\n Motor1_State=
%d",Motor1_State);
printf("\n Motor3_State=
%d",Motor3_State);
return 0;
Structure
union a Key.i
{
short int i;
char ch[2]; ADDR ADDR+1
};
union a key; Key.ch[0] Key.ch[1]
Example 1
#include<stdio.h>
typedef union
{
short int x;
char ch[2];
}demo; Output:
int main()
a.x is 512
{ a.ch[0] is 0
demo a; a.ch[1] is 2
a.x=512;
printf("a.x is %d\n",a.x);
printf("a.ch[0] is %c\n",a.ch[0]);
printf("a.ch[1] is %c\n",a.ch[1]);
return 0;
}
Applied C - Pointers
Level 1
Jargon
!!
Special words or expression used by a profession or group that are
difficult for other to understand
- Definition from Oxford Languages
Lets understand it with 7 simple rules
Sample Code
Parameter passing
int main()
{
int image[4096];
add_background(image);
add_border(image);
add_pattern(image);
send(image);
return 0;
}
Parameter passing
Register or I/O Access
(0xFF0)
Sample Code
Parameter passing
struct Test *foo1() {
Register Access // Return Structure
}
Return a more than one value from a int *foo2() {
function // Return an Array
}
int main()
{
int n = 10, s, c;
return 0;
}
Parameter passing
Register Access Command Line
Arguments
Return a more than one value from a Stack
function Hole
Dynamic Memory Allocation
Heap
.BSS
Segment
(Uninitialized)
Data
Initialized
Text Segment
Well its a bit vast topic and we need to be bit careful while dealing with
it
As said let get its details using 7 rules
5 i
CPU
5 p
RAM Integer i;
Pointer p;
Say:
i=
5;
p
=5;
Example Code 1
#include <stdio.h>
int main()
{
int i;
pointer p;
i = 5;
p = 5;
return 0;
}
Example Code 1
#include <stdio.h>
i = 5;
p = 5;
return 0;
}
Example Code 1
#include <stdio.h>
return 0;
}
Example Code 1
#include <stdio.h>
return 0;
}
Example Code 1
#include <stdio.h>
return 0;
}
Example Code 1
#include <stdio.h>
return 0;
}
Example Code 1
#include <stdio.h>
int main()
{
int i;
pointer p;
i = 5;
p = (int *) 5.5; // Error
return 0;
}
Variable
& *
Address
Example Code 2
#include <stdio.h>
int main()
{
int x;
int *p;
x = 5;
p = &x;
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 ?
int *p; 0
x = 5;
p = &x;
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 ?
int *p; 0
x = 5;
p
p = &x;
200 ?
printf(“*p contains %d\n”, *p); 0
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 5
int *p; 0
x = 5;
p
p = &x;
200 ?
printf(“*p contains %d\n”, *p); 0
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 5
int *p; & 0
x = 5;
p
p = &x;
200 1000
printf(“*p contains %d\n”, *p); 0
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 5
int *p; & 0 *
x = 5;
p
p = &x;
200 1000
printf(“*p contains %d\n”, *p); 0
return 0;
}
Example Code 2
#include <stdio.h>
int main() x
{
int x; 100 5
int *p; & 0 *
x = 5;
p
p = &x;
200 1000
printf(“*p contains %d\n”, *p); 0
return 0;
}
“x ↔ *p”
Example Code 3
#include <stdio.h> x 5 100
0
100
int main()
4
{ 100
int x = 5; 8
101
int *p;
2
p 1000 101
p = &x; 6
102
0
return 0; 102
} 4
int main()
{
int *p1;
char *p2;
float *p3;
double *p4;
return 0;
}
int main()
{
int x = 0x1234;
char y;
return 0;
}
return 0;
}
return 0;
}
return 0;
}
return 0;
}
int main()
{
int x = 0x12345678;
int *ip, char *cp;
ip = &x;
cp = &x;
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
ip = &x;
cp = &x;
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
i i
p p
ip = &x; 1000 1000
200 200
cp = &x; 0 0
c c
p p
1000 1000
printf(“*ip is %d\n”, *ip); 200 200
8 8
printf(“*cp is %d\n”, *cp);
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
i i
p p
ip = &x; 1000 1000
200 200
cp = &x; 0 0
c c
p p
1000 1000
printf(“*ip is %d\n”, *ip); 200 200
8 8
printf(“*cp is %d\n”, *cp);
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
i i
p p
ip = &x; 1000 1000
200 200
cp = &x; 0 0
c c
p p
1000 1000
printf(“*ip is %d\n”, *ip); 200 200
8 8
printf(“*cp is %d\n”, *cp);
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
i i
p p
ip = &x; 1000 1000
200 200
cp = &x; 0 0
c c
p p
1000 1000
printf(“*ip is %d\n”, *ip); 200 200
8 8
printf(“*cp is %d\n”, *cp);
return 0;
}
0 00
0
1 0
1 00
2 0
2 00
3 00
3 00
10
10
10
1
1
1
1
1
int *ip, char *cp;
0
i i
p p
ip = &x; 1000 1000
200 200
cp = &x; 0 0
c c
p p
1000 1000
printf(“*ip is %d\n”, *ip); 200 200
8 8
printf(“*cp is %d\n”, *cp);
return 0;
}
0
10
int *ip, char *cp;
0
i
cp = &x; p
1000
200
ip = &x; 0
c
p
printf(“*cp is %d\n”, *cp); 1000
200
printf(“*ip is %d\n”, *ip); 8
return 0;
}
0
10
int *ip, char *cp;
0
i
cp = &x; p
1000
200
ip = &x; 0
c
p
printf(“*cp is %d\n”, *cp); 1000
200
printf(“*ip is %d\n”, *ip); 8
return 0;
}
1 00
2 00
3 00
10
int *ip, char *cp;
1
1
1
0
i
cp = &x; p
1000
200
ip = &x; 0
c
p
printf(“*cp is %d\n”, *cp); 1000
200
printf(“*ip is %d\n”, *ip); 8
return 0;
}
Example Code 6
#include <stdio.h>
int main()
{
if (sizeof(char *) == (sizeof(long *))
printf(“Yes\n”);
return 0;
}
int main()
{
int a[] = {10, 20, 30, 40, 50};
return 0;
}
40 While
While
pointer
passing to
arithmetic
functions 50
on &a
int main()
{
int a[] = {10, 20, 30, 40, 50};
int *p = a;
p = p + 1;
return 0;
}
1000 200
0
p = 1000 + 4 1004 200
0
p = 1004
p = 1000 + 8 1008 200
0
p = 1008
p = 1000 + 12 1012 200
0
p = 1012
p = 1000 + 16 1016 200
0
p = 1016
1008 200
0
Rule: “Value(p + i) = Value(p) + i * sizeof(*p)”
p
The compiler does it for convenience
1008 200
0
int main()
A Null Pointer is logically understood to
{ be Pointing to Nothing
int *p = NULL;
De-referencing a NULL pointer is illegal
return 0; and will lead to crash (segment violation
} on Linux or reboot on custom board),
p which is better than pointing to some
100 NULL ? unknown location and failing randomly!
0 ?
?
?
#define NULL ((void *) (0))
NUL ? (Note: this is Implementation dependent)
L
int main()
{
int a[5];
int *p = malloc(5 * sizeof(int));
return 0;
}
return 0;
}
return 0; Dynamic
1016 ?
} Allocation
1012 ?
Unnamed
Region
1008 ?
p 1004 ?
4000 1000 1000 ?
return 0; Dynamic
1016 ?
} Allocation
1012 ?
Unnamed
Region by
Managed
1008 ?
user
Allocate and de-allocates as
p 1004 ?
needed
Done at run time using malloc &
4000 1000 1000 ?
free
return 0;
}
Allocate the memory from heap, the size requested is in bytes
On success it returns the allocated memory else NULL
Allocate the memory from heap, the size requested is in bytes x
number of memory blocks needed
The allocated memory is filled with 0’s
On success it returns address of the allocated memory else
NULL
Modifies the size of an already allocated memory either by malloc or
calloc
On success it returns address of the allocated memory else
NULL
NULL ?
NULL ?
NULL ?
NULL ?
NULL ?
NULL ?
NULL ?
NULL ?
Free the memory which should have allocated with the help of malloc(),
calloc() or realloc()
Freeing an already released block or any other block may have
undefined behavior
Freeing NULL doesn’t have any effect
If free is called with invalid argument, it may collapse the memory
management system
If free is not called after dynamic memory allocation, it will lead to
memory leak
int main()
A Null Pointer is logically understood to
{ be Pointing to Nothing
int *p = NULL;
De-referencing a NULL pointer is illegal
return 0; and will lead to crash (segment violation
} on Linux or reboot on custom board),
p which is better than pointing to some
100 NULL ? unknown location and failing randomly!
0 ?
?
?
#define NULL ((void *) (0))
NUL ? (Note: this is Implementation dependent)
L
return 0;
}
return 0;
}
return 0;
}
A pointer to generic data!! which can be used the way we want, since it
doesn’t have types attached to it
Since its a incomplete type, the following has to be taken care
It can’t be de-referenced!!. We must type cast to de-reference
Pointer arithmetic cannot be performed (Compiler support needed)
:GCC Extension:
6.22 Arithmetic on void- and Function-Pointers
In GNU C, addition and subtraction operations are supported on pointers to void and on
pointers to functions. This is done by treating the size of a void or a function as 1.
A consequence of this is that sizeof is also allowed on void and on function types, and
returns 1.
Example Code 12
#include <stdio.h>
int main()
{
int a[] = {0x12345678, 0xABCDE987};
void *vp = a;
return 0;
}
Example Code 12
a
#include <stdio.h>
78 1000
int main() 56 1001
{
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 0
56 1001
{
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 + 0
56 1001
{ 0
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 + 0
56 1001
{ 7
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 + 0
56 1001
{ 3
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 + 0
56 1001
{ 2
int a[] = {0x12345678, 0xABCDE987}; 34 1002
void *vp = a;
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Example Code 12
a vp
#include <stdio.h>
78 100 1000 200
int main() 0 0
56 1001
{
int a[] = {0x12345678, 0xABCDE987}; 34 1002
char *vp = a; // Compiler Warning!!
12 1003
printf(“%hhx\n”, *(char *)vp); 87 1004
printf(“%hhx\n”, *(char *)(vp + 7));
printf(“%hx\n”, *(short *)(vp + 3)); E9 1005
printf(“%x\n”, *(int *)(vp + 2)); CD 1006
return 0; AB 1007
}
Before we talk about the const qualifier along with pointers lets talk
about the values its deals with
A pointer deals with 2 values
Its own value, which is an address of another location
The value at the location its point in to
Pointer Data
Location
200 1000 100 10
0 Pointer own
0 Value at the
value, which location it’s
Is address Pointing to
So it is possible that we sometimes have situations like
We want both variable
We want its value to be constant
We want the value at the location its pointing to, to be constant
At time both constants
Pointer Data
Location
200 1000 100 10
0 0
variabl variabl
e
constan e
variabl
tvariable e
constan
constan tconstan
t t
So, we may have to define pointers as per the above needs, and this is
the place where the constant qualifier comes in picture
int main()
{
int a[] = {10, 20};
int *p = a;
*p = 100;
p++;
*p = 200;
return 0;
}
int main()
{
int a[] = {10, 20};
const int *p = a;
++p;
*p = 100;
return 0;
}
return 0;
}
int main()
{
int a[] = {10, 20};
int * const p = a;
*p = 100;
++p;
*p = 200;
return 0;
}
return 0;
}
int main()
{
int a[] = {10, 20};
const int * const p = a;
*p = 100;
++p;
*p = 200;
return 0;
}
return 0;
}
So the possible combinations are
Both variable
Its value to be constant
Value at the location its pointing to, to be constant
Both constants
Pointer Data
Location
200 1000 100 10
0 0
variabl variabl
e
constan e
variabl
tvariable e
constan
constan tconstan
t t
int main()
{
const int a[] = {10, 20};
int *p = a; // Compiler Warning!!
*p = 100;
++p;
*p = 200;
return 0;
}
int main()
{
int *p = a; // Compiler Warning!!
return 0;
}
&&val
applicable? More details on:
Pointer to Pointer
Visualize Pointer to a Pointe
r
Do’s and Don’ts
Pointer Arithmetic - Subtractions
Precedence and
Associativity
Pointer Conversions
Associated Errors with Pointers
Example Code 20
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(5 * sizeof(char));
/* TODO: Error handling */
p = p * 8; // Compilation Error
p = p / 8; // Compilation Error
free(p);
p = NULL;
return 0;
}
Example Code 21
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(5 * sizeof(char));
/* TODO: Error handling */
p = p + p; // Compilation Error
p = p * p; // Compilation Error
p = p / p; // Compilation Error
free(p);
p = NULL;
return 0;
}
Example Code 22
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = malloc(5 * sizeof(char));
/* TODO: Error handling */
p = p - p;
// Possible, gives you the distance
// between 2 pointers, in this case
// it would NULL!!
free(p);
return 0;
}
Example Code 23
#include <stdio.h>
int main()
{
int a[] = {10, 20, 30, 40, 50};
int *p1 = &a[0];
int *p2 = &a[1];
printf(“%ld\n”, p1 – p2);
printf(“%ld\n”, p2 – p1);
p2 = p2 + 2;
printf(“%ld\n”, p2 - p1);
printf(“%ld\n”, p1 – p2);
return 0;
}
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
Example Code 23
#include <stdio.h>
int main()
{
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0];
Since the precedence level of the *
*p++; printf(“%ld\n”, *p);
operator and ++/-- operator are the
*(p++); printf(“%ld\n”, *p);
(*p)++; printf(“%ld\n”, *p); same, their associativity is from right
++*p; printf(“%ld\n”, *p); to left.
++(*p); printf(“%ld\n”, *p);
*++p; printf(“%ld\n”, *p);
*(++p); printf(“%ld\n”, *p);
return 0;
}
int main() a
{
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0];
100 10
0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 30
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1000 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 30
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1004 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 30
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1008 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 30
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1008 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 31
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1008 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 32
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1008 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 33
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1012 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 33
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
int main() a
{ p
int a[] = {10, 20, 30, 40, 50};
int *p = &a[0]; 200 1016 100 10
0 0
*p++; printf(“%ld\n”, *p); 100 20
*(p++); printf(“%ld\n”, *p); 4
(*p)++; printf(“%ld\n”, *p); 100 33
++*p; printf(“%ld\n”, *p); 8
++(*p); printf(“%ld\n”, *p); 101 40
*++p; printf(“%ld\n”, *p); 2
*(++p); printf(“%ld\n”, *p); 101 50
6
return 0;
}
Example Code 25
#include <stdio.h>
int main()
{
int x = 0x41424344;
float y = 3.2;
char *p1 = &x;
int *p2 = &y;
printf(“%c\n”, *p1);
printf(“%x\n”, *p2);
printf(“%hx\n”, *(short *) p2);
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
return 0;
}
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
float y = 3.2;
char *p1 = &x;
int *p2 = &y;
printf(“%c\n”, *p1);
printf(“%x\n”, *p2);
printf(“%hx\n”, *(short *) p2);
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
return 0;
}
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
float y = 3.2;
char *p1 = &x;
int *p2 = &y;
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0;
}
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = &x; // Warning
1000 200
int *p2 = &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0;
}
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0;
}
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 24 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 25 x
#include <stdio.h> 44 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 25 x
#include <stdio.h> 31 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 25 x
#include <stdio.h> 31 43 42 41
int main() 100 100 100 100
{ 3 2 1 0
int x = 0x41424344;
p1
float y = 3.2;
char *p1 = (char *) &x;
1000 200
int *p2 = (int *) &y;
0
printf(“%c\n”, *p1); y
printf(“%x\n”, *p2); NOTE: Value in
printf(“%hx\n”, *(short *) p2); 40 4C CC CD Hex
*(p1 + 3) = 0x31;
printf(“%x\n”, x);
100 100 100 100
7 6 5 4
return 0; p2
}
1004 200
8
Example Code 29
#include <stdio.h>
int main()
{
int *p1;
static int *p2;
return 0;
}
Example Code 29
#include <stdio.h>
int main()
{
int *p1; // Wild Pointer
static int *p2;
return 0;
}
Example Code 30
#include <stdio.h>
int main()
{
int *p, size, sum;
while (1) {
scanf(“%d”, &size);
p = malloc(size * sizeof(int));
sum = 0;
for (i = 0; i < size; i++) {
scanf(“%d”, &p[i]);
sum = sum + p[i];
}
Example Code 30
#include <stdio.h>
int main()
{
int *p, size, sum;
while (1) {
scanf(“%d”, &size); // 1st Cycle, Say user enters 10
p
p = malloc(size * sizeof(int));
sum = 0;
for (i = 0; i < size; i++) {
scanf(“%d”, &p[i]);
sum = sum + p[i];
}
Example Code 30
#include <stdio.h>
Memor
int main() y
{ Leaked
int *p, size, sum;
while (1) {
scanf(“%d”, &size); // 2nd Cycle, Say user enters 5
p
p = malloc(size * sizeof(int));
sum = 0;
for (i = 0; i < size; i++) {
scanf(“%d”, &p[i]);
sum = sum + p[i];
}
Example Code 30
#include <stdio.h>
Memor
int main() y
{ Leaked
int *p, size, sum;
Memor
while (1) { y
scanf(“%d”, &size); // 3rd Cycle, Say user enters 7 Leaked
p
p = malloc(size * sizeof(int));
sum = 0;
for (i = 0; i < size; i++) {
scanf(“%d”, &p[i]);
sum = sum + p[i];
}
Example Code 30
#include <stdio.h>
Memor
int main() y
{ Leaked
int *p, size, sum;
Memor
while (1) { y
scanf(“%d”, &size); // nth Cycle, Say user enters 5 Leaked
p
p = malloc(size * sizeof(int));
Memor
sum = 0; y
Leaked
for (i = 0; i < size; i++) {
scanf(“%d”, &p[i]);
Memor
sum = sum + p[i]; y
} Leaked
struct Account {
struct Box {
int uid;
int length; Encapsulation of Data
char name[20];
char breadth;
double balance;
int height; Members can differ by type or
int age;
}; meaning
};
Contiguous memory for all
members
Significance of structures
Variable creation, Member access Minimize no.of parameters
while passing to functions
Size of structures, layout of structures Capture multiple results from
functions (passing structures
Memory allocation – only when variables are created (No
by reference and filling them)
memory applicable for just declared struct variable)
struct Account {
struct Box {
int uid;
int length;
char name[20];
char breadth; Structures
int age;
int height;
double balance;
};
};
#include<stdio.h>
struct Box{
int length;
int breadth;
int height;
};
int main()
{
struct Box b1={10,20,2};
struct Box *ptr;
ptr=&b1;
printf("l=%d, b=%d, h=%d",ptr->length,ptr->breadth,ptr-
>height);
return 0;
}
Restricted Circulation | L&T Technology Services | www.LTTS.com
Self Referential Structure
findVolume:-
int area(struct rectangle b) b
{ l b
return (b.length * b.breadth);
} Additional copy, user
defined data typically
large in size
Is it safe?? Returning address of local variables, which will be destroyed when function
returns (Address to auto variable, in destroyed stack frame/activation record)
struct rectangle a;
getValue(&a);
iArea=(a.length * a.breadth);
Printf(“Area=%d”,iArea);
union Sample {
uint32_t val;
union IPAddress {
struct Tuple {
uint32_t val;
uint8_t x;
struct IPPack {
uint8_t y;
unsigned int a : 8;
uint8_t z;
unsigned int b : 8;
}t1;
unsigned int c : 8;
uint8_t buf[8];
unsigned int d : 8;
};
}pack;
uint8_t carr[4];
struct Sensor {
};
enum SensorType type;
union IPAddress ip=0xC0A84819;
union Sample reading;
//access ip.carr[i] (or)
};
//ip.pack.a / b / c /d
//access reading.val, reading.buf
//(or) reading.t1 based on type
struct Box b1 =
struct Box {
{ .length=10, .breadth=12, .height=5 };
int length;
struct Box b2 = {
int breadth;
.length=12,
int height;
.height=10
};
};
x x x x y y y y y y y y z z z z ch x x x x y y y y y y y y z z z
W0 W1 W2 W3 W4 W5 W6 W7
x x x x y y y y y y y y z z z z ch x x x x y y y y y y y y
W0 W1 W2 W3 W4 W5 W6 W7
x x x x c1 y y y y y y y y z z z z c2
Can we
minimize
W0 W1 W2 W3 W4 W5 padding bits?
Padding bits for better Alignment
Structure Padding
struct Node {
int payload;
Self Referential Self Referential Structure
struct Node* pnext;
};
typedef struct Node node_t;
int multiply(int,int);
int multiply(int a,int b)
{
return a*b;
}
int main()
{
int (*ptr)(int,int)=&multiply;
int result=(*ptr)(5,6)
printf("Result=%d\n",result);
return 0;
}
Restricted Circulation | L&T Technology Services | www.LTTS.com
Passing Function Pointer as Function Arguments
Code 2
#include<stdio.h> float Gain(float a, float b)
int main() {
{ return a*b;
}
float (*fp)(float,float);
float Gain(float,float); void func(float (*funp)(float,float))
void func(float (*fp)(float,float)); {
float result; float func_result;
printf("\n Function func() is called ");
fp=Gain; func_result=(*funp)(10,2.1);
result=Gain(5,6.2); printf("\n Result of func() is %f",func_result);
printf("Result=%f\n",result); }
result=(*fp)(10,3.4);
Result=31.000000
printf("Result=%f\n",result); Result=34.000000
func(fp);
return 0; Function func() is called
Result of func() is 21.000000
} Restricted Circulation | L&T Technology Services | www.LTTS.com
Inline Function
If the function definitions are really small, then inline keyword can be used at the time of function
declaration.
The effect of using inline is when that function call instruction is executed by the compiler,
compiler simply replaces that function call with the instructions written under the function.
By doing this ,compiler is eliminating the function call overhead, which reduces the execution
time
strcpy
{
printf("String is %s",str);
}
int main()
{
char string[]="Hai";
display(string);
return 0;
}
Restricted Circulation | L&T Technology Services | www.LTTS.com
Raw Memory APIs & Conversions
memset
bzero
memchr
char buf[100];
memset(buf, '*', 100); struct Sample {
//memset(buf, 0, 100); int x;
//memset(buf, '*', 40); float y;
//memset(buf+40, '$’, 60); double z;
char dummy[NBITS];
bzero(buf, 100); };
bzero(xarr, 5*sizeof(int));
struct sample s1;
bzero(&s1, sizeof(struct
Sample));
bzerof(&s1.dummy, NBITS);
float fval=5.6f;
int arr[10]; double dval=5.6;
char buf[40]; int ival = 5;
memcmp(arr, buf, 40); int64_t lval = 5;
//memcmp(arr, buf, 20);
memcmp(&ival, &fval, 4)
uint32_t uval = 0x41424344; vs ival == fval
char carr[]="ABCD";
memcmp(&uval, carr, 4); memcpy(&lval, &dval, 8)
vs lval = dval
sprintf
int hh, mm, ss;
char tstr[10];
sscanf sprintf(tstr, "%02d:%02d:%02d",hh, mm,
ss);
snprintf for(i=0;i<n;i++) {
sprint(tbuf, “Employee:%d", (i+1);
puts(tbuf); //or any other
processing/comm
snscanf
}
char nstr[]="2578";
strtol int val = strtoul(nstr, NULL, 10);
strtoll
int n=5;
char tstr[n][20];
for(i=0;i<n;i++)
scanf("%d",tstr[i]);
for(i=0;i<n;i++)
printf("%d\n",tstr[i]);
int n=5;
char fstr[][10] =
{ "Hello","Welcome",
"black", "white",
"sunday", "April"};
How to run:-
Optimization Trade-Off
Trying to improve speed/performance Results in increased chip area and also
of the system by increasing resource increases the overall cost of the
usage and timing operations system developed
Example: To improve fast calculation,
trying to add extra ALU units and
Clock extension in processor
Trying to improve the power Results in area and timing trade-offs
requirements
Trying to minimize the system cost Affects the choice of device as it may
and time to market include a comparatively lesser number
of features or may have some other
drawbacks, like improper testing
Memory Time to
Usage Market
Processor
Selection
Program Optimization
Code Power
Optimiza Time Consumptio
tion Optimizatio n
n
O0 O1 O2 O3
O0 O1 O2 O3
● Moderate optimization to
reduce time and code
optimization.
O0 O1 O2 O3
O0 O1 O2 O3
During
If the function function call By doing this,
definitions are instruction the compiler
small, then execution by eliminates the
the inline the compiler, function call
keyword can the compiler overhead and
be used at replaces the reduces the
function function call execution
declaration. with function time.
instructions.
Short functions
defined inside the Inline function Bind all
class are can be statements
Evaluates
Parsed automatically terminated in the body
the
by the made as inline using curly of the
argument
compile functions. brackets. function.
only once.
r.
Defined Optimization of
Function ‘inline’ function Easy to debug
inside or An inline function
in C/C+ is based on because error
outside inside a class can
+ compiler and checking is done
the class. access the data
expands them during
members of the
all. compilation.
class.
Encounters
binding problem
if it contains more
Defined at Always need Definition of macro than one
the to be/are ends with the new statement since it
beginning expanded. line. doesn’t have a
of the termination
program. symbol.
Evaluates the
Expanded
argument Difficult to debug
by the
every time it To be defined macros since error
preprocess
is used inside specifically. checking doesn’t
or.
the code. Can’t access data happen during
members of the class. compile time.
struct abc {
a b
char a;
char b; c
int c;
1st Clock 2nd Clock
} var; Cycle Cycle
char a Last 2 bytes
char b of int c
2 bytes of int
c
519 Restricted Circulation | L&T Technology Services | www.LTTS.com
Structure Padding
There will be To save
unnecessary the number
wastage of of cycles,
CPU cycles to the
store the compiler
variables. adds empty
bytes
Due to called
padding, padding.
The whole
empty variable will
memory get stored in
spaces are the memory
created. in one cycle.
520 Restricted Circulation | L&T Technology Services | www.LTTS.com
Structure Padding
EMPTY
a b
The size is 8
bytes.
The size is 12
bytes.
● While interchanging the variable, the size of all the bytes is 12.
Empty Empty
a b
c
● Depending on the need for the speed of execution and memory
allocation, ‘Structure Padding’ can be disabled.
It is necessary to
avoid the structure
padding in C.
Structure padding is
performed by the
compiler. It
increases the size of
the structure
greater than the
size of the structure
members.
Methods
Using attributes
Switch is faster than the if-else ladder Cases must not have variable
due to ‘jump tables’. expression. Example: case 2+1
Nested if-
Dead code
else-if
C Code is more
C code is A program can be
portable and can
efficient, easy to written on one
be compiled in
understand, machine and run
other platforms
maintain and on other
with least
debug. machines.
modifications.
Code snippet before the loop invariant Code snippet after the loop invariant
expression has been hoisted out of the loop expression has been hoisted out of the loop