Embedded C 1
Embedded C 1
Introduction To Embedded C
Department Of ECE
Introduction To Embedded C
2
C
●
Prior to C, most of the computer languages (such as
Algol)
– Academic oriented, unrealistic and were generally defined by
committees.
– Designed having application domain in mind (Non portable)
●
It has lineage starting from CPL
– Martin Richards implemented BCPL
– Ken Thompson further refined BCPL to a language named as B
– Dennis M. Ritchie added types to B and created a language C
●
With just 32 keywords, C established itself in a very wide
base of applications.
4
C
Where is it used?
●
System Software Development
●
Embedded Software Development
●
OS Kernel Development
●
Firmware, Middle-ware and Driver Development
●
File System Development
And many more!!
5
C
Important Characteristics
●
Considered as a middle level language
●
Can be considered as a pragmatic language.
●
It is indented to be used by advanced programmers, for
serious use, and not for novices and thus qualify less as
an academic language for learning
●
Gives importance to curt code.
●
It is widely available in various platforms from
mainframes to palmtops and is known for its wide
availability
6
C
Important Characteristics
●
It is a general-purpose language, even though it is applied
and used effectively in various specific domains
●
It is a free-formatted language (and not a strongly-typed
language)
●
Efficiency and portability are the important
considerations
●
Library facilities play an important role
7
C
Standard
●
“The C programming language” book served as a
primary reference for C programmers and
implementers alike for nearly a decade
●
However it didn’t define C perfectly and there
were many ambiguous parts in the language
● As far as the library was concerned, only the C
implementation in UNIX was close to the
’standard’
●
So many dialects existed for C and it was the time the language has
to be standardized and it was done in 1989 with ANSI C standard
●
Nearly after a decade another standard, C9X, for C is available that
provides many significant improvements over the previous 1989
ANSI C standard
8
C
Keywords a
●
In programming, a keyword is a word that is reserved by
program because the word has a special meaning
●
Keywords can be commands or parameters
●
Every programming language has a set of keywords that
cannot be used as variable names
●
Keywords are sometimes called reserved names
C 9
Keywords - Categories
Documentation
●
A typical code might contain the
blocks shown on left side
Preprocessor Statements ●
It is generally recommended to
practice writing codes with all
Global Declaration
the blocks
The Main Code:
--------------------
Local Declarations
Program Statements
Function Calls
{
/* To display Hello world */ Comment
}
12
C
Compilation
●
Assuming your code is ready, use the following commands
to compile the code
●
On command prompt, type
$ gcc <file_name>.c
●
This will generate a executable named a.out
●
But it is recommended that you follow proper conversion
even while generating your code, so you could use
$ gcc <file_name>.c -o <file_name>
●
This will generate a executable named <file_name>
13
C
Execution
●
To execute your code you shall try
$ ./a.out
●
If you have named you output file as your <file_name>
then
$ ./<file_name>
●
This should the expected result on your system
14
Embedded C
Number Systems
●
Literally computer understand only two states HIGH and
LOW making it a binary system
●
These states are coded as 1 or 0 called binary digits
●
“Binary Digit” gave birth to the word “Bit”
●
Bit is known a basic unit of information in computer and
digital communication
Value No of Bits
0 0
1 1
16
Embedded C
Data Representation - Byte
●
A unit of digital information
●
Commonly consist of 8 bits
●
Considered smallest addressable unit of memory in
computer
Value No of Bits
0 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 1
17
Embedded C
Data Representation - Character
●
One byte represents one unique character like 'A', 'b', '1',
'$' ...
●
Its possible to have 256 different combinations of 0s and
1s to form a individual character
●
There are different types of character code
representation like
– ASCII → American Standard Code for Information
Interchange – 7 Bits (Extended - 8 Bits)
– EBCDIC → Extended BCD Interchange Code – 8 Bits
– Unicode → Universal Code - 16 Bits and more
18
Embedded C
Data Representation - Character
the
●
ASCII is the oldest representation
●
Please try the following on command prompt to know
available codes
$ man ascii
●
Can be represented by char datatype
Value No of Bits
0 0 0 1 1 0 0 0 0
A 0 1 0 0 0 0 0 1
Embedded C 19
Data Representation - Word
●
Amount of data that a machine can fetch and process at
one time
●
An integer number of bytes, for example, one, two, four,
or eight
●
General discussion on the bitness of the system is
references to the word size of a system, i.e., a 32 bit
chip has a 32 bit (4 Bytes) word size
Value No of Bits
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0
1
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1
Embedded C
Integer Number - Positive 20
●
Integers are like whole numbers, but allow negative
numbers and no fraction
●
An example of 1310 in 32 bit system would be
Bit No of Bits
Position 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Value 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
1
Embedded C 21
Integer Number - Negative
●
Negative Integers represented with the 2's complement of
the positive number
● An example of -1310 in 32 bit system would be
Bit No of Bits
Position 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Value 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1
1's Compli 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0
Add 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
2's Compli 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1
n
●
Mathematically : -k ≡ 2 - k
22
Embedded C
Float Point Number
●
A formulaic representation which approximates a real
number
●
Computers are integer machines and are capable of
representing real numbers only by using complex codes
●
The most popular code for representing real numbers is
called the IEEE Floating-Point Standard
char
Integral
int
Data
Types
float
Floating Point
double
24
Embedded C
Data Type Modifiers and Qualifiers
short T
Size long T
signed T
Signedness
unsigned T
const V
Qualifiers
volatile V
Notes: V Variables
- ANSI says, ensure that: char ≤ short ≤ int ≤ long T Data Types
- unsigned float in not supported F Functions
Embedded C 25
Data Type and Function storage modification
auto V
static V F
Storage
Modifiers
extern V F
register V
inline F V Variables
T Data Types
F Functions
Embedded C 26
Code Statements - Simple
int main()
{
number = 5;
3; +5; Assignment statement
int main()
{
do while
29
Embedded C
Conditional Constructs - if
Syntax Example
if (condition) #include <stdio.h>
{
statement(s); int main()
} {
int num1 = 2;
Syntax Flow
if (condition)
{
statement(s);
}
else true
{ cond?
statement(s);
} false
code code
31
Embedded C
Conditional Constructs – if else
Example
#include <stdio.h>
int main()
{
int num1 = 10;
if (num1 < 5)
{
printf(“num1 < 5\n”);
}
else
{
printf(“num1 > 5\n”);
}
return 0;
}
32
Embedded C
Conditional Constructs – if else if
Syntax Flow
if (condition1)
{
statement(s);
} true
else if (condition2) cond 1? code
{
statement(s); false
} true
else
cond 2? code
{
statement(s);
false
}
code
Embedded C 33
Conditional Constructs – if else if
Example
#include <stdio.h>
int main()
{
int num1 = 10;
if (num1 < 5)
{
printf(“num1 < 5\n”);
}
else if (num1 > 5)
{
printf(“num1 > 5\n”);
}
else
{
printf(“num1 = 5\n”);
}
return 0;
}
34
Embedded C
Conditional Constructs – switch
Syntax Flow
switch (expression)
{
case constant:
statement(s); expr
break;
case constant:
statement(s); true
break; case1? code break
case constant:
statement(s); false
break; true
default: case2? code break
statement(s);
} false
int main()
{
int option;
printf(“Enter the value\n”);
scanf(“%d”, &option);
switch (option)
{
case 10:
printf(“You entered 10\n”);
break;
case 20:
printf(“You entered 20\n”);
break;
default:
printf(“Try again\n”);
}
return 0;
}
Embedded C 36
Conditional Constructs – while
Syntax Flow
while (condition)
{
●
Controls the loop.
statement(s);
●
Evaluated before each
} execution of loop body
Example
false
#include <stdio.h>
cond?
int main()
{ true
int i; co de
i = 0;
while (i < 10)
{
printf(“Looped %d times\n”, i);
i++;
}
return 0;
}
37
Embedded C
Conditional Constructs – do while
Syntax
do
{
●
Controls the loop.
statement(s);
●
Evaluated after each Flow
} while (condition); execution of loop body
Example
#include <stdio.h>
int main()
code
{
int i;
true
i = 0;
do cond?
{
printf(“Looped %d times\n”, i);
i++; false
} while (i < 10);
return 0;
}
38
Embedded C
Conditional Constructs – for
Syntax
for (init; condition; post evaluation expr) Flow
{
statement(s); ●
Controls the loop.
} ●
Evaluated before each
execution of loop body
Example init
#include <stdio.h>
false
int main() cond?
{
int i; true
co de
for (i = 0; i < 10; i++)
{
printf(“Looped %d times\n”, i); post eval
} expr
return 0;
}
39
Embedded C
Conditional Constructs – continue
Flow
●
A continue statement causes a jump
to the loop-continuation portion,
that is, to the end of the loop body
code block
● The execution of code appearing
after the continue will be skipped true
cond? continue?
●
Can be used in any type of multi
iteration loop false
code block
Syntax
do loop
{ cond?
true
conditional statement
continue; false
} while (condition);
40
Embedded C
Conditional Constructs – continue
Example
#include <stdio.h>
int main()
{
int i;
return 0;
}
41
Embedded C
Conditional Constructs – break
Flow
●
A break statement shall appear
only in “switch body” or “loop
body” code block
●
“break” is used to exit the loop,
the statements appearing after true
break in the loop will be skipped cond? break?
true false
Syntax loop
do cond?
{
conditional statement false
break;
} while (condition);
42
Embedded C
Conditional Constructs – break
Example
#include <stdio.h>
int main()
{
int i;
return 0;
}
43
Embedded C
Conditional Constructs – break
Example
#include <stdio.h>
int main()
{
int i;
return 0;
}
44
Embedded C
Operators
●
Symbols that instructs the compiler to perform specific
arithmetic or logical operation on operands
●
All C operators do 2 things
– Operates on its Operands
– Returns a value
Embedded C 45
Operators
unary
Operand binary
ternary
Arithmetic + - * / % ...
Category
Logical ! || && ...
Example
#include <stdio.h>
return 0;
}
48
Embedded C
Type Conversion
Implicit
Type
Conversion
Explicit
49
Embedded C
Type Conversion Hierarchy
long double
double
float
unsigned long long
signed long long
unsigned long
signed long
unsigned int
signed int
unsigned short
signed short
unsigned char
signed char
50
Embedded C
Type Conversion - Implicit
●
Automatic Unary conversions
– The result of + and - are promoted to int if operands are
char and short
– The result of ~ and ! is integer
●
Automatic Binary conversions
– If one operand is of LOWER RANK (LR) data type & other is
of HIGHER RANK (HR) data type then LOWER RANK will be
converted to HIGHER RANK while evaluating the expression.
– Example: LR + HR → LR converted to HR
51
Embedded C
Type Conversion - Implicit
●
Type promotion
– LHS type is HR and RHS type is LR → int = char → LR is promoted
to HR while assigning
●
Type demotion
– LHS is LR and RHS is HR → int = float → HR rank will be demoted
to LR. Truncated
52
Embedded C
Type Conversion – Explicit (Type Casting)
Syntax
(data type) expression
Example
#include <stdio.h>
int main()
{
int num1 = 5, num2 = 3;
return 0;
}
53
Embedded C
Operators - Logical
Operator Description Associativity
! Logical NOT R to L
Example && Logical AND L to R
|| Logical OR L to R
#include <stdio.h>
int main()
{ What will be
int num1 = 1, num2 = 0;
the output?
if (++num1 || num2++)
{
printf(“num1 is %d num2 is %d\n”, num1, num2);
}
num1 = 1, num2 = 0;
if (num1++ && ++num2)
{
printf(“num1 is %d num2 is %d\n”, num1, num2);
}
else
{
printf(“num1 is %d num2 is %d\n”, num1, num2);
}
return 0;
}
54
Embedded C
Operators - Relational
Operator Description Associativity
> Greater than L to R
< Lesser than
>= Greater than or equal
<= Lesser than or equal
== Equal to
Example
!= Not Equal to
#include <stdio.h>
int main()
{
float num1 = 0.7;
return 0;
}
55
Embedded C
Operators - Assignment
Example Example
#include <stdio.h> #include <stdio.h>
return 0;
}
56
Embedded C
Operators - Bitwise
●
Bitwise operators perform operations on bits
●
The operand type shall be integral
●
Return type is integral value
57
Embedded C
Operators - Bitwise
OVpaelruaend Value
Bitwise ANDing of 0Ax60 0x61 0 1 1 0 0 0 0 1
& Bitwise AND all the bits in two 0Bx13 0x13 0 0 0 1 0 0 1 1
operands
A0&x1B3 0x01 0 0 0 0 0 0 0 1
OVpaelruaend Value
Bitwise ORing of 0Ax60 0x61 0 1 1 0 0 0 0 1
| Bitwise OR all the bits in two 0Bx13 0x13 0 0 0 1 0 0 1 1
operands
A0|x1B3 0x73 0 1 1 1 0 0 1 1
OVpaelruaend Value
Bitwise XORing of 0Ax60 0x61 0 1 1 0 0 0 0 1
^ Bitwise XOR all the bits in two 0Bx13 0x13 0 0 0 1 0 0 1 1
operands
A0^x1B3 0x72 0 1 1 1 0 0 1 0
58
Embedded C
Operators - Bitwise
OVpaelruaend Value
Complimenting
~ Compliment all the bits of the 0Ax60 0x61 0 1 1 0 0 0 0 1
operand 0x9E
0~xA13 1 0 0 1 1 1 1 0
Say A = 91 A << 2
Say A = 91 A >> 2
Example
#include <stdio.h>
int main()
{
int count;
unsigned char num = 0xFF;
return 0;
}
63
Embedded C
Operators – Language - sizeof()
Example
#include <stdio.h>
int main()
{
int num = 5;
return 0;
}
Example
#include <stdio.h>
int main()
{
int num1 = 5;
int num2 = sizeof(++num1);
return 0;
}
64
Embedded C
Operators – Language - sizeof()
●
3 reasons for why sizeof is not a function
– Any type of operands,
– Type as an operand,
– No brackets needed across operands
65
Embedded C
Operators – Ternary
Syntax
Condition ? Expression 1 : Expression 2;
Example
#include <stdio.h>
int main()
{ #include <stdio.h>
int num1 = 10;
int num2 = 20; int main()
int num3; {
int num1 = 10;
if (num1 > num2) int num2 = 20;
{ int num3;
num3 = num1;
} num3 = num1 > num2 ? num1 : num2;
else printf(“Greater num is %d\n”, num3);
{
num3 = num2; return 0;
} }
printf(“%d\n”, num3);
return 0;
}
66
Embedded C
Operators – Comma
●
The left operand of a comma operator is evaluated as a
void expression: Then the right operand is evaluated, the
result has its type and value
● Comma acts as separator (not an operator) in following
cases
– Arguments to functions
– Lists of initializers (variable declarations)
●
But, can be used with parentheses as function arguments
such as -
– foo ((x = 2, x + 3)); // final value of argument is 5
67
Embedded C
Over and Underflow
●
8-bit Integral types can hold certain ranges of values
●
So what happens when we try to traverse this boundary?
Overflow
(127 + 1)
Underflow
(-128 - 1)
68
Embedded C
Overflow – Signed Numbers
Say A = +127
Add 1 0 0 0 0 0 0 0 1
Say A = -128
Add -1 1 1 1 1 1 1 1 1
A conveyor belt
Starts here
Equally spaced
Defined length
Carry similar items
Index as 10th item
Ends here
Embedded C 71
Arrays – Know the Concept
Conveyor Belt
Top view First Element
An Array Start (Base) address
●
Total Elements
●
Fixed size
●
Contiguous Address
●
Elements are
accessed by
indexing
●
Legal access region
Last Element
End address
72
Embedded C
Arrays
Syntax
data_type name[SIZE];
Example
int age[5] = {10, 20, 30, 40, 50};
10 20 30 40 50
base addr + 16
base addr + 12
base addr + 4
base addr + 8
base addr
73
Embedded C
Arrays – Point to be noted
●
An array is a collection of data of same data type.
●
Addresses are sequential
●
First element with lowest address and the last element
with highest address
●
Indexing starts from 0 and should end at array SIZE – 1.
Example say array[5] will have to be indexed from 0 to 4
●
Any access beyond the boundaries would be illegal access
Example, You should not access array[-1] or array[SIZE]
74
Embedded C
Arrays – Why?
Example
#include <stdio.h>
int main()
#include <stdio.h>
{
int num1 = 10; int main()
int num2 = 20; {
int num3 = 30; int num_array[5] = {10, 20, 30, 40, 50};
int num4 = 40; int index;
int num5 = 50;
for (index = 0; index < 5; index++)
printf(“%d\n”, num1); {
printf(“%d\n”, num2); printf(“%d\n”, num_array[index]);
printf(“%d\n”, num3); }
printf(“%d\n”, num4);
printf(“%d\n”, num5); return 0;
}
return 0;
}
75
Embedded C
Arrays - Reading
Example
#include <stdio.h>
int main()
{
int array[5] = {1, 2, 3, 4, 5};
int index;
index = 0;
do
{
printf(“Index %d has Element %d\n”, index, array[index]);
index++;
} while (index < 5);
return 0;
}
76
Embedded C
Arrays - Storing
Example
#include <stdio.h>
int main()
{
int num_array[5];
int index;
return 0;
}
77
Embedded C
Arrays - Initializing
Example
#include <stdio.h>
int main()
{
int array1[5] = {1, 2, 3, 4, 5};
int array2[5] = {1, 2};
int array3[] = {1, 2};
int array4[]; /* Invalid */
printf(“%u\n”, sizeof(array1));
printf(“%u\n”, sizeof(array2));
printf(“%u\n”, sizeof(array3));
return 0;
}
78
Embedded C
Arrays – Copying
●
Can we copy 2 arrays? If yes how?
Example
#include <stdio.h>
int main()
{
int array_org[5] = {1, 2, 3, 4, 5}; Waow!! so simple?
int array_bak[5];
But can I do this?
array_bak = array_org;
if (array_bak == array_org)
{
printf(“Copied\n”);
}
return 0;
}
79
Embedded C
Arrays – Copying
●
No!! its not so simple to copy two arrays as put in the
previous slide. C doesn't support it!
●
Then how to copy an array?
●
It has to be copied element by element
80
Embedded C
Pointers – Jargon
●
What's a Jargon?
– Jargon may refer to terminology used in a certain
profession, such as computer jargon, or it may refer to any
nonsensical language that is not understood by most
people.
– Speech or writing having unusual or pretentious vocabulary,
convoluted phrasing, and vague meaning.
●
Pointer are perceived difficult
– Because of jargonification
●
So, let's dejargonify & understand them
81
Embedded C
Pointers – Analogy with Book
●
Just like a book analogy, Computers contains different
different sections (Code) in the memory
●
All sections have different purposes
●
Every section has a address and we need to point to them
whenever required
●
In fact everything (Instructions and Data) in a particular
section has a address!!
●
So the pointer concept plays a big role here
83
Embedded C
Pointers – Why?
●
To have C as a low level language being a high level
language
●
Returning more than one value from a function
●
To achieve the similar results as of ”pass by variable”
●
parameter passing mechanism in function, by passing the
reference
●
To have the dynamic allocation mechanism
84
Embedded C
Pointers – The 7 Rules
●
Rule 1 - Pointer is an Integer
●
Rule 2 - Referencing and De-referencing
●
Rule 3 - Pointer means Containing
●
Rule 4 - Pointer Type
● Rule 5 - Pointer Arithmetic
● Rule 6 - Pointing to Nothing
● Rule 7 - Static vs Dynamic Allocation
85
Embedded C
Pointers – The 7 Rules – Rule 1
6 i
CPU
6 p
RAM
Integer i;
Pointer p;
Say:
i = 6;
p = 6;
86
Embedded C
Pointers – The 7 Rules – Rule 1
●
Whatever we put in data bus is Integer
●
Whatever we put in address bus is Pointer
●
So, at concept level both are just numbers. May be of
different sized buses
●
Rule: “Pointer is an Integer”
●
Exceptions:
– May not be address and data bus of same size
– Rule 2 (Will see why? while discussing it)
87
Embedded C
Pointers – Rule 1 in detail
Example
#include <stdio.h> x
int main() 1000 ? Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 ? Say 4 bytes
ptr = 5;
return 0;
}
88
Embedded C
Pointers – Rule 1 in detail
Example
#include <stdio.h> x
int main() 1000 5 Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 5 Say 4 bytes
ptr = 5;
return 0;
}
●
So pointer is an integer
●
But remember the “They may not be of same size”
32 bit system = 4 Bytes
64 bit system = 8 Bytes
89
Embedded C
Pointers – The 7 Rules – Rule 2
●
Rule : “Referencing and Dereferencing”
&
Variable Address
*
90
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h> x
int main() 1000 5 Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 ? Say 4 bytes
return 0;
}
●
Considering the image, What would the below line mean?
* 1000
91
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h> x
int main() 1000 5 Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 ? Say 4 bytes
return 0;
}
●
Considering the image, What would the below line mean?
* 1000
●
Goto to the location 1000 and fetch its value, so
* 1000 → 5
92
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h> x
int main() 1000 5 Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 ? Say 4 bytes
ptr = &x;
return 0;
}
●
What should be the change in the above diagram for the
above code?
93
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h> x
int main() 1000 5 Say 4 bytes
{
int x;
int *ptr; ptr
x = 5; 2000 1000 Say 4 bytes
ptr = &x;
return 0;
}
●
So pointer should contain the address of a variable
●
It should be a valid address
94
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h> x
int main() 1000 5
{ & *
int x;
int *ptr; ptr
x = 5; 2000 1000
ptr = &x;
return 0;
}
Example
#include <stdio.h>
int main()
{
int number = 10;
int *ptr;
ptr = &number;
return 0;
}
96
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h>
int main()
{
int number = 10;
int *ptr;
ptr = &number;
return 0;
}
97
Embedded C
Pointers – Rule 2 in detail
Example
#include <stdio.h>
int main()
{
int number = 10;
int *ptr;
ptr = &number;
*ptr = 100;
return 0;
}
●
By compiling and executing the above code we can
conclude
“*ptr = number”
98
Embedded C
Pointers – The 7 Rules – Rule 3
●
Pointer pointing to a Variable = Pointer contains the
Address of the Variable
●
Rule: “Pointing means Containing”
Example 1000
#include <stdio.h> a 10
1004
int main()
{ 1008
int a = 10;
int *ptr; 1012
ptr = &a;
1016
ptr 1000
return 0;
} 1020
1024
99
Embedded C
Pointers – Rule 4 in detail
●
The question is, does address has a type?
Example
num
#include <stdio.h>
1000 1234 4 bytes
int main()
{
int num = 1234; ch
char ch;
1004 ? 1 bytes 4
return 0;
}
●
So from the above above diagram can we say &num →
bytes and &ch → 1 byte?
100
Embedded C
Pointers – Rule 4 in detail
●
The answer is no!!, it does
not depend on the type of 1000
num
the variable
1004
ch
●
The size of address 1008
remains the same, and it 1012
depends on the system we
1016
use
1020
●
Then a simple questions
1024
arises is why types to
pointers?
101
Embedded C
Pointers – Rule 4 in detail
num
Example 1234
#include <stdio.h> 1000
int main() ch
{ ?
int num = 1234;
char ch; 1004
iptr
int *iptr; ?
char *cptr;
2000
return 0; cptr
} ?
2004
●
Lets consider the above examples to understand it
●
Say we have a integer and a character pointer
102
Embedded C
Pointers – Rule 4 in detail
num
Example 1234
#include <stdio.h> 1000
int main() ch
{ ?
int num = 1234;
char ch; 1004
iptr
int *iptr = # 1000
char *cptr = &ch;
2000
return 0; cptr
} 1004
2004
●
Lets consider the above examples to understand it
●
Say we have a integer and a character pointer
Embedded C 103
Pointers – Rule 4 in detail
num
●
With just the address, can 1234
num
●
When we say while 1234
●
Since the discussion is on the data fetching, its better
we have knowledge of storage concept of machines
●
The Endianness of the machine
●
What is this now!!?
– Its nothing but the byte ordering in a word of the
machine
●
There are two types
– Little Endian – LSB in Lower Memory Address
– Big Endian – MSB in Lower Memory Address
106
Embedded C
Pointers – Rule 4 in detail - Endianness
●
LSB
– The byte of a multi byte number with the least
importance
– The change in it would have least effect on complete
number
●
MSB
– The byte of a multi byte number with the most
importance
– The change in it would have more effect on complete
change number
107
Embedded C
Pointers – Rule 4 in detail - Endianness
Example ●
Let us consider the following
#include <stdio.h>
example and how it would be
int main()
{ stored in both machine types
int num = 0x12345678;
return 0;
}
●
OK Fine. What now? How is it going affect to fetch and
modification?
● First of all
Let us consider the same example putis in
it the
possible to
previous
slide access a integer with character
● pointer?
Example
#include <stdio.h>
int main()
{
int num = 0x12345678;
int *iptr, char *cptr;
●
If yes, what should be the
iptr = #
effect on access?
cptr = #
●
Let us assume a Litte Endian
return 0;
} system
109
Embedded C
Pointers – Rule 4 in detail - Endianness
1000 num
78 56 34 12
2000 iptr
1000
2004 cptr
1000
●
So from the above diagram it should be clear that when we do
cross type accessing, the endianness should be considered
110
Embedded C
Pointers – The 7 Rules – Rule 4
Example
#include <stdio.h>
●
So changing *cptr will change only
int main() the byte its pointing to
{
int num = 0x12345678;
1000 num
int *iptr = # 12 56 34 12
char *cptr = #
2004 cptr
1000
*cptr = 0x12;
●
So *iptr would contain 0x12345612
now!!
111
Embedded C
Pointers – The 7 Rules – Rule 4
●
So as a summary the type to the pointer does not say its
type, but the type of the data its pointing to
●
So the size of the pointer for different types remains the
same
Example
#include <stdio.h>
int main()
{
if (sizeof(char *) == sizeof(long long *))
{
printf(“Yes its Equal\n”);
}
return 0;
}
112
Embedded C
Pointers – The Rule 5 in detail
●
Before proceeding further let us understand an array
interpretation
– Original Big Variable
– Constant Pointer to the 1st Small Variable in the Big
Variable
– When first interpretation fails than second
interpretation comes to picture.
– The following are the case when first interpretation
fails:
●
When we pass array variable as function argument
● When we assign a array variable to pointer variable
113
Embedded C
Pointers – The Rule 5 in detail
Example
array 1000
#include <stdio.h> 1
1004
int main() 2
{ 1008
int array[5] = {1, 2, 3, 4, 5}; 3
int *ptr = array; 1012
4
return 0; 1016
} 5
1020
●
So, 1024
ptr 1000
Address of array = 1000
Base address = 1000
&array[0] = 1 → 1000
&array[1] = 2 → 1004
114
Embedded C
Pointers – The Rule 5 in detail
Example
array 1000
#include <stdio.h> 1
1004
int main() 2
{ 1008
int array[5] = {1, 2, 3, 4, 5}; 3
int *ptr = array; 1012
4
printf(“%d\n”, *ptr); 1016
5
return 0; 1020
}
1024
ptr 1000
●
This code should print 1 as output
since its points to the base address
●
Now, what should happen if we do
ptr = ptr + 1;
115
Embedded C
Pointers – The Rule 5 in detail
●
ptr = ptr + 1; 1000
array 1
●
The above line can be discribed as 1004
2
follows
1008
3
●
ptr = ptr + 1 * sizeof(data type)
1012
4
●
In this example we have integer
1016
a 5
array, so 1020
●
ptr = ptr + 1 * sizeof(int)
1024
= ptr + 1 * 4 ptr 1004
= ptr + 4
●
Here ptr = 1000 so
= 1000 + 4
= 1004
116
Embedded C
Pointers – The Rule 5 in detail
●
Why does the compiler does this?. Just for convenience
117
Embedded C
Pointers – The Rule 5 in detail
●
Relation with array can be explained
array
1
1000 as
2
1004 ptr + 2
1008
3 ptr + 2 * sizeof(int)
1012
4
1000 + 2 * 4
1016
5
1020 1008 → &array[2]
ptr 1008
1024 ●
So,
ptr + 2 → 1008 → &array[2]
ptr = ptr + 2;
*(ptr + 2) → *(1008) → array[2]
118
Embedded C
Pointers – The Rule 5 in detail
●
So to access a array element using a pointer would be
*(ptr + i) → array[i]
●
This can be written as following too!!
array[i] → *(array + i)
●
Which results to
ptr = array
●
So as summary the below line also becomes valid because
of second array interpretation
int *ptr = array;
119
Embedded C
Pointers – The Rule 5 in detail
●
Wait can I write
*(ptr + i) → *(i + ptr)
●
Yes. So than can I write
array[i] → i[array]
●
Yes. You can index the element in both the ways
120
Embedded C
Pointers – The 7 Rules – Rule 5 – Size of void
●
On gcc size of void is 1
●
Hence pointer arithmetic can be performed on void
pointer
●
Its compiler dependent!
Example
#include <stdio.h>
int main()
num
{
int *num; 1000 ? 4 bytes
return 0;
}
?
Where am I
?
pointing to?
?
What does it ?
Contain? ?
Can I read or
write wherever
I am pointing?
122
Embedded C
Pointers – Rule 6 in detail – NULL Pointer
●
Is it pointing to the valid address?
●
If yes can we read or write in the location where its
pointing?
●
If no what will happen if we access that location?
●
So in summary where should we point to avoid all this
questions if we don't have a valid address yet?
● The answer is Point to Nothing!!
123
Embedded C
Pointers – Rule 6 in detail – NULL Pointer
●
Now what is Point to Nothing?
●
A permitted location in the system will always give
predictable result!
●
It is possible that we are pointing to some memory location
within our program limit, which might fail any time! Thus
making it bit difficult to debug.
●
An act of initializing pointers to 0 (generally, implementation
dependent) at definition.
●
0??, Is it a value zero? So a pointer contain a value 0?
●
Yes. On most of the operating systems, programs are not
permitted to access memory at address 0 because that
memory is reserved by the operating system
124
Embedded C
Pointers – Rule 6 in detail – NULL Pointer
●
So by convention if a pointer is initialized to zero value,
it is logically understood to be point to nothing.
●
And now, in the pointer context, 0 is called as NULL
●
So a pointer that is assigned NULL is called a Null Pointer
which is Pointing to Nothing
●
So dereferencing a NULL pointer is illegal and will always
lead to segment violation, which is better than pointing
to some unknown location and failing randomly!
125
Embedded C
Pointers – Rule 6 in detail – NULL Pointer
●
Need for Pointing to 'Nothing'
– Terminating Linked Lists
– Indicating Failure by malloc, ...
●
Solution
– Need to reserve one valid value
– Which valid value could be most useless?
– In wake of OSes sitting from the start of memory, 0 is a
good choice
– As discussed in previous sides it is implementation
dependent
126
Embedded C
Pointers – Rule 6 in detail – NULL Pointer
Example
#include <stdio.h>
int main()
{
int *num;
num = NULL;
return 0;
}
Example
#include <stdio.h>
int main()
{
int *num = NULL;
return 0;
}
127
Embedded C
Pointers – The 7 Rules – Rule 7
●
Rule: “Static Allocation vs Dynamic Allocation”
Example Example
#include <stdio.h> #include <stdio.h>
●
Unnamed vs named Allocation = Unnamed/named Houses
1 2 3 4 5 6 7 8
●
Managed by Compiler vs User
●
Compiler
– The compiler will allocate the required memory
internally
– This is done at the time of definition of variables
●
User
– The user has to allocate the memory whenever
required and deallocate whenever required
– This done by using malloc and free
130
Embedded C
Pointers – Rule 7 in detail
●
Static vs Dynamic num
1000 ?
Example
#include <stdio.h> num_ptr
int main() 2000 ? 4 bytes
{
int num, *num_ptr, *ptr; ptr
2004 ? 4 bytes
num_ptr = #
ptr = malloc(1);
return 0;
}
131
Embedded C
Pointers – Rule 7 in detail
●
Static vs Dynamic num
1000 ?
Example
#include <stdio.h> num_ptr
int main() 2000 1000 4 bytes
{
int num, *num_ptr, *ptr; ptr
2004 ? 4 bytes
num_ptr = #
ptr = malloc(1);
return 0;
}
132
Embedded C
Pointers – Rule 7 in detail
●
Static vs Dynamic num
1000 ?
Example
#include <stdio.h> num_ptr
int main() 2000 1000 4 bytes
{
int num, *num_ptr, *ptr; ptr
2004 500 4 bytes
num_ptr = #
ptr = malloc(1);
?
return 0;
} ?
?
500 ?
?
133
Embedded C
Pointers – Rule 7 in detail - Dynamic Allocation
●
The need
– You can decide size of the memory at run time
– You can resize it whenever required
– You can decide when to create and destroy it.
134
Embedded C
Pointers – Rule 7 – Dynamic Allocation - malloc
Prototype
void *malloc(size_t size);
●
Allocates the requested size of memory from the heap
●
The size is in bytes
●
Returns the pointer of the allocated memory on success,
else returns NULL pointer
135
Embedded C
Pointers – Rule 7 – Dynamic Allocation - malloc
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr; ?
ptr = malloc(5); ?
return 0; ?
}
?
? Allocate 5 Bytes
?
500 ?
?
?
Embedded C 136
Pointers – Rule 7 – Dynamic Allocation - malloc
Example ptr
#include <stdio.h> 1000 NULL
int main()
{ ?
char *ptr; ?
ptr = malloc(10); ?
NULL
137
Embedded C
Pointers – Rule 7 – Dynamic Allocation - calloc
Prototype
void *calloc(size_t nmemb, size_t size);
●
Allocates memory blocks large enough to hold "n
elements" of "size" bytes each, from the heap
●
The allocated memory is set with 0's
●
Returns the pointer of the allocated memory on success,
else returns NULL pointer
138
Embedded C
Pointers – Rule 7 – Dynamic Allocation - calloc
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr; ?
ptr = calloc(5, 1); ?
return 0; 0
}
0
Allocate 5 Bytes
0 and all are set
0 to zeros
500 0
?
?
139
Embedded C
Pointers – Rule 7 – Dynamic Allocation - realloc
Prototype
void *realloc(void *ptr, size_t size);
●
Changes the size of the already allocated memory by
malloc or calloc.
●
Returns the pointer of the allocated memory on success,
else returns NULL pointer
140
Embedded C
Pointers – Rule 7 – Dynamic Allocation - realloc
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr; ?
ptr = malloc(5); ?
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr; ?
ptr = malloc(5); ?
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr; ?
ptr = malloc(5); ?
●
Points to be noted
– Reallocating existing memory will be like deallocating
the allocated memory
– If the requested chunk of memory cannot be
extended in the existing block, it would allocate in a
new free block starting from different memory!
●
So its always a good idea to store a reallocated
block in pointer, so that we can free the old
pointer.
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free 144
Prototype
void free(void *ptr);
●
Frees the allocated memory, which must have been
returned by a previous call to malloc(), calloc() or realloc()
●
Freeing an already freed block or any other block, would
lead to undefined behaviour
●
Freeing NULL pointer has no effect.
●
If free() is called with invalid argument, might collapse the
memory management mechanism
●
If free is not called after dynamic memory allocation, will
lead to memory leak
145
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free
Example ptr
#include <stdio.h> 1000 ?
int main()
{ ?
char *ptr;
?
int i;
?
ptr = malloc(5);
?
for (i = 0; i < 5; i++)
{
?
ptr[i] = 'A' + i; ?
}
?
free(ptr);
?
return 0;
} ?
?
146
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr;
?
int i;
?
ptr = malloc(5);
?
for (i = 0; i < 5; i++)
{
?
ptr[i] = 'A' + i; ?
}
?
free(ptr);
500 ?
return 0;
} ?
?
147
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr;
?
int i;
?
ptr = malloc(5);
E
for (i = 0; i < 5; i++)
{
D
ptr[i] = 'A' + i; C
}
B
free(ptr);
500 A
return 0;
} ?
?
148
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free
Example ptr
#include <stdio.h> 1000 500
int main()
{ ?
char *ptr;
?
int i;
?
ptr = malloc(5);
E
for (i = 0; i < 5; i++)
{
D
ptr[i] = 'A' + i; C
}
B
free(ptr);
500 A
return 0;
} ?
?
149
Embedded C
Pointers – Rule 7 – Dynamic Deallocation - free
●
Points to be noted
– Free releases the allocated block, but the pointer
would still be pointing to the same block!!, So
accessing the freed block will have undefined
behaviour.
– This type of pointer which are pointing to freed
locations are called as Dangling Pointers
– Doesn't clear the memory after freeing
150