3. Goals & Objectives
● To cover the depth of the C language from its core.
● To cover all the functionalities of the language, more important
from the industry perspective.
● By the end, students are expected to have made their concepts
very clear and become comfortable using the language to any level.
● Mastering the basics, Playing with all kinds of Pointers, Var Args,
Recursions, Functions, Files, Preprocessor Directives, and many
other industry relevant topics.
● As an overall experience, it will take you through all the nitty-
gritties of C through a well organized set of examples and exercises
4. ToC
● Introduction
● Brief History
● Programming languages
● The C standard
● Important Characteristics
● Keywords
6. Language
● Simply put, a language is a stylized communication technique.
● The more varied vocabulary it has, the more expressive it
becomes. Then, there is grammar to make meaningful
communication statements out of it.
● Similarly, being more specific, a programming language is a stylized
communication technique intended to be used for controlling the
behavior of a machine (often a computer),by expressing ourselves
to the machine.
● Like the natural languages, programming languages too, have
syntactic rules (to form words) and semantic rules (to form
sentences), used to define the meaning.
8. Brief History
● Prior to C, most of the computer languages (such as Algol) were
academic oriented, unrealistic and were generally defined by
committees.
● Since such languages were designed having application domain in
mind, they could not take the advantages of the underlying
hardware and if done, were not portable or efficient under other
systems.
● It was thought that a high-level language could never achieve the
efficiency of assembly language.
Portable, efficient and easy to use language was a dream.
9. Brief History ...
● It was a revolutionary language and shook the computer world with
its might. With just 32 keywords, C established itself in a very wide
base of applications.
● It has lineage starting from CPL, (Combined Programming Language)
a never implemented language.
● Martin Richards implemented BCPL as a modified version of CPL.
Ken Thompson further refined BCPL to a language named as B.
● Later Dennis M. Ritchie added types to B and created a language,
what we have as C, for rewriting the UNIX operating system.
10. Programming languages
● There are various types of programming languages, compared on various parameters
● From Embedded system engineer’s view it should be seen how close or how much away from the hardware the
language is
● Based on that view programming languages can be categorized into three areas:
Assembly language (ex: 8051)
Middle level language (ex: C)
High level / Scripting language (ex: Shell)
● Each programming language offers some benefits with some shortcomings
● Depending on the need of the situation appropriate language needs to be chosen
● This make language selection is a key criteria when it comes to building real time products!
11. A comparison
Language parameter Assembly C Shell
Speed High Medium Medium
Portability Low Medium High
Maintainability Low Medium High
Size High Medium Low
Easy to learn Low Medium High
Shell or any scripting language is also called as ‘interpreted’ language as it
doesn’t go thru compilation phase. This is to keep the language simple as
the purpose is different than other languages.
12. The 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.
13. Important
Characteristics
● C is considered as a middle level language.
● C 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.
14. 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
15. Keyword
● In programming, a keyword is a word that is reserved by a
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
16. Keywords ...
● auto
● break
● case
● char
● const
● continue
● default
● do
● double
● else
● enum
● extern
● float
● for
● if
● int
● long
● register
● return
● short
● signed
● sizeof
● static
● struct
● switch
● typedef
● union
● unsigned
● void
● volatile
● while
● goto
20. Data representation
● Why bits?
● Representing information as bits
● Binary/Hexadecimal
● Byte representations
● ANSI data storage
● Embedded specific data storage
● Floating point representation
21. Base 2
● Base 2 Number Representation
● Electronic Implementation
● Easy to store
● Reliably transmitted on noisy and inaccurate wires
● Straightforward implementation of arithmetic
functions
23. Base 2
Integer Representation
●
Negative numbers representation:
Negative numbers are represented by 2's complement .
Below example shows how (-13) 10
are converted to binary form and stored in the 32 – bit
machine.
STEPS:
Step1: Convert ( 13 )10
to binary equivalent.
( 13 )10
= ( 0000 0000 0000 0000 0000 0000 0000 1101 )2
Step2: Take 1's complement of binary equivalent.( i.e converting all 1's to 0's &
all 0's to 1's)
( 1111 1111 1111 1111 1111 1111 1111 0010 )2
25. Byte Encoding
● 1Nibble = 4 bits
● 1Byte = 8 bits
● Binary : 000000002
- 111111112
● Decimal : 010
- 25510
● Octal : 08
- 3778
● Hexadecimal: 0016
- FF16
● Base 16 number representation
● Use characters ‘0’ to ‘9’ and ‘A’ to ‘F’
● Write FA1D37B16
in C as 0xFA1D37B
Hex Dec Bin
0 0 0000
1 1 0001
2 2 0010
3 3 0011
4 4 0100
5 5 0101
6 6 0110
7 7 0111
8 8 1000
9 9 1001
A 10 1010
B 11 1011
C 12 1100
D 13 1101
E 14 1110
F 15 1111
26. Byte Encoding
Quiz
1. Convert 103 from decimal to base 2
2. Convert 1011 0110 0011 from binary to hexadecimal
3. Convert 240 from hexadecimal to binary
4. Convert 011 111 111 from binary to base 8
5. Convert 14 from base 8 to binary
27. Byte ordering
Example:
● Variable x has 2-byte representation D7C4
Machine Type Ordering of Bytes Examples
Big Endian Least significant byte has
Highest address
Sun, Mac
Little Endian Least significant byte has
lowest address
Alphas
30. Sizes :
Basic Data Types
● Type int is supposed to represent a machine's natural word size
● The size of character is always 1 byte
● 1 byte = sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
<= sizeof(long long)
● float = 4 bytes
● double = 8 bytes
● pointer = address word, mostly same as word
31. Sizes :
Basic Data Types
● In C sizes of datatypes are not Fixed
OS 32-Bit 64-Bit
Windows LP32 LLP64
Linux LP32 LP64
32. Basic Data Types:
char
● Smallest addressable unit of the machine that can contain basic
character set.
● It is an integer type.
● Actual type can be either signed or unsigned depending on the
implementation.
● Example:
● char ch = 'a';
● char ch = 97;
Think
char ch = 'a' + 10 is possible?
33. Basic Data Types:
char
● Different ways of reading / scanning the character
Function Example
scanf scanf(“%c”, &ch);
getchar ch = getchar();
getc ch = getc(stdin);
fgetc ch = fgetc(stdin);
34. Basic Data Types:
int
● The most basic and commonly used integral type.
● Format specifiers for ints are either %d or %i, for either printf or
scanf.
● Example:
● int i = 100;
35. Real Numbers:
Representation
IEEE float: 32 bits 1 bit for the sign, 8 bits for the exponent, and 23 bits
for the mantissa. Also called single precision.
IEEE double: 64 bits 1 bit for the sign, 11 bits for the exponent, and 52 bits
for the mantissa. Also called double precision.
sign Exponent mantissa
Float ( 32 bits ) 1 bit 8 bits 23 bits
Double ( 64 bits ) 1 bit 11 bits 52 bits
36. Float to binary
Conversion Procedure
STEP 1: Convert the absolute value of the number to binary, perhaps with a
fractional part after the binary point. This can be done by converting the integral
and fractional parts separately. The integral part is converted with the techniques
examined previously. The fractional part can be converted by multiplication.
STEP 2: Append × (2 ^ 0) to the end of the binary number (which does not change
its value).
STEP 3: Normalize the number. Move the binary point so that it is one bit from the
left. Adjust the exponent of two so that the value does not change.
37. Float to binary
Conversion Procedure
STEP 4: Place the mantissa into the mantissa field of the number. Omit the leading
one, and fill with zeros on the right.
STEP 5: Add the bias to the exponent of two, and place it in the exponent field.
The bias is 2 ^ (k−1)−1, where k is the number of bits in the exponent field. For the
eight-bit format, k = 3, so the bias is 2 ^ (3−1) − 1 = 3. For IEEE 32-bit, k = 8, so the
bias is 2^( 8−1) − 1 = 127.
STEP 6: Set the sign bit, 1 for negative, 0 for positive, according to the sign of the
original number.
38. Float to binary
Conversion Example
Convert 0.1015625 to IEEE 32-bit floating point format.
0.1015625 × 2 = 0.203125 0 Generate 0 and continue.
0.203125 × 2 = 0.40625 0 Generate 0 and continue.
0.40625 × 2 = 0.8125 0 Generate 0 and continue.
0.8125 × 2 = 1.625 1 Generate 1 and continue with the rest.
0.625 × 2 = 1.25 1 Generate 1 and continue with the rest.
0.25 × 2 = 0.5 0 Generate 0 and continue.
0.5 × 2 = 1.0 1 Generate 1 and nothing remains.
STEP 1
So 0.101562510 = 0.00011012.
39. Float to binary
Conversion Example
Convert 0.1015625 to IEEE 32-bit floating point format.
STEP 2
Normalize: 0.00011012 = 1.1012 × 2-4.
STEP 3
Mantissa is 10100000000000000000000, exponent is -4 + 127 = 123 =
011110112, sign bit is 0
So 0.1015625 is 00111101110100000000000000000000 = 3dd0000016
41. const
● The const keyword is used to create a read only variable.
● Once initialised, the value of the variable cannot be changed but
can be used just like any other variable.
● Example:
● const float pi = 3.14;
42. register
● Registers are faster than memory to access, so the variables which
are most frequently used in a C program can be put in registers
using register keyword.
● Syntax
register data_type variable;
● Example:
● register int i;
44. Range
Qualifier Bytes Range
short 2 -32768 to 32767
long 8 -28
to +(28
- 1)
Qualifier Bytes Range
signed int 4 -2147483648 to 2147483647
unsigned int 4 0 to 4294967295
Size Qualifiers
Signed Qualifiers
DIY: Calculate the range for long long if the size is 12 bytes
Examples:
1. char ch; // Default qualifier is implementation dependent
2. int a; // Always it is signed
48. Simple Statements
● May be expression / function call terminated by semicolon(;)
Example Description
A = 2; Assignment statement
x = a + 3; The result of (a + 3) assign to x
4 + 5; has no effect, will be discarded by
smartcompilers
; is a valid statement as it is a part of the statement, and not
just a statement terminator as in Pascal.
49. Compound Statements
And its need
● Compound statements come in two varieties: conditionals and loops.
Output?
51. Declaration
● A declaration specifies a type, and contains a list of one
or more variables of that type.
● Example
int lower, upper, step;
char ch;
Declaration is an announcement and can be done 1 or more times.
52. Definition
● A definition associates an object name with a memory.
● Example
int lower = 10;
char ch = 'A';
Definition is an actual execution and should be done exactly once.
68. Type Conversion:
Implicit
● Automatic Unary conversions
● All operands of type char & short are converted to int before any operations
● Automatic Binary conversions
●
If one operand is of LOWER RANK data type & other is of
HIGHER RANK data type then LOWER RANK will be converted
to HIGHER RANK while evaluating the expression.
● Example
If one operand is int & other is float then, int is converted to float.
69. Type Conversion:
Implicit
● Type conversions in assignments
● The type of right hand side operand is converted to type of left
hand side operand in assignment statements.
● If type of operand on right hand side is LOWER RANK data type &
left hand side is of HIGHER RANK data type then LOWER RANK will
be promoted to HIGHER RANK while assigning the value.
● If type of operand on right hand side is HIGHER RANK data type & left hand side is of
LOWER RANK data type then HIGHER RANK will be demoted to LOWER RANK while
assigning the value.
● Example
Fractional part will be truncated during conversion of float to int.
77. Relational Operators
Operator Description Associativity
>
>=
<
<=
Greater than
Greater than or equal to
Less than
Less than or equal to
L to R
==
!=
Equal
Not equal
L to R
Output ?
78. Assignment Operators
Output ?
● An assignment operator is used to assign a constant / value of one variable to
another
Output ?
79. Bitwise Operators
Opera
tor
How to read Description Example
& Bitwise
AND
Bitwise ANDing all the bits in two
operands
A = 60 = 0011 1100
B = 13 = 0000 1101
(A & B) = 12 = 0000 1100
| Bitwise
OR
Bitwise ORing all the bits in two
operands
A = 60 = 0011 1100
B = 13 = 0000 1101
(A | B) = 61 = 0011 1101
^ Bitwise
XOR
Bitwise XORing all the bits in two
operands
A = 60 = 0011 1100
B = 13 = 0000 1101
(A ^ B) = 49 = 0011 0001
~ Compliment Complimenting all the bits in given
operand
A = 60 = 0011 1100
(~A) = -61 = 1100 0011
>> Bitwise
Right shift
Shift all the bits right n times by
introducing zeros left
A = 60 = 0011 1100
(A << 2) = 240 = 1111 0000
<< Bitwise
Left shift
Shift all the bits left n times by
introducing zeros right
A = 60 = 0011 1100
(A >> 2) = 15 = 1111 0000
Bit wise operators are very powerful, extensively used in low level
programming. This helps to deal with hardware (Ex: registers)
efficiency.
80. Sizeof() Operator
Output ?
● The sizeof operator returns the size of its operand in bytes.
Output ?
The only C operators, which operate during compilation itself,
i.e. a compile-time operator
81. Sizeof() Operator...
● 3 reasons for why sizeof is not a function:
● Any type of operands,
● Type as an operand,
● No brackets needed across operands
Output ?
83. Precedence & Associativity
Of Operators
Operators Associativity Precedence
() [] -> . L - R HIGH
! ++ −− + - * & (type) sizeof∼ R - L
/ % * L - R
+ - L - R
<< >> L - R
< <= > >= L - R
== != L - R
& L - R
^ L – R
| L - R
&& L - R
|| L - R
?: R - L
= += -= *= /= %= &= ^= |= <<= >>= R - L
, L - R LOW
84. Circuit logical
operators
● These operators are similar to the & and | operators that are
applied to Boolean type
● Have the ability to “short circuit” a calculation if the result is
definitely known, this can improve efficiency
• AND operator &&
• If one operand is false, the result is false.
• OR operator ||
• If one operand is true, the result is true.
88. Run time Layout
Run-time memory includes four (or more) segments
• Text area: program text
• Global data area: global & static variables
• Allocated during whole run-time
Stack: local variables & parameters
• A stack entry for a functions
• Allocated (pushed) - When entering a function
• De-allocated (popped) - When the function returns
Heap
• Dynamic memory
• Allocated by malloc()
• De-allocated by free()
89. Details
Text Segment: The text segment contains the actual code to be
executed. It's usually sharable, so multiple instances of a program
can share the text segment to lower memory requirements. This
segment is usually marked read-only so a program can't modify its
own instructions.
Initialized Data Segment: This segment contains global variables
which are initialized by the programmer.
Uninitialized Data Segment: Also named “BSS" (block started by
symbol) which was an operator used by an old assembler. This
segment contains uninitialized global variables. All variables in this
segment are initialized to 0 or NULL pointers before the program
begins to execute.
90. Details
The Stack: The stack is a collection of stack frames which will be
described in the next section. When a new frame needs to be added
(as a result of a newly called function), the stack grows downward
The Heap: Most dynamic memory, whether requested via C's
malloc() . The C library also gets dynamic memory for its own
personal workspace from the heap as well. As more memory is
requested "on the fly", the heap grows upward
92. Storage
Class
Scope Lifetime Memory Allocation
auto Within the
block /
Function
Till the end of the block /
function
Stack
Register Within the
block /
Function
Till the end of the block /
function
Register
Static
local
Within the
block /
Function
Till the end of the program Data Segment
Static
global
File Till the end of the program Data segment
extern Program Till the end of the program Data segment
Storage Classes
93. Storage Classes...
Variable Storage Class Memory
Allocation
global No .BSS
global1 No Initialized data
segment
global2 Static global .BSS
global3 Static global Initialized data
segment
local auto stack
local1 Static local .BSS
local2 Static local Initialized data
segment
i Register Registers
96. Typedefs
● Typedef are the alternative names given to the existing names.
● Mostly used with user defined data types when names of the existing data types
gets complicated.
General Syntax:
Example:
typedef existing_name new_name
typedef unsigned long int size_t