SlideShare a Scribd company logo
1
C PROGRAMMING
AN INTRODUCTION
Arun Umrao
www.sites.google.com/view/arunumrao
DRAFT COPY - GPL LICENSING
2
Contents
1 Basic C 3
1.1 Binary Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1.1 Symbols & Charcodes . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1.2 Decimal to Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Whole Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Decimal Fraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Indexing of Binary Digits . . . . . . . . . . . . . . . . . . . . . . . 8
1.1.3 Binary To Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Whole Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Binary Fraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1.4 Memory Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.2 Formatted I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.2.1 Print & Scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
sprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
scanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.2.2 Placeholders (Modifiers) . . . . . . . . . . . . . . . . . . . . . . . . 22
1.2.3 Escape Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.2.4 Quotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.2.5 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.2.6 Range Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
1.3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.3.1 Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Character & String Variables . . . . . . . . . . . . . . . . . . . . . 33
Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Integer Casting into Char . . . . . . . . . . . . . . . . . . . . . . . 38
Real Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Float Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Double Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Long Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Long Double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Alias Data type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Declaration, Initialization & Assignment . . . . . . . . . . . . . . . 48
Float To Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Signed & Unsigned Integer . . . . . . . . . . . . . . . . . . . . . . 57
Overflow of Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Memory Size (sizeof) . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Scope of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
1.3.2 Qualifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
const Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
static Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
3
extern Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
volatile Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
auto Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
register Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
restrict Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
attribute & pragma . . . . . . . . . . . . . . . . . . . . . . . . . 81
1.4 C Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
1.4.1 Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
1.4.2 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
1.4.3 Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
1.4.4 Binary Relation Operators . . . . . . . . . . . . . . . . . . . . . . 85
1.4.5 Comma Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
1.4.6 Bitwise Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
1.4.7 Logical Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
1.4.8 Shift Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
1.4.9 Condition & Relation Operators . . . . . . . . . . . . . . . . . . . 99
1.4.10 Lexical Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . 100
1.4.11 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . 100
1.4.12 Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 103
1.4.13 Bit Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
1.5 Precedence of Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
1.5.1 Precedence of Arithmetic Operators . . . . . . . . . . . . . . . . . 114
1.5.2 Precedence of Relational Operators . . . . . . . . . . . . . . . . . . 116
1.5.3 Precedence of All Operators . . . . . . . . . . . . . . . . . . . . . . 117
1.5.4 Precedence in Assignment . . . . . . . . . . . . . . . . . . . . . . . 118
1.5.5 Unary & Binary Operators . . . . . . . . . . . . . . . . . . . . . . 118
1.5.6 Associativity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
1.6 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
1.6.1 If Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
1.6.2 If-else Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
1.6.3 If-else-if Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
1.6.4 Switch & Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
1.6.5 Goto Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
1.6.6 Break Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
1.7 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
1.7.1 For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
1.7.2 While Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
1.7.3 For As While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
1.7.4 Do While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
1.8 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
1.8.1 Character Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . 140
1.8.2 String Literal In Expression . . . . . . . . . . . . . . . . . . . . . . 140
1.8.3 String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
strcat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
strchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
strcmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
strcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
4
strlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
strncat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
strncmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
strncpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
strrchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
strstr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
strtok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
strtod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
1.9 Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
1.9.1 Function Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 157
1.9.2 Function Prototype . . . . . . . . . . . . . . . . . . . . . . . . . . 161
1.9.3 Function Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
1.9.4 Function Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
1.9.5 Function As Argument . . . . . . . . . . . . . . . . . . . . . . . . . 169
1.9.6 Function Callback . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
1.9.7 Memory Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
mmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
File Access Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
memset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
memcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
memmov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
memchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
memcmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
1.9.8 Unicode Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
1.10 Procedures & Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
1.10.1 Code Optimisation . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
1.10.2 Increments & Decrements . . . . . . . . . . . . . . . . . . . . . . . 185
1.10.3 Static Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
1.10.4 Function with Variable Arguments . . . . . . . . . . . . . . . . . . 190
1.10.5 Indirect Call of Function . . . . . . . . . . . . . . . . . . . . . . . . 192
1.10.6 Preprocessor Macros . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
#if, #else, #elif, #endif . . . . . . . . . . . . . . . . . . . . . . . . 195
#ifdef & #ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
#define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
1.10.7 Type Converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204
1.11 Parsing Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
1.11.1 Array To Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
1.12 Mathematis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
1.12.1 Trigonometric Functions . . . . . . . . . . . . . . . . . . . . . . . . 210
cos, sin & tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
acos, asin & atan . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
cosh, sinh & tanh . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212
acosh, asinh & atanh . . . . . . . . . . . . . . . . . . . . . . . . . . 213
1.12.2 Logarithm Function . . . . . . . . . . . . . . . . . . . . . . . . . . 213
Exponential & Logarithm . . . . . . . . . . . . . . . . . . . . . . . 213
5
1.12.3 Arithmetic Function . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Square Root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
Floor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
Ceiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
Rounds Off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
1.12.4 Float Point Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . 220
Operators in Float Points Arithmetic . . . . . . . . . . . . . . . . 222
Astray Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Double Floating Point . . . . . . . . . . . . . . . . . . . . . . . . . 224
1.12.5 Zero Crossing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
Limit At Zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224
1.12.6 Random Number Generator . . . . . . . . . . . . . . . . . . . . . . 225
2 Array & Pointer 227
2.1 Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
2.1.1 Uni-Dimensional Array . . . . . . . . . . . . . . . . . . . . . . . . 227
2.1.2 Multi-Dimensional Array . . . . . . . . . . . . . . . . . . . . . . . 231
2.1.3 Array of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243
2.1.4 Array in Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
2.1.5 String As Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
2.1.6 Size of Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
2.1.7 Vector & Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
2.1.8 Sparse Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
2.2 Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
2.2.1 Declaring pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
Assigning values to pointers . . . . . . . . . . . . . . . . . . . . . . 270
Pointer Dereferencing (Value Finding) . . . . . . . . . . . . . . . . 273
Addition of pointers . . . . . . . . . . . . . . . . . . . . . . . . . . 275
Passing of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
2.2.2 Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 279
Pointers to Multidimensional Arrays . . . . . . . . . . . . . . . . . 283
Pointers as Function Argument . . . . . . . . . . . . . . . . . . . . 284
Address as Function Argument . . . . . . . . . . . . . . . . . . . . 288
Pointer Equivalent to Array . . . . . . . . . . . . . . . . . . . . . . 291
2.2.3 Pointers and Text Strings . . . . . . . . . . . . . . . . . . . . . . . 295
Pointers to Function . . . . . . . . . . . . . . . . . . . . . . . . . . 297
Casting of Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . 302
Address Copying Vs Content Copying . . . . . . . . . . . . . . . . 303
2.2.4 Dangling & Wild Pointers . . . . . . . . . . . . . . . . . . . . . . . 304
2.2.5 Pointer, Variable & Address . . . . . . . . . . . . . . . . . . . . . . 305
2.2.6 Constant Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
2.2.7 Memory Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
Dynamic Memory Allocation . . . . . . . . . . . . . . . . . . . . . 312
Reallocate Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
2.2.8 Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
2.2.9 Pointer Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
6
2.2.10 Pointer to Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . 325
int *p[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
int **p[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
int (*p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
int (**p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
int *(*p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
int (*p[ ])[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
int *p(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
int (*p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
int (**p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
int *(*p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
int (*p())(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
int (*p[ ])(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
int (*p())[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345
2.2.11 Pointer Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346
2.2.12 Pointer as Structure . . . . . . . . . . . . . . . . . . . . . . . . . . 347
3 File & Data Structure 349
3.1 Input Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
3.1.1 Handling File Directory . . . . . . . . . . . . . . . . . . . . . . . . 349
3.1.2 Change Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349
3.1.3 FILE pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
Locking & Unlocking a File . . . . . . . . . . . . . . . . . . . . . . 351
Reading/Scanning Directory . . . . . . . . . . . . . . . . . . . . . 353
Open a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354
Close a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356
Reading File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364
Writing File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
Remove & Rename a File . . . . . . . . . . . . . . . . . . . . . . . 383
Resize a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
File Pointer as Function Argument . . . . . . . . . . . . . . . . . . 386
Low Level Input/Output . . . . . . . . . . . . . . . . . . . . . . . 387
3.2 Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
3.3 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
3.3.1 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
Nested Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
Structure As Arguments . . . . . . . . . . . . . . . . . . . . . . . . 408
Multi-Dimensional Struct . . . . . . . . . . . . . . . . . . . . . . . 410
Return Structure from Function . . . . . . . . . . . . . . . . . . . 414
3.3.2 Enumerate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
3.3.3 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
3.3.4 Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
Push A Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Pop A Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
Array in Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
String in Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
3.3.5 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
7
Create Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
Delete Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Update Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
Access Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426
3.3.6 Link List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Linked List (Array) . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Linked List (Pointer) . . . . . . . . . . . . . . . . . . . . . . . . . . 430
3.3.7 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437
Construction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438
Add/Insert an Element . . . . . . . . . . . . . . . . . . . . . . . . 438
Remove an Element . . . . . . . . . . . . . . . . . . . . . . . . . . 439
3.3.8 Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440
Create Tree Structure . . . . . . . . . . . . . . . . . . . . . . . . . 440
Insert Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Display Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
Delete Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
3.3.9 Binary Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445
4 Miscellaneous 447
4.1 Error Handling Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
4.1.1 clearerr function . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447
4.1.2 ferror function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
4.1.3 perror function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448
4.1.4 Segmentation Fault . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
4.2 Reserved Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
4.3 Case Sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450
4.4 Commenting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
5 Library 453
5.1 Through NetBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
5.1.1 Create Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453
5.1.2 Link Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
5.2 From Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
5.2.1 Create Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454
5.2.2 Link Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455
5.3 Load Library Dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
8 Basic C
1.1. BINARY ARITHMETIC 9
1Basic C
C is a technically low level programming and backbone of computer & information
technology. Every device has at least one part that functions on the platform of C.
Now we will study the basic functionality and procedure of C. C must be practiced by
every person who want to learn Computer Programming because C like procedure and
functions are used in all languages developed on C Platform (like Matlab, Octave, Scilab,
PHP, Java, Python, MySQL and Ruby etc). The compiler used in this book is ‘gcc’ in
‘cygwin’ environment. Algorithm is a prescription to solve a problem, which, provided it
is faithfully executed yields the result in a finite number of steps. Programming Gives a
means to translate the algorithm into a set of instructions that can be understood by the
computer.
1.1 Binary Arithmetic
A number that is formed by using digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 are called decimal
numbers. A number consists only digits 0 and 1 are called binary number. Base of decimal
number is 10, and base of binary number is 2. Some other numbers, those are used in
computers are octal and hexadecimal numbers whose base is 8 and 16 respectively. The
sequences of digits of a number system are used to form a number of that number system.
For example, sequence of digits 9, 0, 1 and 2 of decimal number system form a number
with face value 9012. Similarly, sequence of digits 1, 0, 1 and 0 of binary number system
form a number with face value 1010.
Number Digits In a number system, the distinct symbols or digits, which are used
to construct a number of the number system are called number digits of that number.
For example, in decimal form of number system, digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 are
used. In binary form of number system, digits 0 and 1 are used. Similarly, in octal form
of number system, digits 0, 1, 2, 3, 4, 5, 6 and 7 are used. And in hexadecimal number
system, digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e and f are used.
Base of Number Base of a number system is number of distinct digits present in that
number system. For example, there are ten distinct digits in decimal form of number
system. Hence its base is ‘10’. In binary form of number system, there are two distinct
digits, hence base of binary number system is ‘2’. Similarly, base of octal and hexadecimal
form of number systems are ‘8’ and ‘16’ respectively.
Place Value Place value of a digit of a number in a given number system, is digit
times to the exponent power of its place index to base of the number system. Place index
is an integer ranging from 0 to n from right to left for whole part of the number and −1
to −n from left to right for its fraction part. See the figure below:
10 Basic C
103
102
101
100
b
10−1
10−2
10−3
10−4
Figure 1.1: Place values in decimal form of number system.
In above figure, dot (·) represents to decimal symbol separating whole part from
fractional part of the given number. In decimal form of number system, the place value
at an index is 10 times larger than its right side value and 10 times lesser than its left
side value. If a given number is 213.45 then the place values of its digits are given by
2 × 102
2
1 × 101
1
3 × 100
3
b
4 × 10−1
4
5 × 10−2
5
Figure 1.2: Place values of digits of number 213.45.
In above figure, dot (·) represents to decimal symbol separating whole part (213) from
fractional part (45) of the given number 213.45.
1.1.1 Symbols & Charcodes
In human languages, symbols are scripture when pronounced by those who can identify
then gave unique sound or meaning. For example, in Hindi, character ‘ka’ gives unique
sound and meaning when it is pronounced or written by anyone. The symbols are classified
as alphabetic, numeric or special symbols etc. Alphabetic symbols are a to z, numeric
symbols are 0 to 9 and special symbols are &, #, % etc. These symbols are identified by
humans. In, computers, these symbols have no meaning. The computer communicates
using electro-magnetic waves like
t
I
A wave have two half cycles in which one is in positive y-axis side and other is in neg-
ative y-axis side. Electronic devices observe these two half cycles during communication.
The positive half cycle is denoted by ‘1’ and negative half cycle is denoted by ‘0’. Thus
all the electronic symbols are constructed by using these two digits, commonly known as
binary digits.
1.1. BINARY ARITHMETIC 11
t
I
digit 1
digit 0
In digital devices, communication waves are in square shape. Binary digits ‘1’ and ‘0’
are plotted in square wave form as shown below:
t
I
digit 1
digit 0
These two binary digits are called bits. For human machine communication, i.e.
communication between human symbols and electrics wave is done by digital coding of
the symbols. In the following table, all human readable symbols are coded from 1 to 128
with numeric base 10.
Dec Description Dec Description Dec Description
0 Null character 11 Vertical Tab 22 Synchronous idle
1 Start of Header 12 Form feed 23 End of transmission block
2 Start of Text 13 Carriage return 24 Cancel
3 End of Text 14 Shift Out 25 End of medium
4 End of Transmission 15 Shift In 26 Substitute
5 Enquiry 16 Data link escape 27 Escape
6 Acknowledgment 17 Device control 1 28 File separator
7 Bell 18 Device control 2 29 Group separator
8 Backspace 19 Device control 3 30 Record separator
9 Horizontal Tab 20 Device control 4 31 Unit separator
10 Line feed 21 Negative acknowledgement 127 Delete
Table 1.1: Non Printable Character Codes (ASCII)
12 Basic C
Dec Sym Sym Dec Sym Dec Sym Dec Sym Dec Sym Dec
32 48 0 64 @ 80 P 96 ‘ 112 p
33 ! 49 1 65 A 81 Q 97 a 113 q
34 50 2 66 B 82 R 98 b 114 r
35 # 51 3 67 C 83 S 99 c 115 s
36 $ 52 4 68 D 84 T 100 d 116 t
37 % 53 5 69 E 85 U 101 e 117 u
38 & 54 6 70 F 86 V 102 f 118 v
39 ’ 55 7 71 G 87 W 103 g 119 w
40 ( 56 8 72 H 88 X 104 h 120 x
41 ) 57 9 73 I 89 Y 105 i 121 y
42 * 58 : 74 J 90 Z 106 j 122 z
43 + 59 ; 75 K 91 [ 107 k 123 {
44 , 60 ¡ 76 L 92  108 l 124 |
45 - 61 = 77 M 93 ] 109 m 125 }
46 . 62 ¿ 78 N 94 ˆ 110 n 126 ∼
47 / 63 ? 79 O 95 111 o 127
Table 1.2: Printable Character Codes (ASCII)
In above table, each symbol is coded as decimal number and this decimal code is called
character code of the given symbol. In mathematics, numbers are convertible between
different bases. For example, decimal numbers have base ‘10’ while binary numbers have
base ‘2’. Base of a number is that count upto which numeric digits are available to con-
struct a number. For decimal numbers, there are ten digits available for construction of
numbers. Similarly for binary numbers, there are two digits; for hexadecimal numbers,
there are sixteen digits and for octal numbers there are eight digits available for construc-
tion of respective numbers. A well known number conversion is decimal to binary and
vice-versa.
During communication, when we press a symbol, it is lookup into the symbol-decimal
table. The character codes of the pressed symbol is converted into equivalent binary
number. Now, a signal wave is generated representing the binary number. This signal
wave is accepted by computer assuming that it is that symbol which was pressed by user.
To understand the above statements, we will solve few problems.
Solved Problem 1.1 Draw a plot showing binary digits ‘1’ and binary digit ‘0’ assuming
wave width for one bit as one centimeter.
Solution The plot for digits ‘1’ and binary digit ‘0’ assuming wave width one cen-
1.1. BINARY ARITHMETIC 13
timeter is shown below:
t
I
1 1
0
1
0
Solved Problem 1.2 Using the symbol-code table, find the character code of the symbols
‘c’, ‘C’ and ‘k’.
Solution From the ASCII character table, the character codes of symbols ‘c’, ‘C’ and
‘k’ are 99, 67 and 107 respectively.
1.1.2 Decimal to Binary
As computer can understood only binary numbers hence conversion of humane under-
standable numbers into computer understandable number is required. In following sec-
tions, method of number conversion is given.
Whole Integer
If decimal number is a whole decimal number then it can be converted into binary number
by dividing it by 2 and writing remainders in reverse direction. First the number is divided
by 2 and the quotients are also subsequently divided by 2 until, quotient becomes zero.
See example of conversion of (25)10 into binary number.
25/2 12/2 6/2 3/2 1/2 0
Quotient 12 6 3 1 0
Remainder 1 0 0 1 1
Bit Order ←−
Table 1.3: Decimal to binary conversion.
Now write the remainders in reverse order. The binary equivalent to the decimal 25
is
2510 = 0110012 (1.1)
Decimal Fraction
If number is in decimal fraction, then decimal to binary conversion is take place by
multiplying fraction with two and writing whole number as binary bit and fraction again
as decimal fraction. This process undergoes until fraction becomes zero or a ordered
14 Basic C
sequence is obtained. An example of binary conversion of decimal number 0.2510 is given
below.
0.25 × 2 0.5 × 2 0.0 × 2
Result 0.5 1.0 0.0
Fraction Part 0.5 0
Whole Part 0 1
Bit Order −→
Table 1.4: Decimal fraction to binary conversion.
Now write the remainders in forward order by prefixing decimal sign ·. The binary
equivalent to the decimal fraction 0.25 is
0.2510 = 0.012 (1.2)
Indexing of Binary Digits
Binary digits are used in computer science. The normal object counting is started from
1 to n if there are object other wise objects are assumed as zero or nil. But, in computer
science, the counting is started from 0 to n not from 1 to n if there are objects otherwise
objects are assumed as NULL. In computer science zero is nil and NULL is never exist.
Hence Least Significant Bit (LSB) digits is always indexed as 0 and Most Significant Bit
(MSB) digits is indexed as n − 1 in n bits binary number. The ordered counting or place
counting of binary bits in a binary number is always started from zero index.
D7 D6 D5 D4 D3 D2 D1 D0
MSB LSB
1 1 1 1 1 1 1 1
Table 1.5: 8 bits binary number. Bits are indexed from D0 to D7.
Solved Problem 1.3 Identify the D5 bit in the binary number 1101102.
Solution In the binary number 1101102, the D5 bit is bit 1. For more clarity, see the
below bits arrangement.
D7 D6 D5 D4 D3 D2 D1 D0
MSB LSB
0 0 1 1 0 1 1 0
Table 1.6: 8 bits binary number. Bits are indexed from D0 to D7.
1.1. BINARY ARITHMETIC 15
Solved Problem 1.4 Convert decimal number 124 into binary number and identify the
5th
bit or D4 bit from LSB side.
Solution In the decimal 124 on binary conversion gives 11111002. The 5th
bit or D4
bit from LSB side is bit 1. For more clarity, see the below bits arrangement.
D7 D6 D5 D4 D3 D2 D1 D0
MSB LSB
0 1 1 1 1 1 0 0
Table 1.7: 8 bits binary number. Bits are indexed from D0 to D7.
1.1.3 Binary To Decimal
Binary to decimal conversion of numbers is required to understand computer’s numerical
easily by humans. Binary to decimal conversion for whole and fraction binary number is
discussed in followings sections.
Whole Binary
Suppose we have a binary number 1010012 and it is to be converted into decimal equiv-
alent. Now we do following process in binary to decimal conversion.
1010012 = 1 × 25
+ 0 × 24
+ 1 × 23
+ 0 × 22
+ 0 × 21
+ 1 × 20
= 32 + 0 + 8 + 0 + 0 + 1
= 4110
(1.3)
In binary to decimal conversion power of base 2 increases from zero to one less in maximum
bit numbers, i.e. if there are n bits in a binary number then power of base 2 increases
from 0 to n − 1. Zero power in base, is raised in right most bit and max power is raised
in left most bit.
Binary Fraction
Suppose we have a fraction binary number 0.1012 and it is to be converted into decimal
equivalent. Now we do following process in binary to decimal conversion.
0.1012 = 1 × 2−1
+ 0 × 2−2
+ 1 × 2−3
= 0.5 + 0 + 0.125
= 0.62510
(1.4)
In binary to decimal conversion power of base 2 decreases from negative one to the negative
of bits in fraction binary number, i.e. if there are n bits in a fraction binary number then
power of base 2 decreases from −1 to −n. (−1) power in base, is raised in left most bit
16 Basic C
and (−n) power is raised in right most bit. If binary number is in compound form i.e.
11010.11012 then it can be converted into equivalent decimal number by solving whole
part and fraction part separately or by commonly. Decimal conversion in separation of
whole part 110102 and fraction part 0.11012 can done by method described above. If we
have to convert compound binary number as a whole then
1010.112 = 1 × 23
+ 0 × 22
+ 1 × 21
+ 0 × 20
+ 1 × 2−1
+ 1 × 2−2
= 8 + 0 + 2 + 0 + 0.5 + 0.25
= 10.7510
(1.5)
In above conversion, power of base 2 successively increases according to the number line
when we observe it from right to left.
Solved Problem 1.5 Using the symbol-code table, find the character code of the symbols
‘C’ and convert into equivalent binary number.
Solution The character code of symbol ‘C’ in decimal number is 67. Its binary
equivalent is 010000112.
Solved Problem 1.6 Using the symbol-code table, find the character code of the symbols
‘Z’ and convert into equivalent binary number and signal wave assuming wave width for
one bit as one centimeter.
Solution The character code of symbol ‘Z’ in decimal number is 90. Its binary
equivalent is 010110102. The equivalent signal waveform is given below:
t
I
0
1
0
1 1
0
1
0
1.1.4 Memory Storage
Binary data of computers stored in permanent memory in binary form as shown in the
following figure.
1000101000111110101011101010111010101000
This arrangement of binary digits has no meaning. This is due to mainly two reasons
(i) how many bits should be taken to reconstruct the character code which was converted
into binary digits and stored in the memory and (ii) the binary data is not readable.
It has no limiting value. To overcome these problem, binary data is grouped into fixed
number of bits. These groups are called datatypes. See the table given below:
1.1. BINARY ARITHMETIC 17
Bits Data Type Size (bytes)
1 Bit
4 Nibble
8 Byte 1
16 Short 2
32 Integer 4
64 Long, double 8
Table 1.8: Data Types.
The primary unit of memory space is byte, and each byte acts as a memory cell,
housing 8 bits data. If above memory data is arranged in bytes, then it looks like.
10001010 00111110 10101110 10101110 10101000
Though the data is arranged in cells of fixed size. But location of data is undefined.
Thus each memory cell is assigned an address which is unique location of the memory
cell.
0×51 0×52 0×53 0×54 0×55
10001010 00111110 10101110 10101110 10101000
Now we can read or write data on the memory cell which is identified by its address.
Note that, a byte is group of 8 bits, hence data types like bit and nibble are used to
access the bits within a memory cell (byte) and data types like byte, integer etc are used
to access data between the cells (bytes). Data types do not change data while reading it
from memory but they interpret it differently. For example, in the memory arrangement
0×51 0×52 0×53 0×54 0×55
10001010 00111110 10101110 10101110 10101000
if data type is byte, then it read data byte by byte. Starting from the address 0×51,
it reads binary data from one byte at address 0×51, i.e. 100010102 and convert it into
equivalent decimal number, which is 13810. Now, computer returns character symbol
whose character code is 138. Further we can read next data bytes. If data type is
integer type, then it reads four bytes at once. So, starting from the address 0×51, it
reads binary data from four bytes at once, i.e. 100010100011111010101110101011102 and
convert it into equivalent decimal number, which is 231936375810. It can not be converted
into equivalent character symbol as it is beyond the size of characters. Note that, each
variable starts reading data from its first address and it reads data upto number of bytes
which is equal to the size of the variable data type. Hence only first byte address is
important.
18 Basic C
Solved Problem 1.7 The binary data 1001010110000101010000012 is stored in memory
from the address 0×0501. A variable of short data type access this data from the address
0×0502. What will be the value assigned to this variable?
Solution The variable of short type will read data in group of two bytes.
0×0500 0×0501 0×0502 0×0503 0×0504
10010101 10000101 01000001
So, it will read two bytes data started from the address of 0×0502. The value assigned
to this variable will be 10000101010000012 in binary or in equivalent decimal 854110.
1.2 Formatted I/O
A program can received input from its console and puts result in the console after pro-
cessing. In C, printf is used to put the formatted data in output stream and scanf is
used to receive data from input stream.
1.2.1 Print & Scan
Here we will study the inbuilt functions of C which are used to take and put data from
console. Later, we construct own functions. Here is simple C program.
✞
1 /* Include header files , It have predefined functions .*/
#include <stdio.h>
3
int main (void ) {
5 /* print at console */
printf("Hello , world!n");
7
/* return true value*/
9 return 0;
}
✌
✆
When program runs, output of the program appears in console window. Here it is
✞
Hello , world!
✌
✆
In above example,
✞
1 #include <stdio.h>
✌
✆
tells to C compiler to find the standard header file stdio.h globally and include it to the
program. stdio.h contains description of standard input/output functions which we can
use to sent messages to a user or to read input from a user.
✞
1 #include <stdio.h>
#include "stdio.h"
✌
✆
1.2. FORMATTED I/O 19
If a header file is encapsulated between < and > symbols, then compiler searches the
header file in default header directory. Similarly, if the header file is encapsulated between
double quotes (“ ... ”), then compiler searches the header file in local program/project
directory.
✞
int main (void )
✌
✆
is the main function which is automatically invoked when program runs. It is also an
entry point of the program, from where a program starts running. In other words, the
mnemonic instructions of program are executed from the beginning of address of main()
function. Prefix int to main() function has meaning that main() function will return
an integer to the operating system when it is finished. Though the default return value
of main() function is integer but return value as void is also acceptable. The returns
value of main() function tells the OS about the run state of the program. On successful
complete run of the program, it returns 0 otherwise it returns error code. The compiler
shows warning when return value from the main function is not integer.
✞
1 printf("Hello , world!");
✌
✆
is the statement that actually puts the message to the screen. printf is the formatted
printing function that is declared in the header file stdio.h.
✞
1 return 0;
✌
✆
will return zero to the operating system. ‘Return of 0 is indication of successful execution
of program. Return value other than ‘0’ indicates run failure or error in execution of
program. C uses conventional code grouping structure. A function or a code block are
grouped by curly braces, ie {...}. All the variable defined inside the group {...} have local
scope. A semicolon is used to terminate the line.
✞
1 /* The main function */
int main (void ){
3 /* This is the beginning of a ‘block’*/
int i = 6; /* It is first variable of this ‘block’*/
5 { /* Start of new block. */
/* This is a new ‘block’, and because it’s *
7 * a different block it has its own scope. */
9 /* This is also a variable called ‘i’, *
* but in a different ‘block ’, because *
11 * it’s in a different ‘block’ than the *
* old ’i’, it doesn’t affect the old one!*/
13 int i = 5;
printf("%dn", i); /* Prints ‘5’ in the screen */
15 } /* End of new block. */
17 /* Now we’re back into the old block */
printf("%dn", i); /* Prints ‘6’ in the screen */
19
return 0;
20 Basic C
21 }
✌
✆
Also see the example given below.
✞
1 #include <stdio.h>
3 int main () {
int x = 1; /* Original x */
5
printf("x in outer block: %dn", x);
7 { /* Begin of new block. */
int x = 2; /* New x, hides original x */
9 printf("x in inner block: %dn", x);
} /* End of new block. */
11 printf("x in outer block: %dn", x);
for(;x < 5;x++){ /* Original x */
13 int x = 10; /* New x, hides original x */
x++;
15 printf("x in while loop : %dn", x);
}
17 printf("x in outer block: %dn", x);
return 0;
19 }
✌
✆
✞
x in outer block: 1
x in inner block: 2
x in outer block: 1
x in while loop : 11
x in while loop : 11
x in while loop : 11
x in while loop : 11
x in outer block: 5
✌
✆
printf
This function is used to print stuff in console output. Use of this function is shown in the
example given below:
✞
#include <stdio.h>
2 int main (void ) {
printf("Hello , world!n");
4 return 0;
}
✌
✆
On execusion of the program output will be looked like
✞
Hello , world!
✌
✆
1.2. FORMATTED I/O 21
sprintf
It composes a formatted string and instead printing it in console. It copies string into
buffer. It takes values of third parameter in accordance to its second parameter and
converts result into string (i.e. sequece of characters). Now, finally, the converted string
is copied into the buffer parameter. The syntax of this function is given below:
✞
1 n = sprintf (<buff >, <format >, <inputs >)
✌
✆
The size of the buffer should be large enough so that it can contain the entire resulting
string. A terminating null character is automatically appended after the content. If
formatted string is copied into buffer successfully, length of copied string is returned by
the function. On failure negative integer is returned.
✞
1 #include <stdio.h>
3 int main () {
char buffer [20];
5 int n, a = 2, b = 3;
n = sprintf (buffer , "%d * %d = %d", a, b, a * b);
7 printf("Length of string [%s] is %d.n", buffer , n);
return 0;
9 }
✌
✆
✞
Length of string [2 * 3 = 6] is 9.
✌
✆
Same example with change in format of inputs, gives completely different result.
✞
1 #include <stdio.h>
3 int main () {
char buffer [50];
5 double n, a = 2, b = 3;
n = sprintf (buffer , "%f * %f = %f", a, b, a * b);
7 printf("Length of string [%s] is %f.n", buffer , n);
return 0;
9 }
✌
✆
✞
Length of string [2.000000 * 3.000000 = 6.000000] is 30.000000.
✌
✆
Here, decimal zeros are also converted into their respective characters. In the following
example, sprintf function replaces the desired character or string with supplied character
or string. In this example recursive replacement of a character or string takes places until
all characters are replaced.
✞
1 #include <stdio.h>
#include <string.h>
3
int main (int argc , char *argv [ ]) {
5 char st [100] = "This is my string.";
22 Basic C
char r_it [2] = "s";
7 char repl [12] = "1.2";
char buffer [4096];
9 char *ch;
// printf ("b:%sn", st);
11 while (ch = strstr(st , r_it )) {
strncpy (buffer , st , ch - st);
13 // printf("d:%sn", buffer);
buffer[ch - st] = 0;
15 sprintf (buffer + (ch - st), "%s%s", repl , 
ch + strlen(r_it ));
17 if (ch != NULL )
strcpy(st , buffer);
19 }
printf("The makeup string is :n %s", buffer);
21 return 0;
}
✌
✆
✞
Thi 1.2 i1.2 my 1.2 tring.
✌
✆
This makeup of string is very useful in the mathematical computation. In algebraic
equations, the variables and constants are required to be replaced by their numerical
values.
Buffer
“Buffer” is one of the common words used in C programs. Now a question rises about the
buffer, its constitution and its applications. Buffer is specific region of memory where data
is stored temporarily for internal processes and after processes it is flushed in instream
or outstream of the system. For example, consider a small program,
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 int i, j;
i = 10;
7 j = 2*i;
return 0;
9 }
✌
✆
in which two integer type variables ‘i’ and ‘j’ stores value 10 and 20. We want to get
output be printed in output console as
✞
10,20
✌
✆
Here, first we have to store value of ‘i’ temporarily in memory but should not be
appeared in output console. For this, we have to create a memory array space of sufficient
size (here 10 bytes long).
1.2. FORMATTED I/O 23
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 char buff [10];
char tb [4];
7 int i, j;
i = 10;
9 return 0;
}
✌
✆
The memory space shall be looked like,
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49
buff
Now, store value of ‘i’ in this created memory space at the beginning of the buff
pointer.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
char buff [10];// space of 11 bytes
6 char tb [4];
int i, j;
8 i = 10;
sprintf (tb , "%d", i);// formatted string ’10’
10 strncpy (buff , tb , 4);// copy into buff from tb
return 0;
12 }
✌
✆
sprintf function converts an integer value into sequence of one byte long characters. For
example, 4 bytes long integer, i.e. ‘10’ is converted into string of characters ‘1’ and ‘0’
respectively. Note that, previously, integer ‘10’ occupies four bytes as it was an integer
value, now occupies only two bytes as it is converted into sequence of characters depicting
a strings. The memory space shall be looked like,
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49
buff
00000001 00000000
Now, store comma after the memory cell where value of ‘i’ is stored in the buffer
memory as desired output is required.
✞
#include <stdio.h>
24 Basic C
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
char buff [10];// space of 11 bytes
6 char tb [4];
int i, j;
8 i = 10;
sprintf (tb , "%d", i);
10 strncpy (buff , tb , 4);
sprintf (tb , "%c", ’,’);// append comma
12 strcat(buff , tb); // concatenate string
return 0;
14 }
✌
✆
The memory space shall be looked like,
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49
buff
00000001 00000000 00101100
Now, store value of 2 × i after the memory cell where character comma is stored in
memory.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
char buff [10];// space of 11 bytes
6 char tb [4];
int i, j;
8 i = 10;
sprintf (tb , "%d", i);
10 strncpy (buff , tb , 4);
sprintf (tb , "%c", ’,’);
12 strcat(buff , tb);
sprintf (tb , "%d", 2 * i);
14 strcat(buff , tb); // append ’20’
return 0;
16 }
✌
✆
The memory space shall be looked like,
0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49
buff
00000001 00000000 00101100 00000010 00000000
Our buffer of desired shape is generated. Now, it can be flushed into output stream
so that, it may appear in output console.
1.2. FORMATTED I/O 25
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (int argc , char ** argv ) {
char buff [10];// space of 11 bytes
6 char tb [4];
int i, j;
8 i = 10;
sprintf (tb , "%d", i);
10 strncpy (buff , tb , 4);
sprintf (tb , "%c", ’,’);
12 strcat(buff , tb);
sprintf (tb , "%d", 2 * i);
14 strcat(buff , tb);
printf("%sn", buff ); // get buffer string
16 return 0;
}
✌
✆
The desired output is
✞
10,20
✌
✆
scanf
On simplest invocation, the scanf format string holds a single placeholder representing
the type of value that will be entered by the user. scanf examines the input characters
from input stream and ignores space, tab, newline, enter and for feed characters etc.
✞
1 #include <stdio.h>
3 int main (void ) {
int a;
5 printf("Write an integer : ");
/*& operator is used to assign *
7 *address to the integer value.*/
scanf("%d", &a);
9 printf("Integer value entered is %d.n", a);
return 0;
11 }
✌
✆
Output of the programm is
✞
Write one integer value :1
Integer value passed by you is 1.
✌
✆
If a string is scanned by using scanf, ‘&’ operator is not prefixed to the character
variable. A utility program, that is not designed with printf and scanf mechanism, when
it is compiled and run then what ever is written in the output console in a line is read
and scanned by the utility. To terminate an input line in output console, enter key is
26 Basic C
pressed. To get output Ctrl+Z or Ctrl+C or Ctrl+X is pressed. If scanf is used to scan
a string or an array to the character variable ‘str’, then it is used as
✞
scanf("%s", str)
✌
✆
It is equivalent to array scanning
✞
1 scanf("%s", &str [0])
✌
✆
If the function is used like
✞
1 scanf("%s", &str)
✌
✆
then to scanf, string is passed to a pointer-to-char[256], but it points to the same place.
As scanf stops input stream when it encounters with tab, newline, enter etc. Similarly,
when scanf starts scanning a string having with white spaces then scanf stops reading
string when it encounters white space. See the example below:
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
char str [10];
5 printf("Enter string : ");
int n = scanf("%s", str);
7 printf("Status and string is :=> ");
printf("%d : %sn", n, str);
9 return 0;
}
✌
✆
✞
Enter string : arun kr
Status and string is :=> 1 : arun
✌
✆
To overcome this problem, scanf is used as
✞
scanf("%[^< input terminating character >]", <var >);
✌
✆
Here, less than and greater than signs represent beginning and ending of terminating
character. The line terminating character must be preceded by carat character ‘ˆ’ and
both should be enclosed in square braces. See the example below
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
char str [10];
5 printf("Enter string ending with ~ : ");
/* Scan the string until ~ not found.*/
7 int n = scanf("%[^~]", str);
printf("Status and string is :=> ");
9 printf("%d : %sn", n, str);
return 0;
11 }
✌
✆
1.2. FORMATTED I/O 27
The input string on console is “i am king∼” and output is printed as
✞
Enter string ending with ~ : i am king ~
Status and string is :=> 1 : i am king
✌
✆
scanf also accepts escape characters for termination of inputs. When escape character
is found by scanf, it stops scanning of inputs. See the example given below:
✞
#include <stdio.h>
2
int main (int argc , char *argv [ ]) {
4 char str [30];
printf("Enter string & press enter key : ");
6 /* Scan the string until new line *
*escape character is not found.*/
8 int n = scanf("%[^ n]", str);
printf("Status and string is :=> ");
10 printf("%d : %sn", n, str);
return 0;
12 }
✌
✆
✞
Enter string & press enter key : This is my key
Status and string is :=> 1 : This is my key
✌
✆
Another example with tab escape character, which is used as termination of input for
scanf function.
✞
#include <stdio.h>
2
int main (int argc , char *argv [ ]) {
4 char str [30];
printf("Enter string & press enter key : ");
6 /* Scan the string until tabular *
*escape character is not found.*/
8 int n = scanf("%[^ t]", str);
printf("Status and string is :=> ");
10 printf("%d : %sn", n, str);
return 0;
12 }
✌
✆
✞
Enter string & press enter key : This is my string
Status and string is :=> 1 : This is
✌
✆
Asterisk character ‘*’ when placed between the ‘%’ sign and typedef character then the
corresponding input is ignored.
✞
#include <stdio.h>
2
int main (int argc , char *argv [ ]) {
4 int i, j, k;
28 Basic C
printf("Enter three integers with spaces : ");
6 scanf("%d %d %*d", &i, &j, &k);
printf("Integers are n");
8 printf("%dt%dt%dn", i, j, k);
return 0;
10 }
✌
✆
✞
Enter three integers with spaces : 12 58 4
Integers are
12 58 0
✌
✆
As third input ‘k’ is ignored by scanf hence address of the ‘k’ variable or 0 is printed
rather than its value.
1.2.2 Placeholders (Modifiers)
Placeholders are group of symbol(s) and are used to put the values at the place of place-
holder as per specified modifiers. For example, ‘%d’ is used to put integers, ‘%ld’ for long
integers, ‘%lli’ for long long integer, ‘%f’ for float integers, ‘%lf’ for double integers, ‘%c’
for characters, ‘%s’ for strings and ‘%x’ for hexadecimal.
✞
1 #include <stdio.h>
3 int main (void ){
int i;
5 for(i = 0; i<2; i++)
printf("Integer value is %d.n", i);
7 return 0;
}
✌
✆
Output of above script is
✞
Integer value is 0.
Integer value is 1.
✌
✆
Integer can also be written in its equivalent ascii character. To do this we have to just
change the integer modifier ‘%d’ by character modifier ‘%c’.
✞
#include <stdio.h>
2
int main (){
4 int i;
for (i = 65; i <= 68; ++i){
6 printf("Integer %d is equivalent to : %c.", i, i);
printf("n");
8 }
}
✌
✆
Output of above script is
1.2. FORMATTED I/O 29
Symbolic Constant Represents
%a Floating-point number, hexadecimal digits and p-
notation.
%A Floating-point number, hexadecimal digits and P-
notation.
%c Single character.
%d Signed decimal integer.
%e Floating-point number in e-notation form.
%E Floating-point number in e-notation form.
%f Floating-point number in decimal notation form.
%g If the exponent is less than 4 or greater than or equal
to the precision %e used otherwise %f is used.
%G If the exponent is less than 4 or greater than or equal
to the precision %E used otherwise %F is used.
%i Signed decimal integer.
%o Unsigned octal integer.
%p A pointer.
%s Character string.
%u Unsigned decimal integer.
%x Unsigned hexadecimal integer using hex digits 0f.
%X Unsigned hexadecimal integer using hex digits 0F.
%% Prints a percent sign.
Table 1.9: Conversion specifiers.
30 Basic C
✞
Integer 65 is equivalent to : A.
Integer 66 is equivalent to : B.
Integer 67 is equivalent to : C.
✌
✆
In C, modifiers are used to print formatted outputs. A modifier ‘%s’ simply puts the
string by creating space equal to the length of string. If this modifier is redefined like
‘%20s’ (a positive integer between % and ‘s’ symbols), then space for 20 characters is
created. If string length is less than 20 characters then ‘ ’ (space) is prefixed to the string
to increase its length to 20. If number in modifier is less than the length of string then
nothing is done.
✞
1 #include <stdio.h>
#include <string.h>
3
int main () {
5 printf(""%s" secured numbers "%d"n", "Arun Kumar", 100);
printf(""%20s" secured numbers "%5 d"n", "Arun Kumar", 100) ;
7 return 0;
}
✌
✆
✞
"Arun Kumar" secured numbers "100"
" Arun Kumar" secured numbers " 100"
✌
✆
In case of string modifier, prefixed spaces can not be filled by any other character. In
case of numeric modifier, if a ‘.’ (ie full stop) is placed just after the ‘%’ symbol then
prefixed space is filled by ‘zero’ as shown in example below.
✞
#include <stdio.h>
2 #include <string.h>
4 int main () {
printf(""%5 s" secured numbers "%5 d"n", "Arun Kumar", 100) ;
6 printf(""%.20s" secured numbers "%.5d"n", "Arun Kumar",
100) ;
return 0;
8 }
✌
✆
✞
"Arun Kumar" secured numbers " 100"
"Arun Kumar" secured numbers "00100"
✌
✆
The same output is found when space specifier is prefixed by zero. For example,
✞
#include <stdio.h>
2
int main (void ) {
4 printf("%05dt %0.5 dn", 100, 200) ;
return 0;
6 }
✌
✆
1.2. FORMATTED I/O 31
✞
00100 00200
✌
✆
For numeric modifiers, total spaces and filled space can also be used simultaneously if
modifier is modified like ‘%10.6d’. Here number ‘10’ will create 10 spaces (field of length
10) for placing a number and if digits in number is less than ‘6’ then ‘0’ will be prefixed
with the number.
✞
1 #include <stdio.h>
#include <string.h>
3 int main () {
int i;
5 printf("%5s%10s%10sn", "Num", " Square", "Cubic");
for (i = 90; i < 92; i++) {
7 printf("%5.3 d%10.6d%10.6dn", i, i*i, i * i * i);
}
9 return 0;
}
✌
✆
✞
Num Square Cubic
090 008100 729000
091 008281 753571
✌
✆
✞
1 #include <stdio.h>
#include <limits.h> // integer limits
3 #include <float.h> // floating -point limits
5 int main (void ) {
printf("Biggest int: %dn", INT_MAX );
7 return 0;
}
✌
✆
✞
Biggest int: 2147483647
✌
✆
There are several methods of modifier conversions. Modifiers accept bits equivalent to
their size. Other bits during the modifier conversion is truncated.
✞
1 #include <stdio.h>
#define NUM 61000
3
int main (void ) {
5 printf("Num as int , short int and char : %d, %hd , %cn",
NUM , NUM , NUM);
7 return 0;
}
✌
✆
✞
Num as int , short int and char : 61000 , -4536, H
✌
✆
32 Basic C
‘+’ in placeholders prints a plus sign if the value is positive. ‘-’ causes left justify to
the result. Single Quotes (’) Separate the digits into groups as specified by the locale
specified. ‘O’ pads the field with zeros instead of spaces.
✞
1 #include <stdio.h>
3 int main (void ) {
printf("|%-10d|%10 d|%-5d|n", 500000 , -1000, 200) ;
5 printf("|%+10d|%-10d|%05 d|n", 500000 , -1000, 200) ;
printf("|%’10d|%10 d|%-5d|n", 500000 , -1000, 200) ;
7 return 0;
}
✌
✆
✞
|500000 | -1000|200 |
| +500000| -1000 |00200|
| 500000| -1000|200 |
✌
✆
There is a common error that arises from the format mismatch. for example, when we try
to print an integer as float without casting, compiler shows warning of mismatch format
and it gives strange output. See the example below:
✞
1 #include <stdio.h>
3 int main (void ) {
int a=10,b;
5 b=a/7;
printf("%f",b);
7 return 0;
}
✌
✆
✞
0.00000
✌
✆
This is why, to prevent the format mismatch error, we should either cast the variable or
should use proper variable declarations.
1.2.3 Escape Characters
Escape characters are used to perform action even if they are used as string. For example
✞
1 #include <stdio.h>
int main (void ) {
3 printf("Hello , world!n");
return 0;
5 }
✌
✆
n at the end of printf function would add a new line after “Hello world!”. The output
of the program is
✞
Hello , world!
✌
✆
1.2. FORMATTED I/O 33
Other escape characters are
Escape Character Hex Value Meaning
a 07 Add CPU alert
b 08 Backspace
t 09 Adding a tab
n 0A Start a new line
v 0B Vertical tab
f 0C Form feed
r 0D Carriage return
" 22 Double quote (”)
’ 27 Single quote (’)
? 3F Question mark (?)
 5C Backslash ()
1.2.4 Quotes
Character inside single quote (’) represents its character code in the machine. For example
‘A’ is equivalent to ‘65’ of the machine code.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
printf("%d", ’A’);
6 return EXIT_SUCCESS ;
}
✌
✆
✞
65
✌
✆
A multi-character string constants can be used inside the single quotes (‘ ’) while assigning
the value to an integer variable. First, all characters are converted into their equivalent
machine codes, then they are put in memory space one by one in their binary equivalent
form. While copying, characters are taken from the right to left direction and put in
four bytes memory space from right to left respectively (this method of computation is
machine dependent). After that, corresponding 4 bytes long binary sequence pointed by
the declared variable is converted into equivalent number and assigned to the declared
integer variable. See the example below:
✞
1 #include <stdio.h>
3 int main (void ) {
34 Basic C
/* Declare i as integer */
5 int i = ’aa’;
printf("Value of i is : %d n", i);
7 return 0;
}
✌
✆
The value ‘aa’ is stored in memory as shown below:
01100001
‘a’
01100001
‘a’
i
The decimal equivalent of binary sequence 01100001 01100001 is 24929. The output
of above program is
✞
Value of i is : 24929
✌
✆
The effective length of single quotes string is the size of data type of the declared
variable. For integer, it is four bytes. So only first four bytes of string are assigned to
variable i in the following example, rest of values are not accepted.
✞
1 #include <stdio.h>
3 int main (void ) {
/* Declare i as integer */
5 int i = ’aabb ’;
printf("Value of i is : %d n", i);
7 return 0;
}
✌
✆
Single quoted string, ‘aabb’, is stored in memory as shown below:
01100001
‘a’
01100001
‘a’
01100010
‘b’
01100010
‘b’
i
The output of above program after computing the four bytes long binary sequence is
✞
Value of i is : 1633772130
✌
✆
✞
1 #include <stdio.h>
3 int main (void ) {
/* Declare i as integer */
5 int i = ’aabbcc’;
printf("Value of i is : %d n", i);
7 return 0;
}
✌
✆
1.2. FORMATTED I/O 35
Single quoted string, ‘aabbcc’, is stored in memory as shown below:
01100001
‘a’
01100001
‘a’
01100010
‘b’
01100010
‘b’
01100011
‘c’
01100011
‘c’
i
The output of above program after computing the four bytes long binary sequence is
✞
Value of i is : 1650615139
✌
✆
Notice that, here as shown in above figure, in character to integer computation takes
only those four bytes which are started from the pointer of ‘i’. Rest are neglected. Char-
acter inside double quote (”) represents to a array of character i.e. a string.
1.2.5 Comments
Commenting is most useful feature of the C programming. It is used to write comments
before or after a function or variable. Stuff within the commenting delimiters is ignored
during compilation of the program. There are two type of commenting delimiters. First,
single line commenting delimiter and second, multi-line commenting delimiter. For single
line commenting ‘//’ is used and for multi-line commenting ‘/* ... */’ is used.
✞
1 #include <stdio.h>
int main (void ) {
3 /* Here printf prints string multiple times.*
*Loop is used for multiple output lines. */
5 for(ix =1; ix <=2; ix ++){
printf("%d - Hello , world!",ix);
7 }
return 0;
9 }
✌
✆
The output of above program is
✞
1 - Hello , world!
2 - Hello , world!
✌
✆
1.2.6 Range Operator
C language supports declaration of range by using ‘...’ operator. For example, range
from 1 to 10 is declared as “1 ... 10”. The range operator may be used either with case
statement or in definition of the function arguments. See the example below:
✞
#include <stdio.h>
2
int main () {
4 int i = 5;
switch (i) {
6 case 1 ... 10:
36 Basic C
printf("Within range from 1 to 10. n");
8 break;
default :
10 printf("Not supposed .n");
break;
12 }
}
✌
✆
✞
Within range from 1 to 10.
✌
✆
1.3 Variables
Variables are multicharacter names used to refer to some locations in memory that holds
a value to which we are working. Variables are multicharacter names used to refer to
some locations in memory that holds a value to which we are working. A data type is
type of data that can be assigned to a variable. We know that data is stored in memory
in groups, commonly known as bytes. When a small number like, 20 or 30 is stored, it
consumes hardly one byte as they are binary equivalent to 10100 or 11110 respectively.
So, data can be easily read or write in the data memory byte.
0×20 0×21 0×22 0×23 0×24
00010100 00011110
i = 20 i = 30
If number is large, say 1024, then it needs two bytes memory space as it is binary
equivalent to 10000000000, which is spread between two bytes.
0×20 0×21 0×22 0×23 0×24
00000100 00000000
i = 1024
In C, to deal with this data span, grouping of memory bytes is allowed. This grouping
is called data type. For example, single memory byte is said as character data type.
Group of two bytes is called short data type, group of four bytes is called integer data
type etc. Grouping of bytes is fixed to maintain system independent uniformity and as
the number of bytes in a group increases, group able to store larger binary data. Note
that, data in each type of group is read and write at once. For example, binary data
101100010111010001010 spread in three bytes.
0×20 0×21 0×22 0×23 0×24
00110110 00101110 10001010
i = 9842186
1.3. VARIABLES 37
If this is integer type data then each time all these bits are read at once and will be
converted into decimal number which is 9842186. Any data type does not allow partial
read or write of data. The datatypes in C are char-one byte long, int-four bytes long,
float-four bytes long and double-eight bytes long. long data type is used to change the
byte length of float and double. The derived datatypes are arrays, structure, pointer,
function etc. The short, long, signed and unsigned are used as type modifier. Variables
are not values by itself but points to values. A variable is equivalent to its assigned value.
A variable may be alphanumeric name with underscore character. First numeric character
of a variable name is not acceptable. Spaces and special characters which are reserved
for internal operations of C are illegal. Similarly, use of comma, dot, symbol of question
mark, symbols reserved for relation operations, symbols reserved for bitwise operations,
colon and line terminating symbol are also considered as illegal if used in variable names.
Key words specially reserved for internal programming of C, can not be used like variable
name. A list of reserved keyword is given in section 4.2.
✞
1 int A1; // Legal and acceptable .
int 1A; // Illegal , first character is numeric
3 int A_1;// Legal , _ is acceptable
int A$1;// Legal , $ is not reserved character
5 int A#1;// Illegal , # reserved for header inclusion
int A 1;// Illegal , space is not acceptable
7 int for;// Illegal , for is reserved keyword
✌
✆
A variable declared once can not be re-declared again within the same scope. Scope of
a variable is segment of a code, from where variable is accessible. By default, a local
variables get garbage value and global variables get a value 0 by default on declaration.
Sometime, words, “argument” and “parameter” are used in the C programming. The
word “argument” denotes the value that is passed to a function whereas word “parameter”
denotes the name by which the value is referred to in the body of the function.
1.3.1 Address
A most commonly used word in C programming is ‘address’. By definition, “address” is
the location of memory where either data is stored or from where data is retrieved. An
address is a multibytes value that refers to a certain memory location rather than the
value stored at that location. Take a memory map of matrix 10 × 8 size as shown below:
11 12 13 14 15 16 17 18
21 22 23 24 25 26 27 28
31 32 33 34 35 36 37 38
41 42 43 44 45 46 47 48
51 52 53 54 55 56 57 58
61 62 63 64 65 66 67 68
0×00 0×01 0×02 0×03 0×04 0×05 0×06 0×07
Low bytes
0×00
0×01
0×02
0×03
0×04
0×05
High
bytes
Here, memory addressed are two bytes long and it depends on system to system. The
38 Basic C
first byte represents to high byte (i.e. rows in above matrix) and second byte represents
to low byte (i.e. column in the above matrix). For example an address 0×0304 represents
to the memory cell at 4th
row and 5th
column. This value indicates to location of memory
not to value at that location. From the above matrix, at 4th
row and 5th
column cell,
value stored is 45 not 0×0304 (address). In C we do not deals directly with addresses but
a variable name is assigned to the address. For example, if a variable
✞
1 int i = 45;
✌
✆
is declared and assigned a value equal to encircled value in above memory matrix. For
this value, address of variable ‘i’ shall be 0×0304. Address assigned to variable is always
hidden and can be retrieved by using addressof (‘&’) symbol.
✞
1 #include <stdio.h>
3 int main () {
unsigned int i=45;
5 printf("%x", &i);
return 0;
7 }
✌
✆
✞
0304
✌
✆
Here address variable is of 2 bytes long. Note that address of operator can not be used
with constants and variable that is declared using register storage class. A question rises
here that why address is assigned to a variable not the value itself. Its answer is, value
assigned to variable is of any size and for long values, it is impossible to assign directly
to the variable. This is why, pointers or variables are let to point the address the first
byte of the memory location where data is stored.
0×00 0×01 0×02 0×03 0×04 0×05 0×06 0×07 0×08 0×09
Low bytes
0×00
0×01
0×02
0×03
0×04
0×05
High
bytes
T w o P e n s 0
Str
Assume a variable ‘Str’ which is assigned a string “Two Pens”. This is eight bytes
long data. So a variable can not store this data directly. Therefore, the string is stored in
the temporary memory as shown in above figure. The variable ‘Str’ points to first byte
of the string, i.e. to ‘T’. The scope of ‘Str’ variable ended at the next null char ‘0’. The
memory address of ‘T’ is 0×0201. Hence, variable ‘Str’ points to memory address 0×0201
from where the string started and ‘Str’ does not points to the string itself.
1.3. VARIABLES 39
Character & String Variables
char is used to initialize a character or character string. A char data type variable which
can be initialized only for one character is declared and initialized as
✞
1 /* Declaration .*/
char c;/* Char variable one byte long */
3 /* Declaration & Initialization .*/
char c=’K’;/* Single quote one byte long value.*/
✌
✆
Character string can be initialized as an array or pointer. The size of char data type is 1
byte. In following figure, the memory byte B[3] is reserved for character variable c (value
stored at this memory byte is K) and memory byte B[4] is reserved for character variable
s (value stored at this memory byte is L).
B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11]
K L
c s
In case of character string, as shown in the syntax given below,
✞
char *s="abcd ";
✌
✆
variable s is a pointer and points to the address of first element, i.e. ‘a’ of the string
“abcd”.
B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11]
a b c d
s
The memory location used to store this string is from B[5] to B[8]. B[5] stores to first
character, ‘a’ of the string, B[6] stores to second character, ‘b’ of the string, B[7] stores
to third character, ‘c’ of the string and B[8] stores to fourth character, ‘d’ of the string.
By default, a char is signed unless unsigned keyword is not used.
✞
1 /* Group of characters in double quotes , i.e. string */
char *<var name >="This is string.";
3 char <var name >[ ]="This is string.";
✌
✆
✞
1 #include <stdio.h>
3 int main () {
/* Single quote to single char .*/
5 char c = ’a’;
/* Double quote to single char .*/
7 char ch [2] = "b";/* String size is 2. One byte for b*
*and one byte for null terminator */
9 char *s = "This is my string.";/* Pointer to string.*/
40 Basic C
printf("c is %cn", c); /* Print char */
11 printf("ch is %sn", ch);/* Print string*/
printf("s is %sn", s); /* Print string.*/
13 return 0;
}
✌
✆
✞
c is a
ch is b
s is This is my string.
✌
✆
A single character when it is in single quote is consider as a character while the same
character when is in double quote, it is considered as a string. A group of characters has
string length, equal to one more to the number of character. The last byte of string is for
string terminator ‘0’. A char variable without initialization stores null character.
✞
1 #include <stdio.h>
3 int main () {
/* Declare char variable . Not initialized .*/
5 char *ch;
printf("Value of ch : %sn", ch);
7 return 0;
}
✌
✆
✞
Value of ch : (null )
✌
✆
The null terminator terminates a string. Value to a character data type may be assigned
by two ways. One, by using bymbol and other by using equivalent character code. See
the example below:
✞
1 #include <stdio.h>
3 int main () {
char c[5], s[5];
5 c[0]=0; /* Assign null character by*
* using char code value. */
7 printf("%s",c);
s[0]= ’0’; /* Assign null character by *
9 * using single quoted symbol.*/
printf("%s",s);
11 return 0;
}
✌
✆
Output of above program is null or empty string. See another example, in which character
array is initialized with empty string (NOT NULL). Remember that ‘0’ and “0” are both
same as single backslash is used to represent escape characters. To print the backslash
symbol at output stream, it is used in double, i.e. “”.
✞
#include <stdio.h>
1.3. VARIABLES 41
2
int main () {
4 char c[5], s[5], s2 [5];
c[0]=0; // Assign null char by using char code value.
6 printf("%s",c);
s[0]= ’0’; // Assign null char by using single quoted symbol.
8 printf("%s",s);
s2 [0]= "0";/* Assign null character by using double *
10 *quoted backslash and 0 (escape character ).*/
printf("%s",s2);
12 return 0;
}
✌
✆
NULL or empty string is also represented by “” (nothing within double quote symbols).
✞
1 #include <stdio.h>
3 int main () {
/* Variable initialized with EMPTY value.*/
5 char *ch = "";
/* Prints empty character .*/
7 printf("ch as character : %sn", ch);
9 /* Prints integer value. Here empty character has *
*charcode 0. It is not ZERO char of charcode 48.*/
11 printf("ch as integer : %dn", *ch);
return 0;
13 }
✌
✆
✞
ch as character :
ch as integer : 0
✌
✆
Though the compiler assigned dynamically available memory address to the pointer type
variable declaration, yet we can assign designated address to the variable as shown below:
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main () {
char value = *( char *)0xA0008;
6 printf("%c", value);
return 0;
8 }
✌
✆
The output of this program may or may not correct and depends on platform and mostly,
it returns “Segmentation Fault (SIGSEGV)” error. To read data from allowed memory
address and desired result, see the following example.
✞
#include <stdio.h>
2 #include <stdlib.h>
42 Basic C
4 int main (int argc , char ** argv ) {
char x[20] = "This is my string";
6 printf("Char at address of x is :%cn", *x);
printf("Char at address of (x + 1) is :%cn", *(x + 1));
8 printf("Char at address of (x + 2) is :%cn", *(x + 2));
printf("Address of x is :%xn", x);
10 /*In my machine , address of x is 0x22cd40 */
printf("Char at address of (0 x22cd40 +0x1) is :%cn", 
12 *( char *) (0 x22cd40 + 0x1));
return (EXIT_SUCCESS );
14 }
✌
✆
✞
Char at address of x is :T
Char at address of (x + 1) is :h
Char at address of (x + 2) is :i
Address of x is :22 ccb0
Char at address of (0x22 cd 40+0 x1) is :h
✌
✆
NULL (0), a Magic Symbol Let we have a special file which contains our secret
passphrase, keywords including secret passwords. When this file is deleted, only name
variable, that points to the address of the file data, is removed from the file table. Data
stored in permanent memory remains intact. If someone scan the whole memory of the
storage device, he may able to retrieve your secret passphrase or passwords. Then, how
do we make a safe removal of the data file? We can do it my flushing file data with 0
(NULL character) by mapping whole file (using mmap function) in the memory before
its removal. Now, if anyone scan the storage memory, he will get only garbage data.
✞
1 #include <stdio.h>
#include <stdlib.h>
3 #include <sys/mman .h>
#include <fcntl.h>
5
int main (int argc , char *argv []) {
7 int fd , i;
char *data ;
9 if ((fd = open ("a.txt", O_RDWR)) == -1) {
printf("Unable to open file .n");
11 return 1;
}
13 /* Put mmap in loop for large size file mapping */
data = mmap (0, 1024, PROT_READ |PROT_WRITE , MAP_SHARED , fd , 0);
15 if (* data == -1) {
printf("Unable to map file .n");
17 return 1;
}
19 for(i=0; i < 1024; i++)
data [i]=’0’; // replace data with garbage
21 return 0;
}
1.3. VARIABLES 43
✌
✆
Now open and see the experimental file.
Integers
A 4 bytes long numerical value can be declared and initialized by using int data type. In
following figure, bytes B[3] to B[6] are reserved for storing integer value assigned to the
integer variable i and B[7] to B[10] are reserved for storing integer value assigned to the
integer variable j.
B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11]
xxxx xxxx xxxx xxxx yyyy yyyy yyyy yyyy
i j
When a real number is initialized to a integer variable, then its fraction part is trun-
cated. A valid integer type is either a whole number of a whole number with suffix ‘L’.
An integer variable is declared and initialized as shown below:
✞
int <var name >; /* Declared .*/
2 int <var name >=<value >; /* Initialized .*/
✌
✆
An example is given below:
✞
#include <stdio.h>
2
int main () {
4 int i = 10;
int iL = 11L;
6 int j = 12.5;
/* Print whole integer i.*/
8 printf("i : %dn", i);
/* Print whole integer iL.*/
10 printf("iL : %dn", iL);
/* Truncated to decimal part of j.*/
12 printf("j : %dn", j);
return 0;
14 }
✌
✆
✞
i : 10
iL : 11
j : 12
✌
✆
Similarly, if a double or float number is casted as integer then again its decimal part is
truncated. Remember float number larger than that of size of integer cause overflow.
✞
1 #include <stdio.h>
3 int main () {
44 Basic C
double i = 10.25;
5 float j = 12.75;
printf("i : %dn", (int) i);
7 printf("j : %dn", (int) j);
printf("j as float : %fn", (int) j);
9 return 0;
}
✌
✆
✞
i : 10
j : 12
j as float : -0.000000
✌
✆
Note that, prepend zeros in the values of integer type variables, cast the values into octal
number form. In C, prepend zeroes has significant meaning here.
✞
1 #include <stdio.h>
3 int main () {
int a = 010; // Declare & assign octal 010 to variable a
5 a = a + 10; // Ouput is a = 10 + 8 = 18 in decimal .
printf("%d", a);
7 return 0;
}
✌
✆
✞
18
✌
✆
Here, output is decimal 18 and octal 010 is equivalent to decimal 8. Therefore, be cautious
while using prepend zeros in the numeric values.
Integer Casting into Char
Here is a question that how a numerical value is stored as integer and as string and what
is different in these two storing modes. For example, assume a numeric value 62, which
is to be stored as integer and as string. The numeric value 62, as integer, it is equal to
binary value ‘00111110’ and it is stored in the first byte of four byte long storage memory
allocated for integer variable.
✞
1 #include <stdio.h>
3 int main () {
int i = 62; /* Four byte long data type */
5 /*x Point to first byte of address of i*/
char *x = (char *) &i;
7 printf("First byte %dn", x[0]) ;
printf("Second byte %dn", x[1]) ;
9 printf("Third byte %dn", x[2]) ;
printf("Fourth byte %dn", x[3]) ;
11 return 0;
}
✌
✆
1.3. VARIABLES 45
✞
First byte 62
Second byte 0
Third byte 0
Fourth byte 0
✌
✆
In this case, numeric value is stored as integer needs only one byte (as numeric value is
small) of four bytes allocated memory for integer variable. Remember that, an integer is
four bytes long data.
x[3] x[2] x[1] x[0]
i :
Value at byte :
Pointer x :
00000000 00000000 00000000 00111110
0 0 0 62
62 is small number hence it is accommodated in one byte. If this value is larger then
it need two or more bytes to store it. Assume a number 12345. In binary form, it is
“110000 00111001” and accommodated in 4 bytes long memory as shown below:
x[3] x[2] x[1] x[0]
i :
Value at byte :
Pointer x :
00000000 00000000 00110000 00111001
0 0 48 57
✞
#include <stdio.h>
2
int main () {
4 int i = 12345; /* Four bytes long */
/*x Point to first byte of address of i*/
6 char *x = (char *) &i;
printf("First byte %dn", x[0]) ;
8 printf("Second byte %dn", x[1]) ;
printf("Third byte %dn", x[2]) ;
10 printf("Fourth byte %dn", x[3]) ;
return 0;
12 }
✌
✆
✞
First byte 57
Second byte 48
Third byte 0
Fourth byte 0
✌
✆
In image processing, the image data is written byte by byte as group of two, three, four or
more bytes. Four bytes long integers are also written as byte by byte while they are read
as four byte long data. Therefore, pointing to an integer as character by character has
great significance in image processing. Now, in the case, when 62 is stored as a group of
characters, i.e. in form of string, it becomes “62” (a group of character “6” and character
“2”).
46 Basic C
✞
#include <stdio.h>
2
int main () {
4 char *s = "62"; /* Two bytes long */
char *x = s; /* Points to first byte .*/
6 printf("First byte : %d=’%c ’n", x[0], x[0]) ; /* Char code of 6*/
printf("Second byte : %d=’%c ’n", x[1], x[1]) ; /* Char code of 2*/
8 return 0;
}
✌
✆
✞
First byte : 54=’6’
Second byte : 50=’2’
✌
✆
Here, the numeric value 62, is stored as string “62”, it needs two bytes long memory.
One byte for character ‘6’ (char code 54, binary equivalent to 00110110) and one byte for
character ‘2’ (char code 50, binary equivalent to 00110010).
x[0] x[1]
s :
Value at byte :
Pointer x :
00110110 00110010
6 2
This is the main difference in storage of integers and strings in computer memory.
Note that the same binary data in a memory byte has different meaning for different data
type. For example, binary value 00110010 is equal to symbol ‘2’ (numeric digit two) for
character data type. The same binary value is equal to number ‘50’ (equal to char code)
for integer data type. Thus each data type has different way of reading and interpreting
binary data.
Little Endian & Big Endian Little and big endian are two ways of storing multibyte
data, i.e. int, float, etc. In little endian machines, least significant byte of binary rep-
resentation of the multibyte data is stored first, i.e. at lowest address of the memory.
In big endian machines, most significant byte of binary representation of the multibyte
data is stored first, i.e. at lowest address of the memory. For example, a multi byte data
12D589A116 is written in the machine as big endian as shown in the following table
Address Value
1000 12
1001 D5
1002 89
1003 A1
The same multibyte data is written in the machine as little endian as shown in the
following table
1.3. VARIABLES 47
Address Value
1000 A1
1001 89
1002 D5
1003 12
The program that can check the machine as little endian or big endian is given below:
✞
#include <stdio.h>
2
int main (void ) {
4 int *T;
6 T = (int *) " 01000000000000000";
if (*T == 1)
8 printf("Machine is High -Endian .n");
else
10 printf("Machine is Low -Endian .n");
return 0;
12 }
✌
✆
According to this program, my machine is
✞
Machine is High -Endian.
✌
✆
Real Numbers
A real number has decimal point. Thus 12.0 and 12 are not equal characteristically but
they are equal numerically. In C, some operators like modulo, left and right shift, etc do
not work with real numbers. In the following example, modulo of 12 by 5 is 2.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 printf("12 %% 5 = %d n", 12 % 5);
return (EXIT_SUCCESS );
7 }
✌
✆
✞
2
✌
✆
But in the following example, there is error.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
48 Basic C
int main (int argc , char ** argv ) {
5 printf("12.0 %% 5 = %d n", 12.0 % 5);
return (EXIT_SUCCESS );
7 }
✌
✆
The reason behind these difference is treatment of value 12, i.e. how the bits of memory
bytes stored 12 or 12.0 are grouped, interpreted and converted into numbers. In first
case, it was an integer and all bits in four bytes of integer data type were part of the
integer value. But in above code, 12.0 is a float type values. The bits in four bytes float
data type are treated differently. Few bits are used as mantissa and rest are used for
characteristics. Similarly, left or right bit shift operator do.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (int argc , char ** argv ) {
5 printf("12.0 << 5 = %d n", 12.0 << 5);
return (EXIT_SUCCESS );
7 }
✌
✆
Above code shows error. In left bit shift or right bit shift of real numbers, mentisaa and
characteristics bits trespass each others places. This is why, some operators are illegal
with real numbers.
Float Decimals
This data type is floating-point type. It usually referred to as a single-precision floating-
point. Float-to-integer or integer-to-float type conversion of numbers take place by casting
the number. It is 4 byte long. Its range varies from 1.2×10−38
to 1.2×1038
. The precision
of the float data type is upto 6 decimal places. Syntax for the float data type is
✞
1 float <var name >;
float <var name >=< decimal value >;
✌
✆
See the example below.
✞
#include <stdio.h>
2
int main () {
4 float i = 10.25;
int j = 15;
6 printf("i as float : %fn", i);
printf("i as integer : %dn", (int) i);
8 printf("Int j as float : %fn", ( float) j);
return 0;
10 }
✌
✆
✞
i as float : 10.250000
i as integer : 10
Int j as float : 15.000000
✌
✆
1.3. VARIABLES 49
A floating point is represented in scientific notation form by using ‘e’ (here ‘e’ is exponent
and is equivalent to ‘10’) as
✞
1 float 125e-n
float 125e+n
✌
✆
A positive power ‘+n’ shifts the decimal point from left to right and negative power ‘–
n’ shifts the decimal point from right to left. For example, −12345e + 5 in C notation
is equivalent to −12345 × 10+5
in mathematics. Similarly, 12345e − 5 in C notation is
equivalent to 12345 × 10−5
in mathematics. See the example given below:
✞
#include <stdio.h>
2
int main () {
4 float i = -12345e+5;
float j = 12345e-5;
6 printf("i is %f n", i);
printf("j is %f n", j);
8 return 0;
}
✌
✆
✞
i is -1234499968.000000
j is 0.123450
✌
✆
A float is 32 bits long and has three components, (i) a sign bit (first bit from left side),
(ii) exponent (next 8 bits from left side) and (iii) mantissa (rest of 23 bits). A floating
point number is written as
f = ±m × b±e
Here, m is mantissa of the number, b is base either ‘10’ or ‘e’ or ‘2’ and n is exponent of
the floating type number. In computers, the base is ‘2’.
Double Decimals
This data type is floating-point type. It usually referred to as a double-precision floating-
point. Double-to-integer or integer-to-double type conversion of numbers take place by
casting of the number. It is 8 bytes long. Its range is from 2.3 × 10−308
to 2.3 × 10308
.
The precision of the double data type is upto 15 decimal places. Syntax for the double
data type is
✞
double <var name >;
2 double <var name >=< decimal value >;
✌
✆
See the example below.
✞
#include <stdio.h>
2
int main () {
4 double i = 10.25;
printf("i as double : %fn", i);
50 Basic C
6 printf("i as integer : %dn", (int) i);
return 0;
8 }
✌
✆
✞
i as double : 10.250000
i as integer : 10
✌
✆
A double is 64 bits long and has three components, (i) a sign bit (first bit from left side),
(ii) exponent (next 11 bits from left side) and (iii) mantissa (rest of 52 bits). A double
point floating point number is written as
f = ±m × b±e
Here, m is mantissa of the number, b is base either ‘10’ or ‘e’ or ‘2’ and n is exponent
of the floating type number. In computers, the base is ‘2’. double data type is preferred
over float in numerical programming to avoid variance and kept precision in results.
✞
#include <stdio.h>
2
int main () {
4 printf("%fn", (float) 343434333.98) ;
printf("%fn", (float) 545454323.31) ;
6 printf("%fn", (double) 343434333.98) ;
printf("%fn", (double) 545454323.31) ;
8 return 0;
}
✌
✆
✞
343434336.000000
545454336.000000
343434333.980000
545454323.310000
✌
✆
Long Decimals
long is long integer type. It is capable of containing any integer value within the range
from 2147483647 to +2147483647. It is a 32 bits or 4 bytes long in size. Long-to-integer
or integer-to-long type conversion of numbers is done by casting.
✞
long <var name >;
2 long <var name >=< decimal value >;
✌
✆
See the example below.
✞
#include <stdio.h>
2
int main () {
4 long i = 10.25;
int j = 15;
1.3. VARIABLES 51
6 printf("i as long : %ldn", i);
printf("i as integer : %dn", (int) i);
8 printf("Int j as long : %ldn", (long ) j);
return 0;
10 }
✌
✆
✞
i as long : 10
i as integer : 10
Int j as long : 15
✌
✆
Long Double
It is 10 bytes long data type. Its range is from 3.4×10−4932
to 3.4×104932
. The precision
of the long double data type is upto 19 decimal places. Syntax for the long double data
type is
✞
1 long double <var name >;
long double <var name >=< decimal value >;
✌
✆
The example is
✞
#include <stdio.h>
2
int main (void ) {
4 long double x = -5.32e-5;
printf("x = %LEn", x);
6 return 0;
}
✌
✆
✞
x = -5.320000 E-05
✌
✆
Alias Data type
typedef is used to create an alias name for any other data type. As such, it is often
used to simplify the syntax of declaring complex data structures consisting of struct and
union types, but is just as common in providing specific descriptive type names for integer
datatypes of varying lengths. The syntax of typedef is given by
✞
1 typedef <old type name > <new alias >;
✌
✆
Redefining the long long data type with new variable as given below.
✞
1 typedef long long <major unit >;
typedef int <minor unit >;
✌
✆
An example is given below.
52 Basic C
✞
#include <stdio.h>
2
typedef long long km;
4 typedef int mm;
6 int main (void ) {
km dis = 10;
8 printf("Distance is %d km.n", dis);
return 0;
10 }
✌
✆
✞
Distance is 10 km.
✌
✆
typedef can also be used to define alias names to a structure. See the example given
below:
✞
1 #include <stdio.h>
3 typedef struct Coord {
int x;
5 int y;
} c;
7
int main () {
9 c coord1 = {2, -5}; // Assign default values
c coord2 = coord1; // Copy coord1 into coord2
11 printf("%d", coord2.y); // get value
return 0;
13 }
✌
✆
✞
-5
✌
✆
Always remember that, alias names created by using typedef keyword, are used to create
new instances of structure. They do not act as instances themselves. So, accessing the
elements of a structure, as given in above example, like
✞
1 c.x;
c.y;
✌
✆
are invalids and give compile time error.
Boolean
C has no dedicated boolean variable. Hence a comparison between variable and return
value can not be performed. In C, the true and false numeric values are depend on the
implementation concepts by the program writer. For example, if two strings are exactly
same, then their comparison by strcmp() function is true and it returns ‘0’. It returns any
number if two strings are not exactly same, i.e. the false case. Similarly, scanf returns
1.3. VARIABLES 53
1 if it success to scan a value according to modifiers otherwise 0 on failure. So, we can
say that boolean returned values are dependent to success or error or failure states or
implementation of user’s function. In following example, we check whether there are
spaces in a string or not.
✞
#include <stdio.h>
2 /* Space function . */
/* Return 0 if no spaces otherwise > 0.*/
4 int has_space (char *s) {
int num = 0;
6 while (*s++ != ’0’) {
if (*s == ’ ’) {
8 num ++;
}
10 }
return num;
12 }
14 int main (int argc , char ** argv ) {
char *s = "This is pen.";
16 printf("Spaces : %dn", has_space (s));
return 0;
18 }
✌
✆
In concept implementation, function has space() returns the number of space occurring
in the string. It means, if return value is ‘0’ then there are no spaces in the string. Other
positive integer values tells the number of spaces in the string. It means presence of space,
i.e. true state has any positive integer value while false state has ‘0’ value. In following
example, a totally different concept implemented for return value for true or false state.
✞
#include <stdio.h>
2 /* Return 0 if only numeric otherwise > 0.*/
int is_only_numeric (char s[ ]) {
4 int num = 0, i = 0;
while (s[i] != ’0’) {
6 if (s[i] < 48 || s[i] > 59) {
num ++;
8 }
i++;
10 }
return num;
12 }
14 int main (int argc , char ** argv ) {
char *s = "341";
16 printf("Numeric only : %dn", is_only_numeric (s));
return 0;
18 }
✌
✆
In above function, return value is zero, if string has only numeric digits ranging from 0
to 9. If there are other characters or symbols, the return value is greater than zero. The
54 Basic C
type comparison like
✞
if(has_space (s) == 0)
✌
✆
shall be true if there are no spaces in string ‘s’. Again, the type comparison like
✞
1 if(has_space (s) > 0)
✌
✆
shall be true if there are spaces in string ‘s’. But
✞
1 if(has_space (s) != 0)
✌
✆
can’t be implemented. Boolean in C depends on implementation and varies from library
to library. In mathematics library, true is any number while false is zero.
✞
1 #include <stdio.h>
3 int main () {
int b = 2, c = 3;
5 printf("%dn", (c > b)); // true case
printf("%dn", (c < b)); // false case
7 return 0;
}
✌
✆
✞
1
0
✌
✆
Declaration, Initialization & Assignment
A variable in C can be assigned as integer, if syntax is defined as given below:
✞
int variable_name ;
✌
✆
It means there is some space declared somewhere to store integer value. Multiple variables
can be assigned in single line or successive way like
✞
1 int variable_a , variable_b , variable_c ;
✌
✆
A variable in C is said to be initialized if a numeric or an alphabetic value is assigned to
it. For example variable a is initialized by
✞
1 int variable_a = <value >;
✌
✆
To distinct the words of a variable, underscore symbol (‘ ’) is used. Anytime within a
program in which we specify a value explicitly instead of referring to a variable or some
other form of data, that value is referred as a literal. Literals can either take a form
defined by their type, or one can use hexadecimal (hex) notation to directly insert data
into a variable regardless of its type. Hex numbers are always preceded with ‘0×’. There
1.3. VARIABLES 55
are five major datatypes which are given in the following table. C also allow suitable
combinations of numeric datatypes for long numerical values.
Data type Meaning
int Integer
char Character
long Long integer
float Floating data with single digit precision
double Floating data with double digit precision
The length of data type is measured its byte length. The data type may be signed or
unsigned. In signed data type, the MSB is used for sign declaration and rest of the bits
are used for data value. In unsigned data type, all the bits are used for data value. The
byte length of different data type are given in following table.
Type Storage size Format Specifier
char 1 byte %c
un-signed char 1 byte %c (%hhu for numerical output)
signed char 1 byte %c (%hhi for numerical output)
int 2 or 4 bytes %i or %d
unsigned int 2 or 4 bytes %u
unsigned short 2 bytes %hu
short 2 bytes %hi
long 4 bytes %li
unsigned long 4 bytes %lu
long long 8 bytes %lli
long long int 8 bytes %lli or %Ld
unsigned long long 8 bytes %llu
double 8 bytes %f
long double 10 bytes %Lf
Table 1.10: Declaration type and their storage size in byte.
Example, that scans a 8 bytes long integer by using ‘%Ld’ format specifier.
✞
1 #include <stdio.h>
56 Basic C
3 int main (){
long long int a;
5 scanf("%Ld" ,&a);
if(a%6==0 || a%6==1 || a%6==3){
7 printf("YES");
}else {
9 printf("NO");
}
11 return 0;
}
✌
✆
✞
2154478958845
YES
✌
✆
Example for long double data type.
✞
#include <stdio.h>
2 #include <math .h>
4 int main () {
long double x;
6 printf("%lfn",pow (2 ,50));
return 0;
8 }
✌
✆
✞
1125899906842624.000000
✌
✆
Sometime, variables are declared but not initialized and further used. Integer type data
variables if declared as static or global, they store zero by default.
✞
1 #include <stdio.h>
3 int main () {
int i;
5 printf("%dn", i);
return 0;
7 }
✌
✆
✞
0
✌
✆
Though, the non-initialized integers are zero by default, yet the initialization of integer
variables are required. If not initialized, the result is garbage.
✞
1 #include <stdio.h>
3 int main () {
int i;
5 int j;
while (i < 5) {
1.3. VARIABLES 57
7 j = i + j;
i++;
9 }
printf("i:%d, j:%dn", i, j);
11 return 0;
}
✌
✆
✞
i:5, j: -1081549298
✌
✆
The same problem gives desired result if a printf function is placed inside while loop.
✞
1 #include <stdio.h>
3 int main () {
int i;
5 int j;
while (i < 5) {
7 j = i + j;
printf("i:%d, j:%dn", i, j);
9 i++;
}
11 printf("i:%d, j:%dn", i, j);
return 0;
13 }
✌
✆
✞
%Inner loop printf%
i:0, j:0
i:1, j:1
i:2, j:3
i:3, j:6
i:4, j:10
%Outer loop printf%
i:5, j:10
✌
✆
In the following example, ‘res’ variable is not initialized. Hence the result is not as we
required.
✞
#include <stdio.h>
2
int main () {
4 char intg [ ] = "1234233 ";
/* res is not initialised and assumed as zero */
6 int i = 0, res;
while (intg [i] != ’0’) {
8 /* Product of res with 10 is null .*/
res = res * 10 + (intg [i] % 48);
10 i++;
}
12 printf("%dn", res);
return 0;
58 Basic C
14 }
✌
✆
✞
-678766791
✌
✆
But when res in above example is initialized then answer is that as we required.
✞
1 #include <stdio.h>
3 int main () {
char intg [ ] = "1234233 ";
5 /* Res is not initialised to 0.*/
int i = 0, res =0;
7 while (intg [i] != ’0’) {
/* Product of res with 10 is null .*/
9 res = res * 10 + (intg [i] % 48);
i++;
11 }
printf("%dn", res);
13 return 0;
}
✌
✆
✞
1234233
✌
✆
Observing above examples given for un-initialized variables, it is recommended that each
variable should be initialized before its use to avoid unpredictable results. See the follow-
ing example, in which variable ‘i’ is not initialized inside the XYZ() function. i.e.
✞
1 int i;
✌
✆
The while function does not give any output.
✞
1 #include <stdio.h>
3 int XYZ() {
int i; /*i is NOT initialized .*/
5 int loops = 5;
while (i < loops) {
7 /* It shall NOT be printed at output console .*/
printf("i is %dn", i);
9 i++;
}
11 return 0;
}
13
int main (void ) {
15 /* Call XYZ() function .*/
XYZ();
17 return 0;
}
✌
✆
1.3. VARIABLES 59
When we initialized the variable ‘i’ inside the XYZ() function as given below.
✞
int i=0;
✌
✆
The while function gives desired output.
✞
1 #include <stdio.h>
3 int XYZ() {
int i=0; /*i is initialized .*/
5 int loops = 5;
while (i < loops) {
7 /* It shall be printed at output console.*/
printf("i is %dn", i);
9 i++;
}
11 return 0;
}
13
int main (void ) {
15 /* Call XYZ() function .*/
XYZ();
17 return 0;
}
✌
✆
✞
i is 0
i is 1
i is 2
i is 3
i is 4
✌
✆
In the C language’s grammar, a scalar initializer may be enclosed in any number of curly
brace pairs.
✞
1 int x = 12;
int y = { 23 }; // valid , no warning
✌
✆
Most compilers issue a warning if there is more than one such pair.
✞
int z = { { 34 } }; // valid , expects a warning
✌
✆
If there are multiple values being assigned to a variable and are comma separated then
assignment of value to the variable is take place in Right-to-Left order. For example
✞
1 int i=10, 20, 30; // valid
✌
✆
always assigns value 10 to i. Structures, unions and arrays stores data of variable numbers
and size. These can be initialized in their declaration using an initializer list. Without
designator, the initialization of a structure, union or array is sequential. To initialize a
successive element, the preceding element must be initialized by assigning a value either
empty, null or zero. For example, take the structure as
60 Basic C
✞
1 struct st{
int x;
3 float y;
char *z;
5 };
✌
✆
To initialize z without designation, initializer list is used like
✞
1 /* Following type of declaration is invalid*
* as its first element must be an integer */
3 struct st k = {"Konark Temple" };
/* Following declaration is invalid and *
5 * unacceptable . Its first and second *
* elements must be an integer or a float*/
7 struct st k = {4, "Konark Temple" };
/* Following declarations are valid */
9 struct st k = {3, 4, "Konark Temple" };
struct st k = {0, 0, "Konark Temple" };
✌
✆
Here is the complete example in which struct table is initialized with integers and strings.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 struct st {
int x;
6 float y;
char *z;
8 };
10 int main (void ) {
struct st k = {"Konark Temple"}; /* Illegal assignment */
12 printf("Temple name is %sn", k.z);
return EXIT_SUCCESS ;
14 }
✌
✆
✞
Temple name is null
✌
✆
The above example is modified for different output.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
struct st {
5 int x;
float y;
7 char *z;
};
9
int main (void ) {
1.3. VARIABLES 61
11 /* valid assignment */
struct st k = {0, 0, "Konark Temple"};
13 printf("%dn", k.x);
printf("Temple name is %sn", k.z);
15 return EXIT_SUCCESS ;
}
✌
✆
✞
0
Temple name is Konark Temple
✌
✆
To overcome this strict initialization, designated initializers are used like
✞
/* valid and acceptable */
2 struct st k = {.z="Konark Temple" };
✌
✆
✞
#include <stdio.h>
2 #include <stdlib.h>
4 struct st {
int x;
6 float y;
char *z;
8 };
10 int main (void ) {
// valid designator initializer
12 struct st k = {.z=" Konark Temple" };
printf("Temple name is %sn", k.z);
14 return EXIT_SUCCESS ;
}
✌
✆
✞
Temple name is Konark Temple
✌
✆
Designated initializers allow its members to be initialized by name, in any order, and
without explicitly providing the preceding values. Compound designators can be used to
provide explicit initialization.
✞
1 struct { int a[3], b; } w[ ] =
{
3 { { 1, 0, 0 }, 0 },
{ { 2, 0, 0 }, 0 }
5 };
✌
✆
Compound literals are often combined with designated initializers to make the declaration
more readable:
✞
1 pi = (struct s){ .z = "Pi", .x = 3, .y = 3.1415 };
✌
✆
62 Basic C
✞
1 #include <stdio.h>
#include <stdlib.h>
3
struct st {
5 int x;
float y;
7 char *z;
};
9
int main (void ) {
11 struct st k;
k = ( struct st){ .z = "Konark Temple", .x = 1, .y = 1.51 };
13 printf("Temple name is %sn", k.z);
return EXIT_SUCCESS ;
15 }
✌
✆
✞
Temple name is Konark Temple
✌
✆
By default, strings are addresses of memory where strings are stored. Integer variables
are not so. This is why to get the address of integer value, integer variables are prefixed
with ‘&’ symbol.
✞
1 int i=10;
3 /*It is address of integer i*
*where value 10 is stored. */
5 int *j=&i;
7 char j[10]="Harappa";/*j is address itself.*/
✌
✆
See the following example, which is complete code of the above code snippet.
✞
1 #include <stdio.h>
3 int print(int *i) {
printf("%d", *i);
5 return 0;
}
7
int main () {
9 int i = 10;
int *j = &i;
11 print(j);
return 0;
13 }
✌
✆
✞
10
✌
✆
1.3. VARIABLES 63
Float To Integer
Variable type ‘int’ stores data with zero digit precision while ‘float’ stores data with single
digit precision. When a floating point number is assigned to an integer type variable then
only whole part of the floating point number is assigned to the integer variable, and its
fraction part is truncated. See the example below.
✞
1 #include <stdio.h>
3 int main () {
float x;
5 printf("Enter a number : ");
scanf("%f", &x);
7 int y = x;
float z = (x - y);
9 printf("Whole part is %dn", y);
printf("Fraction part is %fn", z);
11 return 0;
}
✌
✆
The output of this program is
✞
Enter a number : 2.5
Whole part is 2
Fraction part is 0.500000
✌
✆
Signed & Unsigned Integer
A byte is 8 bits long memory space. The size of int is 4 byte, i.e. 32 bits. In a signed
integer, first bit, from MSB side is considered as sign bit and remaining 31 bits are used
for storing of an integer value. If integer is defined as unsigned then all 32 bits are used
for storing of an integer value. For convenience of understanding, assume that we are
storing small integer type value, and it is one byte long as shown below:
1 1 1 1 1 1 1 1
Sign bit
1 Byte
As the above byte is signed integer byte, hence its MSB bit represents to sign of the
integer. Bit 1 represents to negative sign and bit 0 represents to positive sign. This is
why, above binary data is equivalent to -127 decimal value.
1 1 1 1 1 1 1
0
Sign bit
1 Byte
64 Basic C
As the above byte is signed integer byte, hence its MSB bit represents to sign of the
integer. Bit 1 represents to negative sign and bit 0 represents to positive sign. This is
why, above binary data is equivalent to -127 decimal value.
✞
1 //+--------------------- Sign bit
(1) 1111111 b =>-127 d // Signed 8 bits long integer
3 11111111 b => 255d // Unsigned 8 bits long integer
✌
✆
1 1 1 1 1 1 1 1
1 Byte
As the above byte is unsigned integer byte. This is why, above binary data is equivalent
to 255 decimal value. A signed integer ranges from -2147483647 to 2147483647 while
unsigned integer ranges from 0 to 4294967294. In the C, bit ‘0’ is used for positive sign
and bit ‘1’ is used for negative sign. Now, a question is here that what will happen if we
store a negative number to the unsigned variable? For example,
✞
1 unsigned char i=-16; // char type for one byte long data
✌
✆
The answer is that, here, compiler uses one’s complement method to store the negative
value. It means first, 16 is converted into binary data and then it is complemented and
added by bit 1. The result thus obtained is stored in the memory address pointed by the
variable.
1 Byte
0 0 0 1 0 0 0 0 = 1610
1 Byte
1 1 1 0 1 1 1 1 = 23910
Complement
1 Byte
1 1 1 1 0 0 0 0 = 24010
Complement + 1
Now, an unsigned variable (one byte long here) stores value -16 in memory as binary
11110000b. See the example given below:
✞
1 #include <stdio.h>
3 int main () {
unsigned char c = -16;
5 printf("%dn", c);
return 0;
7 }
✌
✆
1.3. VARIABLES 65
✞
240
✌
✆
Overflow of Data
A variable declared as integer, long, float or double integer and character has capacity
to store a specific size of data. An integer variable can not store data as long as float
variable. This is why, a variable shall be declared of proper size for storing a data. To
understand the overflow, consider a variable ‘k’ of virtual data type, DATATYPE, that
can store only one byte long data. This variable ‘k’ may be signed or unsigned. First
assume it is unsigned, then the largest decimal value, that can be stored by it is 255.
Initially, ‘k’ is declared and initialized with decimal value 254.
✞
1 DATATYPE k;
k = 254d = 11111110 b; /*8 bit result */
✌
✆
Here, suffix ‘d’ represents the decimal form of number and ‘b’ represents to binary form
of number. Now, ‘k’ is incremented by 1, it becomes
✞
k = 255d = 11111111 b; /*8 bit result */
✌
✆
Again, ‘k’ is incremented by 1, it becomes
✞
1 k = 256d = 1 00000000 b; /*9 bit result */
✌
✆
The bit size of result is larger than one byte. The value of ‘k’ is reset to zero due to
overflow. Here, overflow carry is ‘1’. Similarly a positive signed value becomes negative
signed value if it is incremented beyond the signed data range. Taking the same data
type DATATYPE, and variable ‘k’ with signed value.
✞
1 /* Bit inside parentheses represents to sign .*/
signed DATATYPE k;
3 k = 127d = (0) 1111111b;
✌
✆
Here, suffix ‘d’ represents the decimal form of number and ‘b’ represents to binary form
of number. Now, ‘k’ is incremented by 1, the result becomes
✞
1 /* Bit inside parentheses represents to sign .*/
k = -0d = (1) 0000000b;
✌
✆
It becomes negative zero. Again, if ‘k’ is incremented by 1, the result becomes
✞
/* Bit inside parentheses represents to sign .*/
2 k = -1d = (1) 0000001b;
✌
✆
Which is -1. Here, again ‘k’ is overflowed.
66 Basic C
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
kth
Byte
+ 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
kth
Byte
lth
Byte
Maximum size of one byte long data is decimal 255. When it is binary added by bit
1. The result becomes 256. The bit arrangement of result 256 is shown in above figure.
Additive carry bit 1, is stored in another byte while actual byte has all 0 bits. One byte
long data type variable (say ‘i’) that points to this byte takes additive carry bit as overflow
bit and it is un-used for this variable. Therefore, the value of variable ‘i’ becomes zero.
✞
#include <stdio.h>
2
int main () {
4 int i; /* Four bytes long */
unsigned char *x; /* One byte long */
6 for (i = 255; i <= 256; i++) {
/* Points to each byte independently of integer i.*/
8 x = (char *) &i;
/* Print little endian byte only of integer i.*/
10 printf("x[0] byte of integer %d is %dn", i, x[0]) ;
}
12 return 0;
}
✌
✆
Little endian byte access by variable ‘x’ of above example is illustrated in the following
figure.
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
x[0] Byte
+ 1
0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0
x[0] Byte
Output of above example is shown below:
✞
x[0] byte of integer 255 is 255
x[0] byte of integer 256 is 0
✌
✆
See another example given below, in which result is not as required due to bigger size
of data as the integer variable can store. An integer can store 2 or 4 byte long data. In
1.3. VARIABLES 67
numerical equivalent the maximum unsigned number can be stored by an integer variable
is ‘2147483647’. If number is larger than it, the result is wiered.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
/* Signed value of an integer ranges *
6 * from -2147483648 to 2147483647. If *
* integer value become larger than *
8 * 2147483647 it overflows by one bit *
* and integer value becomes largest *
10 * negative number. */
signed int i = 2147483645;
12 int j;
for (j = 0; j < 5; j++)
14 printf("%dn", i + j);
return EXIT_SUCCESS ;
16 }
✌
✆
✞
2147483645
2147483646
2147483647
-2147483648
-2147483647
✌
✆
The unsigned integers were standard in ISO C90. In later C standards, an integer is
implicitly is a signed integer. Following example will give a strange result though the
integer value is less than the largest unsigned integer value.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 /* Unsigned value of an integer*
* ranges from 0 to 4294967295. */
7 signed int i = 4294967293;
int j;
9 for (j = 0; j < 5; j++)
printf("%dn", i + j);
11 return EXIT_SUCCESS ;
}
✌
✆
✞
-3
-2
-1
0
1
✌
✆
68 Basic C
So, the double data type is used in place of unsigned int to used integers larger than
2147483647.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 /* Unsigned value of an integer*
* ranges from 0 to 4294967295. */
7 double i = 4294967293.00;
double j;
9 for (j = 0; j < 5; j++)
printf("%fn", i + j);
11 return EXIT_SUCCESS ;
}
✌
✆
✞
4294967293.000000
4294967294.000000
4294967295.000000
4294967296.000000
4294967297.000000
✌
✆
Following is another good example.
✞
1 #include <stdio.h>
3 int Fac(int i) {
int j = 1;
5 while (i > 0) {
j = j*i;
7 i--;
}
9 return j;
}
11
int main () {
13 int i = 10;
while (i < 15) {
15 printf("Factorial of %d is %dn", i, Fac(i));
i++;
17 }
return 0;
19 }
✌
✆
The output of the program is
✞
Factorial of 10 is 3628800
Factorial of 11 is 39916800
Factorial of 12 is 479001600
%Actual Factorial of 13 is 6227020800
Factorial of 13 is 1932053504 %Wiered result
1.3. VARIABLES 69
%Actual Factorial of 14 is 87178291200
Factorial of 14 is 1278945280 %Wiered result
✌
✆
Memory Size (sizeof)
sizeof () function is used to find the memory used by a variable, pointer, array or structure.
Its result is used in implementation process. The return value of this function is either
unsigned long or unsigned int. In the following example, memory spaced allocated or
to be allocated for pointer-to-integer variables or pointer-to-arrays is obtained by using
sizeof ().
✞
1 #include <stdio.h>
#include <limits.h>
3
int main (void ) {
5 int *a;/* Single pointer -to -integer variable */
printf("Storage size for a : %d n", sizeof (a));
7 int *b[10];/* pointer -to -integer array with 10 elements */
printf("Storage size for b : %d n", sizeof (b));
9 int *c[20];/* pointer -to -integer array with 20 elements */
printf("Storage size for c : %d n", sizeof (c));
11 int *d[30];/* pointer -to -integer array with 30 elements */
printf("Storage size for d : %d n", sizeof (d));
13 return 0;
}
✌
✆
The output is
✞
Storage size of a : 4
Storage size of b : 40
Storage size of c : 80
Storage size of d : 120
✌
✆
When sizeof is used to get the size of an array it returns one more than the actual
size of array (size is sum of number of array elements and following null terminating
character). It always returns size of first associated element if its argument is dereference
to a pointer variable.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 /* arr[ ] points to the string , Hello.*/
const char arr[ ] = "Hello";
6 /* *cp points to the address of char , H*/
const char *cp= "Hello";
8
int main () {
10 /* Returns size of whole string including terminating char .*/
printf("Size of array %lun", (unsigned long ) sizeof (arr));
12 /* Returns size of first character of string. It is char size .*/
70 Basic C
printf("Size of *cp %lun", (unsigned long ) sizeof (*cp));
14 exit ( EXIT_SUCCESS );
}
✌
✆
✞
Size of array 6
Size of *cp 1
✌
✆
Similarly for integer pointers
✞
#include <stdio.h>
2
/* *cp points to the address of integer */
4 const int *cp = {10};
6 int main () {
/* Returns size of first element of integer array.*/
8 printf("Size of *cp %lun", (unsigned long ) sizeof (*cp));
return 0;
10 }
✌
✆
✞
Size of *cp 4
✌
✆
Similarly, memory space used by an integer array can also be obtained. Remember that,
size of a pointer is fixed for a compiler. All pointer types take same number of bytes for a
compiler. That is why, we get the size of pointer ‘pi’ and ‘pc’ as 4 bytes in the following
example.
✞
1 #include <stdio.h>
3 int main () {
/* Array of integers .*/
5 int i[ ] = {1, 2, 3};
/* Point to address of first integer element .*
7 *Here pi is pointer to the integer array i.*/
int *pi = i; /* Size of pointer is fixed*/
9
/* Array of characters .*/
11 char c[ ] = {1, 2, 3};
/* Point to address of first character element .*
13 *Here pc is pointer to the character array c.*/
char *pc = c; /* Size of pointer is fixed*/
15
printf("Size of i[ ] = %d n", sizeof (i));
17 printf("Size of pi = %d nn", sizeof (pi));
19 printf("Size of c[ ] = %d n", sizeof (c));
printf("Size of pc = %d n", sizeof (pc));
21
return 0;
23 }
✌
✆
1.3. VARIABLES 71
✞
Size of i[ ] = 12
Size of pi = 4
Size of c[ ] = 3
Size of pc = 4
✌
✆
The safe way to use sizeof operator is; either cast the return value to unsigned long or to
use the defined type size t provided in the ‘stddef.h’ header file.
✞
1 #include <stddef.h>
#include <stdio.h>
3 #include <stdlib.h>
5 main () {
size_t sz;
7 sz = sizeof (sz);
printf("Size of sizeof is %lun",
9 (unsigned long ) sz);
exit ( EXIT_SUCCESS );
11 }
✌
✆
✞
Size of sizeof is 4
✌
✆
Here is another example.
✞
1 #include <stdio.h>
#include <stdlib.h>
3 const char *list [ ] = {"Red", "Green", "Blue ", "Black", "White"};
#define LIST_SIZE (sizeof(list )/sizeof(list [0]) )
5
int main (int argc , char *argv [ ]) {
7 int ix;
for (ix = 0; ix < LIST_SIZE ; ix ++) {
9 printf("%sn", list [ix]);
}
11 return 0;
}
✌
✆
✞
Red
Green
Blue
Black
White
✌
✆
A function, equivalent to sizeof() function is explained in following example.
✞
1 #include <stdio.h>
3 int main () {
72 Basic C
/* Pointer ’s name . */
5 char *ptA , *ptB;
char fl;
7 /* Get initial pointer location for character */
ptA = &fl;
9 /* Get next pointer location for character . *
* Addition of 1 in pointer , pointer jumps *
11 * equivalent to the zide of data type . */
ptB = (&fl + 1);
13 /* Size of character . */
printf("Size of char is %u", ptB - ptA);
15 return 0;
}
✌
✆
✞
Size of char is 4
✌
✆
In case of numerical array, the argument of sizeof () function may be first element value
itself of its data type. Both gives same result.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
float A[ ] = {10.10 , 50.50 , 4.57, 1.21};
5 float B[ ] = {10.10 , 50.50 , 4.57, 1.21, 2.21};
printf("Elements in array A are : %dn",
sizeof(A)/sizeof(float));
7 printf("Elements in array A are : %dn",
sizeof(A)/sizeof(A[0]) );
printf("Elements in array B are : %dn",
sizeof(B)/sizeof(float));
9 printf("Elements in array B are : %dn",
sizeof(B)/sizeof(B[0]) );
return 0;
11 }
✌
✆
✞
Elements in array A are : 4
Elements in array A are : 4
Elements in array B are : 5
Elements in array B are : 5
✌
✆
Casting
We knew that, a data type arranges memory bytes to be read or write at once. For
example, the character data type read and write one character in one byte at once.
Integer data type uses four bytes at once to read or write one integer value, and so on.
Casting is performed to convert a value of one data type into other form of data type.
For example, conversion of integer data type into float or double data type, or conversion
1.3. VARIABLES 73
of integer data type into character data type. Actually, casting rearranges the number of
bytes being read or write by a variable.
i : 0×00 0×00 0×00 0×04
char c=(char) i;
c : 0×00 0×00 0×00 0×04
In above figure, an integer ‘i’ is casted into character data type, i.e. data which was
represented by group of four bytes is now arranged into data represented by group of one
byte. Now, the character data type ‘c’ points to array of four bytes. In casting only way
of grouping of bytes changes, while the number of bytes remain same. In C, there are
two types of castings, (i) implicit casting and (ii) explicit casting. Implicit type casting is
automatically handled by compiler i.e. when two or more datatypes are under execution.
The final data-type will be that data type which is declared.
✞
// integer data type variable declared & initialized
2 int i = 2;
// double data type variable declared & initialized
4 double j = 2;
// integer i is casted as double and used
6 double k = j/i;
✌
✆
An explicit type cast is a cast that should we specifically invoked with either of the cast.
The compiler does not automatically invoke to resolve the data type conversion.
✞
// integer data type variable declared & initialized
2 int i = 2;
double j = i; // implicit casting
4 double k = (double) i; // explicit casting or forced casting
✌
✆
In casting, data of one data type is converted into data of other data type. Therefore,
there is loss of data. Loss of data is due to way and length of reading data stored in the
memory. The same binary data of memory bytes are read in different way for character
data type or integer data type or in float data type. For example, if double data type is
casted as integer data type, then compiler shows warning.
✞
// double data type variable declared & initialized
2 double i = 2.0;
int j = i; /* warning !! as double (8 bytes size ) *
4 *is casted to integer (4 bytes size ). *
*Possible loss of data */
✌
✆
In case of referencing, implicit casting results warning, while explicit casting is acceptable
without warning.
✞
1 // integer data type variable declared & initialized
int i = 2;
3 // double data type variable declared & initialized
double j = 2.5;
74 Basic C
5 double *k = &j; // explicit casting or forced casting
i = k; // warning !! assignment makes integer from
7 // pointer without a cast
i = (int) k;// explicit casting , acceptable
✌
✆
See an example for casting that is given below:
✞
#include <stdio.h>
2
void main () {
4 /* Integer type values.*/
int m1 = 70, m2 = 70, m3 = 100, total;
6 /*’per ’ variable is float type .*/
float per;
8 /* Total is integer type .*/
total = m1 + m2 + m3;
10 /* Result ’per’ variable is of integer type .*
*as all the variables are integer type . */
12 per = total / 300 * 100;
/*’per ’ are called as float while *
14 *all the variables are integer type .*/
printf("The perc is %f", per);
16 printf("n");
/* Result ’per’ variable is integer type . *
18 *’total’ is cast as float. So that result *
*via ’per’ variable convert to float type .*/
20 per = (float) total / 300 * 100; // Explicit casting
/*’per ’ are called as float.*/
22 printf("The perc is %f", per);
printf("n");
24 }
✌
✆
Output of above program is
✞
The perc is 0.000000
The perc is 80.000000
✌
✆
The casting data type is always put inside the parentheses otherwise compiler tries to
re-declare existing variable again and shows compile time error.
Scope of Variables
A variable has either global or local scope. A variable declared at the header of program
has global access restrict to the code file. A variable declared inside a function has scoped
only within the function. A variable declared within braced block has scope within the
block only.
✞
#include <stdio.h>
2 int i = 0; /* Global scope of variable .*/
4 int main () {
1.3. VARIABLES 75
int j = 10; /* Local scope within main ()*/
6 { /* Start of new block 1*/
int j = 20; /* Local scope within block 1*/
8 printf("j inside block 1 is %dn", j);
{ /* Start of new block 2*/
10 int j = 30; /* Local scope within block 2*/
printf("j inside block 2 is %dn", j);
12 } /* End of the block 2*/
printf("j inside block 1 is %dn", j); /*j=2*/
14 } /* End of the block 1*/
printf("j within main () is %dn", j);
16 printf("i within main () is %dn", i);
printf("Updated j within main () is %dn", ++j);
18 printf("Updated i within main () is %dn", ++i);
/* Try to update value of i. Compile error *
20 *as i has local scope within braced block*/
//i = 3;
22 // printf (" Updated i is %dn", i);
return 0;
24 }
✌
✆
✞
j inside block 1 is 20
j inside block 2 is 30
j inside block 1 is 20
j within main () is 10
i within main () is 0
Updated j within main () is 11
Updated i within main () is 1
✌
✆
A variable declared as extern qualifier has global access to whole program. Using extern
qualifiers we can access the variables declared in other code files of a program.
1.3.2 Qualifiers
Qualifiers are those keywords which are used to restrict the nature of a variable. A
variable declared as const type can not be updated later. Similarly, a variable declared
as extern can access to variable declared in other code files within the program.
const Qualifier
When the const qualifier is used, the declared variable must be initialized at declaration.
It is then not allowed to be changed. const declaration creates the declared variable as
read only. The method of const declaration is
✞
1 const int i = 12; // OK
✌
✆
The constant variable must be defined when they are declared as shown above. Therefore,
it is not allowed to declare const variable as given below.
76 Basic C
✞
1 const int i;
i=12; // Not OK
✌
✆
An array can also be declared const that can not be altered later. For example
✞
const int mdays[12] = {31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31};
✌
✆
A pointer can also be declared as constant.
✞
1 const float * ptrf ; /* ptrf points to a constant float value */
✌
✆
In following example, i is declared as constant integer equal to 10. It is printed int the
output console.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
/* Declare i as constant integer .*
5 * And initialize it at here . */
const int i = 10;
7 printf("i is %dn", i);
return 0;
9 }
✌
✆
✞
i is 10
✌
✆
But changing the value of variable i is not allowed. In following example, compiler shows
error at i++;
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
/* Declare i as constant integer .*
5 * And initialize it at here . */
const int i = 10;
7 printf("i is %dn", i);
/* Increment of i is not allowed.*/
9 i++; /* Illegar expression . Will show error.*/
printf("i++ is %dn", i);
11 return 0;
}
✌
✆
The const type variable can not be assigned new values. But value can be changed by
other code or pointer.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main () {
const volatile int i = 10;
1.3. VARIABLES 77
6 printf("i is %d n", i);
int *mod = (int*) &i;
8 *mod = 20;
printf("Now , i is %d n", i);
10 return (EXIT_SUCCESS );
}
✌
✆
✞
i is 10
Now , i is 20
✌
✆
A structure is declared as const type and may or may not initialized. Further, the data
members of the instances can not be modified later. If we try to modify them, a compile
time error (‘assignment to read-only type variable’) is shown by the compiler. See the
example below:
✞
#include <stdio.h>
2 #include <stdlib.h>
4 struct myS {
int i;
6 int j;
};
8
int main (void ) {
10 /* struct instances s is declared & *
*assigned values to its members */
12 struct myS s = {9, 19};
printf("s : %d, %dn", s.i, s.j);
14 /* Update member values of s*/
s.i = 10;
16 s.j = 20;
printf("s : %d, %dn", s.i, s.j);
18 /* struct instances t is declared here as const*
*and it is initialized with initial values. */
20 const struct myS t = {15, 25};
printf("t : %d, %dn", t.i, t.j);
22 /* Update member values of const type t*
*It returns errors at compile time . */
24 //t.i = 16;// Uncomment line to see the error
return 0;
26 }
✌
✆
✞
s : 9, 19
s : 10, 20
t : 15, 25
✌
✆
78 Basic C
static Qualifier
When we declare a function or global variable as static it becomes internal. We cannot
access the function or variable through the extern keyword from other files. When we
declare a local variable as static, it is created just like any other variable. However, when
the variable goes out of scope the variable stays in memory, retaining its value, until the
program ends. Variables declared static are initialized to zero (or for pointers, NULL) by
default.
✞
1 #include <stdio.h>
3 /* This variable is accessed by both up() and down () functions .*/
static int j = 0;
5
void up(void ) {
7 /*k is set to 0 when the program starts. The line *
*is then "ignored" for the rest of the program . *
9 *(k is not set to 0 every time up() is called) */
static int k = 0;
11 j++;
k++;
13 printf("up() called. k= %2d, j= %2dn", k, j);
}
15
void down (void ) {
17 static int k = 0;
j--;
19 k--;
printf("down () called. k= %2d, j= %2dn", k, j);
21 }
23 int main (void ) {
int i;
25 /* Call the up function 3 times , then the down function 2 times*/
for (i = 0; i < 3; i++)
27 up ();
for (i = 0; i < 2; i++)
29 down ();
return 0;
31 }
✌
✆
Output of above function is
✞
up() called. k=1, j=1
up() called. k=2, j=2
up() called. k=3, j=3
down () called. k=-1, j=2
down () called. k=-2, j=1
✌
✆
The ‘j’ variable is accessible by both up and down and retains its value. The ‘k’
variables also retain their value, but they are two different variables, one in each of their
scopes. Static variables are a good way to implement encapsulation.
1.3. VARIABLES 79
Property Default Value
Keyword used static
Storage Memory
Default value Zero
Scope Local to the block in which it is declared
Life Time Value persists between different function calls
Optionality Mandatory to use the keyword
Table 1.11: Features of static variable.
When a variable is declared as static, it is assigned value ‘0’ automatically.
✞
1 #include <stdio.h>
3 int main () {
static int i;
5 int j;
printf("%dn", i); // prints 0
7 printf("%dn", j); //j acts as wild pointer , prints garbage
return 0;
9 }
✌
✆
✞
0
1629773328
✌
✆
Static variable initialized once can not be re-initialized, but the variable can store new
value.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 void print(void ) {
/* Static initialization of a*/
6 static int a = 0;
/* Print value of a*/
8 printf("%dn", a);
/* Increment of the static value*/
10 a++;
}
12
int main (void ) {
14 print(); //a is initialized in this function call
print(); //a is NOT reinitialized but stores a+1 value
16 print(); //a is NOT reinitialized but stores a+2 value
return 0;
18 }
✌
✆
80 Basic C
✞
0
1
2
✌
✆
C does not advocate to return the address of a local variable to outside of the function.
Hence it is recommended that the local variable should be defined as static variable. Take
and example as given below:
✞
1 #include <stdio.h>
int * myF( ) {
3 int r[1];
r[0]=10;
5 return r;
}
7 int main () {
int *p;
9 p = muF();
printf("%dn", *p);
11 return 0;
}
✌
✆
On compilation of above program, the result shall be shown correctly but the compiler
shall warn about that the function returns address of local variable. Output of above
example is looked like
✞
warning: function returns address of local variable
[-Wreturn -local -addr ]
return r;
^
10
✌
✆
When integer variable ‘r’ is declared as static, the compiler gives output without
warning.
✞
#include <stdio.h>
2 int * myF( ) {
static int r[1];
4 r[0]=10;
return r;
6 }
int main () {
8 int *p;
p = muF();
10 printf("%dn", *p);
return 0;
12 }
✌
✆
✞
10
✌
✆
1.3. VARIABLES 81
extern Qualifier
extern is used when a file needs to access a variable in another file that it may not have
#include directly. Therefore, extern does not actually carve out space for a new variable,
it just provides the compiler with sufficient information to access the remote variable.
Property Default Value
Keyword used extern
Storage Memory
Default value Zero
Scope Global (all over the program)
Life Time Value persists till the program’s execution
Optionality Optional if declared outside all the functions
Table 1.12: Features of extern variable.
The syntax of this qualifier is
✞
1 /* Implicit declaration of variable , this only described *
* and assumed allocated elsewhere , normally from include */
3 extern int AVar ;
/* Custom function that will increase external variable by one*/
5 void MyFunc(void ) {
++ AVar ;
7 }
✌
✆
Assume a simple program which has three code files. First main file ‘main.c’, second
header file ‘myH.h’ and third function file ‘Incr.c’. The codes in header file ‘myH.h’, are
✞
1 void Incr ();
✌
✆
The codes in function file ‘Incr.c’, are
✞
1 int in =0;
void Incr (){
3 in ++;
}
✌
✆
The codes in main file ‘main.c’, are
✞
#include <stdio.h>
2 #include "myH.h"
int main () {
4 /* Try to access the ’in’ variable *
*declared in other program file .*/
6 extern int in;
Incr ();/* Increments to ‘in’ declared in ‘Incr .c’ file .*/
82 Basic C
8 printf("%d", in);/* Prints result of external ‘in’*/
return 0;
10 }
✌
✆
By using extern qualifier, we can access to the variable ‘in’ declared and initialized in
function file ‘Incr.c’. The function ‘Incr()’ increments to the variable which is printed in
output by using printf function. The output of the above program is
✞
1
✌
✆
If the code line
✞
1 extern int in;
✌
✆
given in above ‘main.c’ file is rewritten as
✞
1 int in;
✌
✆
then, the program output shall be ‘0’. It is because ‘Incr()’ function increments to the
variable declared in its ‘Incr.c’ file. Inside the main() function of ‘main.c’ file, we print
output by using printf function and by this function value of locally declared ‘in’ variable
is ptrinted, which is 0 by default. See the modified codes of ‘main.c’ file
✞
1 #include <stdio.h>
#include "myH.h"
3 int main () {
/*‘in ’ variable is declared locally here .*/
5 int in;
Incr ();/* Does not increment to locally declared ‘in’*/
7 printf("%d", in);/* Prints result of local ‘in’*/
return 0;
9 }
✌
✆
✞
0
✌
✆
volatile Qualifier
volatile is a special type modifier which informs the compiler that the value of the variable
may be changed by external entities other than the program itself. The value of volatile
variable may change between two successive readings of the variable even though program
has not modify the value of volatile type variable. It is good practice to read the variable
value each time before program tries to accessing it. volatile is relevant with embedded
systems. In embedded systems a program has not have complete control on a variable.
The syntax for volatile qualifier is
✞
1 int volatile i;
✌
✆
See the example below in which a variable ‘i’ is declared as constant. The value of the
variable ‘i’ can not be changed by program itself.
1.3. VARIABLES 83
✞
1 #include <stdio.h>
3 int main (void ) {
/* Declare i as constant integer */
5 const int i = 10;
int *j = (int*) &i;
7 printf("Value of i is : %d n", i);
/* Try to modify value of i*/
9 *j = 100;
printf("New value of i is : %d n", i);
11 return 0;
}
✌
✆
✞
Value of i is : 10
New value of i is : 10
✌
✆
Now, the same variable ‘i’ is declared as constant and volatile. The value of the variable
‘i’ can be changed by program itself.
✞
#include <stdio.h>
2
int main (void ) {
4 /* Declare i as constant integer */
const volatile int i = 10;
6 int *j = (int*) &i;
printf("Value of i is : %d n", i);
8 /* Try to modify value of i*/
*j = 100;
10 printf("New value of i is : %d n", i);
return 0;
12 }
✌
✆
✞
Value of i is : 10
New value of i is : 100
✌
✆
auto Qualifier
auto is a modifier which specifies an “automatic” variable that is automatically created
when in scope and destroyed when out of scope. If you think this sounds like pretty much
what you’ve been doing all along when you declare a variable, you’re right: all declared
items within a block are implicitly “automatic”. For this reason, the auto keyword is
more like the answer to a trivia question than a useful modifier, and there are lots of very
competent programmers that are unaware of its existence. The automatic variable is not
initialized at all.
84 Basic C
Property Default Value
Keyword used auto
Storage Memory
Default value Garbage value or random value
Scope Local to the block in which it is defined
Life Time Value persists till the control remains within
the block
Optionality Optional
Table 1.13: Features of auto variable.
In following example, ‘b’ has declared as automatic variable and it has scope only
inside the block where it is declare. Here, ‘b’ is declared outside the main function block,
so on compilation, it shows an error.
✞
#include <stdio.h>
2 /* Automatic variable b*/
auto int b = 10;
4
int main () {
6 auto int a = 5;
a++;
8 printf("%dn", a);
printf("%dn", b);
10 return 0;
}
✌
✆
In following example, variable ‘b’ is global integer while a is defined as automatic inside
the main() function. Hence variable ‘a’ and ‘b’ are accessible inside the main() function.
✞
1 #include <stdio.h>
/*b has declared as global.*/
3 int b = 10;
5 int main () {
auto int a = 5;
7 a++;
printf("a : %dn", a);
9 printf("b : %dn", b);
return 0;
11 }
✌
✆
✞
a : 5
b : 10
✌
✆
1.3. VARIABLES 85
When defining a variable, we dont actually need to state its type explicitly when it can
be deduced from the auto initializer. With auto, we use equal (=) syntax because there
is no type conversion involved that might cause problems. See the example below:
✞
#include <stdio.h>
2
int main () {
4 auto i = ’c’;
printf("%c ", i);
6 return 0;
}
✌
✆
✞
c
✌
✆
register Qualifier
Storing and retrieving of data in memory is slower than storing and retrieving of data
from CPU resistors. Hence, sometime storing and retrieving of data from resistor makes
a program run faster. register is a hint to the compiler to attempt to optimize the
storage of the given variable by storing it in a register of the computer’s CPU when the
program is run. Most optimizing compilers do this anyway, so use of this keyword is
often unnecessary. In fact, ANSI C states that a compiler can ignore this keyword if it so
desires and many do.
Property Default Value
Keyword used register
Storage CPU registers (values can be retrieved faster
than from memory)
Default value Garbage value
Scope Local to the block in which it is defined
Life Time Value persists till the control remains within
the block
Optionality Mandatory to use the keyword
Table 1.14: Features of register variable.
Example for register type variable is given below.
✞
1 #include <stdio.h>
3 int main () {
register int i;
5
for (i = 0; i < 5; i++) {
86 Basic C
7 printf("Value is %d n", i);
}
9 }
✌
✆
✞
Value is 0
Value is 1
Value is 2
Value is 3
Value is 4
✌
✆
When a C-program is run, the main() function refers to two special purpose registers, i.e.
‘rbp’ and ‘rsp’. ‘rbp’ is the base pointer, which points to the base of the current stack
frame, and ‘rsp’ is the stack pointer, which points to the top of the current stack frame.
When a variable is added in stack, ‘rbp’ increments by one and points to next memory
cells to store next variable value. In GCC, register keyword with asm keyword provides
access to these special purpose registers directly as shown in the following example.
✞
1 #include <stdio.h>
#include <stdlib.h>
3
int main (void ) {
5 register long rsp asm("rsp");
register long rbp asm("rbp");
7 int i = 10; // value at rbp -0x4
int j = 20; // value at rbp -0x8
9 int k = 30; // value at rbp -0 x12
printf("rpb = %lxn", rbp); /* Current pointer of rbp *
11 * points next empty cell */
printf("a = %dn", *( int *) ((( char *) rbp) - 0x4));
13 printf("b = %dn", *( int *) ((( char *) rbp) - 0x8));
printf("c = %dn", *( int *) ((( char *) rbp) - 0xc));
15 printf("rsp = %lxn", rsp);
return (0);
17 }
✌
✆
✞
rpb = 22cd 68
a = 10
b = 20
c = 30
rsp = 22cd 40
✌
✆
See another example, in which accumulator register is accessed through register keyword.
✞
1 #include <stdio.h>
3 int main () {
int out;
5 register char bx asm("ebx");
/* Add 10 and 20 and store *
7 *result into register %eax*/
1.3. VARIABLES 87
__asm__ ("movl $10 , %% eax;"
9 "movl $20 , %% ebx;"
"addl %%ebx , %% eax;"
11 : "=a" (out)
);
13 printf("Sum is %dn", out);
printf("bx register has %dn", bx);
15 return 0;
}
✌
✆
✞
Sum is 30
bx register has 20
✌
✆
restrict Qualifier
restrict keyword is used with pointers only. It restricts the access of the object pointed by
pointer only through the pointer pointing to that object. It helps compiler for not further
checks. If this keyword is not used properly, result becomes undefined. This keyword is
used to optimize the assembler codes.
attribute & pragma
pragma and attribute directives are used to tell the program that which parts of the
codes shall be executed before (at run) or after (at exit) running of the main program.
#pragma does not support by gcc compiler. The use of #pragma and attribute direc-
tives is given below:
✞
#pragma startup <func1 >
2 #pragma exit <func2 >
//
4 void __attribute__ (( constructor )) <func1() >;
void __attribute__ (( destructor )) <func2() >;
✌
✆
See the program given below:
✞
1 #include <stdio.h>
3 void myFuncA ();
void myFuncB ();
5
void __attribute__ (( constructor )) myFuncA ();
7 void __attribute__ (( destructor )) myFuncB ();
9 void myFuncA () {
printf("Inside my function A.n");
11 }
13 void myFuncB () {
printf("Inside my function B.n");
88 Basic C
15 }
17 int main () {
printf("Inside main ()n");
19 return 0;
}
✌
✆
✞
Inside my function A.
Inside main ()
Inside my function B.
✌
✆
These directives are used to warn users about the dependencies or pre-requirements of
specific libraries for the given program.
1.4 C Operators
1.4.1 Expression
An expression is a combination of one or more explicit values, constants, variables, op-
erators, and functions. The evaluated value of expression is assigned to another variable
or printed in output stream. If a function is present in an expression and the function
is declared as void return type, then returned value is discarded in that expression. For
example
y = x2
+ b ∗ x + 9
is an expression of variables ‘x’ and ‘y’ while ‘b’ and ‘9’ are constants. ‘y’ is dependent
variable and other variables are either constant or independent. The terms of expression
are evaluated as their mathematical operations. Here ‘ˆ’ means power rather than bitwise
operator. ‘b’ and ‘x’ are in product (‘*’ means multiplication) and all the terms in right
hand side are in summation. The expression with function is declared as
y = x2
+ myF(x)
Where ‘myF()’ is user defined function.
1.4.2 Instructions
There are three types of instructions in C. Declaration instruction, arithmetic instruction
and control instruction. Declaration instructions are used in declaration of data type,
assigning values and evaluation of operators.
✞
1 int i; // Declaration Instruction
int j=0; // Declaration Instruction
✌
✆
Arithmetic instructions are used to perform arithmetic operations on variables and con-
stants.
✞
int i; // Declaration Instruction
2 int j=0; // Declaration Instruction
int k = i + j; // Arithmetic Instruction
✌
✆
1.4. C OPERATORS 89
Control instructions are used to control the flow of program. The control instructions are
if, if-else, switch statements and other conditional operators.
✞
1 int k = 1; // Declaration Instruction
if(k>2){ // Control Instruction statement
3 printf("True ");
}else {
5 printf("False");
}
✌
✆
1.4.3 Unary Operators
In a unary operation, operator has only one operand. The unary operators used in C are
given in table below.
Type Representation
Increment ++x, x++
Decrement – – x, x – –
Address &x
Indirection *x
Positive +x
Negative –x
Ones’ complement ∼x
Logical negation !x
Sizeof sizeof x, sizeof (type-name)
Cast (type-name) cast-expression
In above table, ‘type-name’ is variable type, like int, char, long, double etc. ‘cast-
expression’ is variable that is being converted from one data type to other data type.
✞
#include <stdlib.h>
2
int main () {
4 printf("Negative of 2 is %dn", -2);
return 0;
6 }
✌
✆
✞
Negative of 2 is -2
✌
✆
Increment operator ‘++’ is used either as prefix or suffix to a variable. Both are not same.
When ‘++’ operator is prefixed to variable then value of the variable is first incremented
90 Basic C
and then used. Similarly, when ‘++’ operator is suffix to a variable then value of variable
is used first then it is incremented.
✞
1 /* Use then increment */
i ++;
3 /* Increment then use*/
++ i; /* Equals to i = i + 1; */
✌
✆
Equivalent example for i + + is given below:
✞
#include <stdio.h>
2
int main () {
4 int i = 9;
{/* Begin of i++ block*/
6 printf("i is %dn", i);/* Use i*/
i = i + 1; /* Then increment it*/
8 }/* End of i++ block*/
return 0;
10 }
✌
✆
✞
i is 9
✌
✆
Equivalent example for + + i is given below:
✞
1 #include <stdio.h>
3 int main () {
int i = 9;
5 {/* Begin of ++i block*/
i = i + 1; /* Increment i*/
7 printf("i is %dn", i); /* Then use it*/
9 }/* End of ++i block*/
return 0;
11 }
✌
✆
✞
i is 10
✌
✆
If increment or decrement operator is used with function parameter in a function call, then
at first variable is computed and then its value is passed to the fuction as its argument.
✞
1 #include <stdio.h>
3 int get(int i){
return i+1;
5 }
7 int main () {
int i = 2;
1.4. C OPERATORS 91
9 /*Here , ++i = 3 and next ++i = 4. Now , i is replaced *
*by 4. The value 4*4=16 is passed for function call */
11 printf("%d", get (++i * ++i)); // Prints 17
return 0;
13 }
✌
✆
✞
17
✌
✆
If one of the operand of a valid operator is another valid operator then it acts as unary
operator as shown in the following example.
✞
1 #include <stdio.h>
3 int main () {
int z = 4 * -3 / -2;
5 printf("%d", z);
return 0;
7 }
✌
✆
✞
6
✌
✆
In this example, minus sign (–) is unary operator as its preceding operand is a valid
multiplication operator. Hence, it makes number 3 and number 2 as negative numbers.
1.4.4 Binary Relation Operators
Binary operators are those operators which require two operands. These operators are
addition, subtraction, multiplication, division, less than, greater than, equals to etc. The
relational binary operators are
Operator Description
< Less than
> Greater than
≤ Less than or equal to
≥ Greater than or equal to
== Equals
! = Not equals
In relation, a < b indicates that ‘a’ is less than ‘b’ and ‘a’ may have infinite numbers
of values which are lesser than ‘b’, i.e. (−∞, b). The value of ‘a’ shall be positive or
negative depends on the value of ‘b’. a ≤ b is similar to a < b except ‘a’ can also be equal
to ‘b’, i.e. (−∞, b]. a == b indicates than ‘a’ is exactly equal to ‘b’ and ‘a’ have no other
value than ‘b’. a! = b means ‘a’ never be equal to ‘b’. ‘a’ may be lesser than or greater
than ‘b’, i.e. (−∞, ∞)-(b).
92 Basic C
✞
1 #include <stdio.h>
#include <string.h>
3
int main (void ) {
5 int a = 5;
int b = 2;
7 int c = 5;
if (a < b)
9 printf("%d is less than %d.n", a, b);
if (a > b)
11 printf("%d is greater than %d.n", a, b);
if (a <= c)
13 printf("%d is either less than or equal to %d.n", a, c);
if (a == c)
15 printf("%d is exactly equal to %d.n", a, c);
if (a != b)
17 printf("%d is not equal to %d.n", a, b);
return 0;
19 }
✌
✆
Output of above program is
✞
5 is greater than 2.
5 is either less than or equal to 5.
5 is exactly equal to 5.
5 is not equal to 2.
✌
✆
Remember that ‘=’ and ‘==’ are not same. ‘=’ is used to assign a value to a variable
and ‘==’ is used for comparison. For example, ‘c=20’ assigned the value 20 to variable
c and returns true in output rather than comparing of c to 20. This is why, because C
does not have a dedicated boolean type. So ‘0’ means false and anything else is true.
✞
int a = 20; // constant initialized
2 /* constant reassigned as 10 and*
*a becomes 10 and returns true */
4 if (a = 10)
printf("Stuff"); // printing of this value.
✌
✆
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 20;
if (i = j)// its true though i is not equal to j.
7 printf("i is equal to j.n"); // will be printed .
if (i == j)
9 printf("i is perfectly equal to j.n"); // will be printed .
}
✌
✆
1.4. C OPERATORS 93
✞
i is equal to j.
i is perfectly equal to j.
✌
✆
Again to be noted that, the equal operator (‘==’) is applicable between two values
or between two variables or between a value and a variable. It is not applicable with
references, i.e. pointers as they points to address not to values. For example
✞
#include <stdio.h>
2
int main () {
4 int *a, *b; // two integer type pointers
a = malloc (4); // allocate memory for ptr a
6 b = malloc (4); // allocate memory for ptr b
*a = 10; // store value for a
8 *b = 10; // store value for b
if (a == b) { // REFERENCE comparison
10 printf("Equaln");
} else {
12 printf("Not Equaln");
}
14 return 0;
}
✌
✆
✞
Not Equal
✌
✆
Now above example is modified as shown below:
✞
1 #include <stdio.h>
3 int main () {
int *a, *b; // two integer type pointers
5 a = malloc (4); // allocate memory for ptr a
b = malloc (4); // allocate memory for ptr b
7 *a = 10; // store value for a
*b = 10; // store value for b
9 if (*a == *b) { // VALUE comparison
printf("Equaln");
11 } else {
printf("Not Equaln");
13 }
return 0;
15 }
✌
✆
✞
Equal
✌
✆
Similarly we should avoid comparison like
✞
1 #include <stdio.h>
int main () {
94 Basic C
3 int v = 20;
if (0 < v < 10) {
5 printf("Stuff");
}else {
7 printf("noStuff ");
}
9 return 0;
}
✌
✆
✞
Stuff
✌
✆
In above example, ‘v’ is greater than 0. Hence in first comparison, construct assign
value 1 to variable ‘v’. Now, value of variable ‘v’ is compared to 10, which is true, so
the statement block of if construct is executed. The appropriate form of comparison is
shown in below example.
✞
1 #include <stdio.h>
int main () {
3 int v = 20;
if (0 < v && v < 10) {
5 printf("Stuff");
}else {
7 printf("noStuff ");
}
9 return 0;
}
✌
✆
✞
noStuff
✌
✆
1.4.5 Comma Operator
Comma operator (,) is a binary operator that evaluates its first operand and discards
the result, and then evaluates the second operand and returns this value. In strings,
comma operator acts as a separator. If comma separated expressions are enclosed inside
the parentheses, then last expression is evaulated. The comma operator has the lowest
precedence. When comma operator is combined with semicolon, then semicolon has lower
precedence than comma.
✞
1 a, b; c, d; => (a, b); (c, d);
✌
✆
Example, when expression is separated by comma and enclosed within parantheses
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 5;
/* First expression is evaluated and its result is discarded */
1.4. C OPERATORS 95
7 printf("%d", (i, j));
return 0;
9 }
✌
✆
✞
5
✌
✆
Example, when expression is separated by comma and not enclosed within parantheses
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 5;
printf("%d", i, j);// First expression is evaluated here
7 return 0;
}
✌
✆
✞
10
✌
✆
Above result is obtained with compilar warning. Another example
✞
1 #include <stdio.h>
3 int main () {
int i = 10;
5 int j = 5;
/* First expression is evaluated and its *
7 * result is discarded but its result is *
* used in evaluation of second expression .*/
9 printf("%d", (i, i+j));
return 0;
11 }
✌
✆
✞
15
✌
✆
If multiple expressions separated by comma operator, are returned by return keyword,
then only last expression is returned while others are just discarded.
✞
1 #include <stdio.h>
3 int myRet(){
return 1, 2, 3;// Last expression is evaluated
5 // and returned by return
}
7 int main () {
printf("%d", myRet());
9 return 0;
}
✌
✆
96 Basic C
✞
3
✌
✆
If multiple expressions separated by comma operator, are assigned to a variable then only
last expression is assigned while others are just discarded.
✞
1 #include <stdio.h>
3 int main () {
// Last expression is assigned to i
5 int i = (1, 2, 3);
printf("%d", i);
7 return 0;
}
✌
✆
1.4.6 Bitwise Operator
A bitwise OR (|) gives result ‘1’ if either one or both bits are ‘1’ otherwise result is zero.
A bitwise AND (&) gives result ‘1’ if both bits are ‘1’ otherwise result is zero. A bitwise
XOR (ˆ) results ‘1’ if only either of two bits1
are ‘1’ otherwise result is zero. A bitwise
NOT (∼) or complement, is a unary operation that performs logical negation on each bit,
forming the ones’ complement of the given binary value. Bits those are 0 become 1, and
those that are 1 become 0.
✞
#include <stdio.h>
2
int main () {
4 /*10 is Binary equivalent to 1010 */
int i = 10;
6 /*5 is Binary equivalent to 0101 */
int j = 5;
8 /* --------------------------**
Bitwise OR Operation is
10 1010
0101
12 ------
1111 = 15
14 **-------------------------- */
printf("Bitwise OR of %d, %d is %d.n", i, j, (i | j));
16 /* ----------------------------**
Bitwise AND Operation is
18 1010
0101
20 ------
0000 = 0
22 **---------------------------- */
printf("Bitwise AND of %d, %d is %d.n", i, j, (i & j));
24 /* ----------------------------**
1
If both bits are opposite bits.
1.4. C OPERATORS 97
Bitwise XOR Operation is
26 1010
0101
28 ------
1111 = 15
30 **---------------------------- */
printf("Bitwise XOR of %d, %d is %d.n", i, j, (i ^ j));
32 /* -----------------------------------------**
Bitwise NOT Operation is
34 00001010 = 10 (decimal)
-------------------------------------
36 11110101 = 117 (signed)=117 -128= -11
**----------------------------------------- */
38 printf("Bitwise NOT of %d is %d.n", i, ~i);
return 0;
40 }
✌
✆
✞
Bitwise OR of 10, 5 is 15
Bitwise AND of 10, 5 is 0.
Bitwise XOR of 10, 5 is 15.
Bitwise NOT of 10 is -11.
✌
✆
The precedence for evaluation of Boolean expression are parentheses, NOT, AND and
OR bitwise operators from high to low. Normally, bitwise & operator returns the value
equal to or less than the lesser operand. This is why & operator is used to restrict the
upper limit of the random result.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
int i = 0;
6 while (i < 10) {
printf("%d&%d=>%d, t", i, 5, i & 5);
8 i++;
}
10 printf("n");
return EXIT_SUCCESS ;
12 }
✌
✆
✞
0&5 => 0, 1&5 => 1, 2&5 => 0, 3&5 => 1, 4&5 => 4,
5&5 => 5, 6&5 => 4, 7&5 => 5, 8&5 => 0, 9&5 => 1,
✌
✆
While bitwise | operator returns the value equal to or larger than the largest operand.
This is why | operator is used to restrict the lower limit of random result.
✞
#include <stdio.h>
2 #include <stdlib.h>
4 int main (void ) {
98 Basic C
int i = 0;
6 while (i < 10) {
printf("%d|%d=>%d, t", i, 5, i | 5);
8 i++;
}
10 printf("n");
return EXIT_SUCCESS ;
12 }
✌
✆
✞
0|5=>5, 1|5=>5, 2|5=>7, 3|5=>7, 4|5= >5
5|5=>5, 6|5=>7, 7|5=>7, 8|5=>13, 9|5= >13
✌
✆
1.4.7 Logical Operator
C has no dedicated boolean type. This is why, it returns 0 on true state and any other
value on false state. In C, the false state returns certain error codes. These certain codes
are either pre-implemented in libraries are user implemented in the user defined functions.
For example, in strcmp() function, when two strings as arguments of this function are
exactly same then it returns 0 otherwise it returns -1. In C, Logical operators are those
operators which compare the variables logically.
Operator Description
&& Logical AND. If both the operands are non-zero, then
condition becomes true. The two operands may be
equal or unequal
|| Logical OR. If any of the two operands are non-zero,
then condition becomes true. It is not matter that
both operands are equal or not.
! Logical NOT. Use to reverses the logical state of its
operand. If a condition is true then Logical NOT
operator will make false.
The precedence for evaluation of Boolean expression are parentheses, NOT, AND and
OR logic operators from high to low.
✞
#include <stdio.h>
2
int main () {
4 int i = 10; /* Not zero , hence true value.*/
int j = 20; /* Not zero , hence true value.*/
6 int k = 0; /* Zero , hence false value.*/
/* print "1" if both integers are not zero .*/
8 printf("&& relation between %d, %d is %d.n", i, j, i && j);
/* print "0" if any of two integers are zero .*/
10 printf("&& relation between %d, %d is %d.n", i, k, i && k);
1.4. C OPERATORS 99
/* print "1" if any of two integers are not zero .*/
12 printf("|| relation between %d, %d is %d.n", i, j, i || j);
return 0;
14 }
✌
✆
✞
&& relation between 10, 20 is 1.
&& relation between 10, 0 is 0.
|| relation between 10, 20 is 1.
✌
✆
It is remembered that bitwise operation is performed between bits of binary
numbers while logical operation is performed between two operand either
binary or integer. Logical expressions are evaluated from left to right. Evaluation
stops as soon as something is discovered that renders the expression false.
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
/* Here 6 is greater than 2. And it is true .*
5 * true value is logically ANDED with 3 and *
* if result is equal to 3 then print value *
7 * is 1 otherwise print value is 0. */
printf("Expression result is %dn", 6 > 2 && 3 == 3);
9 return 0;
}
✌
✆
✞
Expression result is 1
✌
✆
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
int x=6;
5
/* Here x is equal to 6. So , the relation *
7 * x != 6 is false. Now second relation *
* x / 2 < 5 is not evaluated here . So , *
9 * the result is 0. */
11 printf("Expression result is %dn", x != 6 && x / 2 < 5);
return 0;
13 }
✌
✆
✞
Expression result is 0
✌
✆
✞
1 #include <stdio.h>
3 int main (int argc , char *argv [ ]) {
int x=4;
100 Basic C
5
/* Here x is not equal to 6. So , that *
7 * x != 4 is true . Now second relation *
* x / 2 < 5 is logically ANDED with *
9 * the result of x != 6. Here x/2 is 2*
* and 2 is less than 5, so logical *
11 * AND of left and right values is 1 */
13 printf("Expression result is %dn", x != 6 && x / 2 < 5);
return 0;
15 }
✌
✆
✞
Expression result is 1
✌
✆
A point shall be remember here, that evaluation of an expression is discontinued if the
value of a conditional expression is determined early. See the example below:
✞
1 #include <stdio.h>
3 int main () {
int i;
5 int j = 0;
for (i = 0; i < 5; i++) {
7 if ((i > 3) || (j > 4))
printf("Sr No %d, first line n", i);
9 else
printf("Sr No %d, second line n", i);
11 }
}
✌
✆
In above example, ‘i’ is incremented from 0 to 4, while ‘j’ keep always equal to 0. This
is why, j > 0 is always false. While ‘i’ is less than or equal to 3, if () condition remains
false and codes within else block are executed. When ‘i’ becomes larger than 3, codes
within if () block are executed even when condition or j remains false. This is due that
OR operator returns true result. The output of this program is
✞
Sr No 0, second line
Sr No 1, second line
Sr No 2, second line
Sr No 3, second line
Sr No 4, first line
✌
✆
1.4.8 Shift Operator
The logical shift operators defined in C are shown in the following table.
Ad

More Related Content

What's hot (14)

Assembly Codes in C Programmes - A Short Notes by Arun Umrao
Assembly Codes in C Programmes - A Short Notes by Arun UmraoAssembly Codes in C Programmes - A Short Notes by Arun Umrao
Assembly Codes in C Programmes - A Short Notes by Arun Umrao
ssuserd6b1fd
 
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
ssuserd6b1fd
 
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
ssuserd6b1fd
 
Thats How We C
Thats How We CThats How We C
Thats How We C
Vineeth Kartha
 
The C Preprocessor
The C PreprocessorThe C Preprocessor
The C Preprocessor
iuui
 
Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
ssuserd6b1fd
 
Electrónica digital: Logicsim
Electrónica digital: LogicsimElectrónica digital: Logicsim
Electrónica digital: Logicsim
SANTIAGO PABLO ALBERTO
 
Introduction to Arduino
Introduction to ArduinoIntroduction to Arduino
Introduction to Arduino
Rimsky Cheng
 
Differential Equations for Engineers
Differential Equations for EngineersDifferential Equations for Engineers
Differential Equations for Engineers
amelslideshare
 
Hats guia de_macro
Hats guia de_macroHats guia de_macro
Hats guia de_macro
Erick Souza Martinho
 
Advanced macro guide
Advanced macro guideAdvanced macro guide
Advanced macro guide
Erick Souza Martinho
 
Reading Materials for Operational Research
Reading Materials for Operational Research Reading Materials for Operational Research
Reading Materials for Operational Research
Derbew Tesfa
 
Signals and systems
Signals  and systemsSignals  and systems
Signals and systems
Pricha Leelanukrom
 
Assembly Codes in C Programmes - A Short Notes by Arun Umrao
Assembly Codes in C Programmes - A Short Notes by Arun UmraoAssembly Codes in C Programmes - A Short Notes by Arun Umrao
Assembly Codes in C Programmes - A Short Notes by Arun Umrao
ssuserd6b1fd
 
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
Notes and Description for Xcos Scilab Block Simulation with Suitable Examples...
ssuserd6b1fd
 
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...Notes of 8085 micro processor Programming  for BCA, MCA, MSC (CS), MSC (IT) &...
Notes of 8085 micro processor Programming for BCA, MCA, MSC (CS), MSC (IT) &...
ssuserd6b1fd
 
The C Preprocessor
The C PreprocessorThe C Preprocessor
The C Preprocessor
iuui
 
Java Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun UmraoJava Programming Notes for Beginners by Arun Umrao
Java Programming Notes for Beginners by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
Notes for GNU Octave - Numerical Programming - for Students 01 of 02 by Arun ...
ssuserd6b1fd
 
Introduction to Arduino
Introduction to ArduinoIntroduction to Arduino
Introduction to Arduino
Rimsky Cheng
 
Differential Equations for Engineers
Differential Equations for EngineersDifferential Equations for Engineers
Differential Equations for Engineers
amelslideshare
 
Reading Materials for Operational Research
Reading Materials for Operational Research Reading Materials for Operational Research
Reading Materials for Operational Research
Derbew Tesfa
 

Similar to Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by Arun Umrao (20)

Introduction to c++ (cpp)
Introduction to c++ (cpp)Introduction to c++ (cpp)
Introduction to c++ (cpp)
Arun Umrao
 
Haltermanpythonbook.pdf
Haltermanpythonbook.pdfHaltermanpythonbook.pdf
Haltermanpythonbook.pdf
nebulaa2
 
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
EloquenFundamentalsof Web Developmentt_JavaScript.pdfEloquenFundamentalsof Web Developmentt_JavaScript.pdf
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
kasperkey106
 
Fortran programming help book
Fortran programming help bookFortran programming help book
Fortran programming help book
Arun Umrao
 
Xcos simulation
Xcos simulationXcos simulation
Xcos simulation
Arun Umrao
 
thinkcspy3.pdf
thinkcspy3.pdfthinkcspy3.pdf
thinkcspy3.pdf
ssuser244a2a
 
Notes of Java
Notes of JavaNotes of Java
Notes of Java
Arun Umrao
 
caret.pdf
caret.pdfcaret.pdf
caret.pdf
Dr. SANJEEV GUPTA
 
Scilab help book 1 of 2
Scilab help book 1 of 2Scilab help book 1 of 2
Scilab help book 1 of 2
Arun Umrao
 
Algorithmic Problem Solving with Python.pdf
Algorithmic Problem Solving with Python.pdfAlgorithmic Problem Solving with Python.pdf
Algorithmic Problem Solving with Python.pdf
Emily Smith
 
452042223-Modern-Fortran-in-practice-pdf.pdf
452042223-Modern-Fortran-in-practice-pdf.pdf452042223-Modern-Fortran-in-practice-pdf.pdf
452042223-Modern-Fortran-in-practice-pdf.pdf
kalelboss
 
Copy_of_python-journeyman.pdf
Copy_of_python-journeyman.pdfCopy_of_python-journeyman.pdf
Copy_of_python-journeyman.pdf
NedyalkoKarabadzhako
 
Debugger.pdf
Debugger.pdfDebugger.pdf
Debugger.pdf
BuTriLn
 
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdfA_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
ssuser7fcce2
 
A Practical Introduction To Python Programming
A Practical Introduction To Python ProgrammingA Practical Introduction To Python Programming
A Practical Introduction To Python Programming
Nat Rice
 
A practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinoldA practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinold
FaruqolayinkaSalako
 
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdfA_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
TariqSaeed80
 
A practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinoldA practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinold
the_matrix
 
Introduction to Programming Using Java v. 7 - David J Eck - Inglês
Introduction to Programming Using Java v. 7 - David J Eck - InglêsIntroduction to Programming Using Java v. 7 - David J Eck - Inglês
Introduction to Programming Using Java v. 7 - David J Eck - Inglês
Marcelo Negreiros
 
javanotes5.pdf
javanotes5.pdfjavanotes5.pdf
javanotes5.pdf
kmspega
 
Introduction to c++ (cpp)
Introduction to c++ (cpp)Introduction to c++ (cpp)
Introduction to c++ (cpp)
Arun Umrao
 
Haltermanpythonbook.pdf
Haltermanpythonbook.pdfHaltermanpythonbook.pdf
Haltermanpythonbook.pdf
nebulaa2
 
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
EloquenFundamentalsof Web Developmentt_JavaScript.pdfEloquenFundamentalsof Web Developmentt_JavaScript.pdf
EloquenFundamentalsof Web Developmentt_JavaScript.pdf
kasperkey106
 
Fortran programming help book
Fortran programming help bookFortran programming help book
Fortran programming help book
Arun Umrao
 
Xcos simulation
Xcos simulationXcos simulation
Xcos simulation
Arun Umrao
 
Scilab help book 1 of 2
Scilab help book 1 of 2Scilab help book 1 of 2
Scilab help book 1 of 2
Arun Umrao
 
Algorithmic Problem Solving with Python.pdf
Algorithmic Problem Solving with Python.pdfAlgorithmic Problem Solving with Python.pdf
Algorithmic Problem Solving with Python.pdf
Emily Smith
 
452042223-Modern-Fortran-in-practice-pdf.pdf
452042223-Modern-Fortran-in-practice-pdf.pdf452042223-Modern-Fortran-in-practice-pdf.pdf
452042223-Modern-Fortran-in-practice-pdf.pdf
kalelboss
 
Debugger.pdf
Debugger.pdfDebugger.pdf
Debugger.pdf
BuTriLn
 
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdfA_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
ssuser7fcce2
 
A Practical Introduction To Python Programming
A Practical Introduction To Python ProgrammingA Practical Introduction To Python Programming
A Practical Introduction To Python Programming
Nat Rice
 
A practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinoldA practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinold
FaruqolayinkaSalako
 
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdfA_Practical_Introduction_to_Python_Programming_Heinold.pdf
A_Practical_Introduction_to_Python_Programming_Heinold.pdf
TariqSaeed80
 
A practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinoldA practical introduction_to_python_programming_heinold
A practical introduction_to_python_programming_heinold
the_matrix
 
Introduction to Programming Using Java v. 7 - David J Eck - Inglês
Introduction to Programming Using Java v. 7 - David J Eck - InglêsIntroduction to Programming Using Java v. 7 - David J Eck - Inglês
Introduction to Programming Using Java v. 7 - David J Eck - Inglês
Marcelo Negreiros
 
javanotes5.pdf
javanotes5.pdfjavanotes5.pdf
javanotes5.pdf
kmspega
 
Ad

More from ssuserd6b1fd (20)

Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
ssuserd6b1fd
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umrao
ssuserd6b1fd
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umrao
ssuserd6b1fd
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umrao
ssuserd6b1fd
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
ssuserd6b1fd
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umrao
ssuserd6b1fd
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
ssuserd6b1fd
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
ssuserd6b1fd
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun UmraoPrinciples of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
ssuserd6b1fd
 
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun UmraoLimit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Principle of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun UmraoPrinciple of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun Umrao
ssuserd6b1fd
 
Principle of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun UmraoPrinciple of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun Umrao
ssuserd6b1fd
 
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
Notes for c programming for mca, bca, b. tech cse, ece and msc (cs) 1 of 5 by...
ssuserd6b1fd
 
Decreasing increasing functions by arun umrao
Decreasing increasing functions by arun umraoDecreasing increasing functions by arun umrao
Decreasing increasing functions by arun umrao
ssuserd6b1fd
 
Distribution of normal data understanding it numerical way by arun umrao
Distribution of normal data   understanding it numerical way by arun umraoDistribution of normal data   understanding it numerical way by arun umrao
Distribution of normal data understanding it numerical way by arun umrao
ssuserd6b1fd
 
Decreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umraoDecreasing and increasing functions by arun umrao
Decreasing and increasing functions by arun umrao
ssuserd6b1fd
 
What is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun UmraoWhat is meaning of epsilon and delta in limits of a function by Arun Umrao
What is meaning of epsilon and delta in limits of a function by Arun Umrao
ssuserd6b1fd
 
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
Notes for GNU Octave - Numerical Programming - for Students - 02 of 02 by aru...
ssuserd6b1fd
 
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
Notes for C++ Programming / Object Oriented C++ Programming for MCA, BCA and ...
ssuserd6b1fd
 
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
Think Like Scilab and Become a Numerical Programming Expert- Notes for Beginn...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 5 of 5 by...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 4 of 5 by...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5  b...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 3 of 5 b...
ssuserd6b1fd
 
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 2 of 5 by...
ssuserd6b1fd
 
Work and Energy Notes by Arun Umrao
Work and Energy Notes by Arun UmraoWork and Energy Notes by Arun Umrao
Work and Energy Notes by Arun Umrao
ssuserd6b1fd
 
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun UmraoNotes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
Notes of Units, Dimensions & Errors for IIT JEE by Arun Umrao
ssuserd6b1fd
 
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun UmraoPhysics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
Physics dictionary for CBSE, ISCE, Class X Students by Arun Umrao
ssuserd6b1fd
 
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun UmraoMaxima & Minima of Functions - Differential Calculus by Arun Umrao
Maxima & Minima of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun UmraoPrinciples of Linear Motion of Objects - Physics - Explained by Arun Umrao
Principles of Linear Motion of Objects - Physics - Explained by Arun Umrao
ssuserd6b1fd
 
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun UmraoLimit & Continuity of Functions - Differential Calculus by Arun Umrao
Limit & Continuity of Functions - Differential Calculus by Arun Umrao
ssuserd6b1fd
 
Principle of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun UmraoPrinciple of Integration - Basic Introduction - by Arun Umrao
Principle of Integration - Basic Introduction - by Arun Umrao
ssuserd6b1fd
 
Principle of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun UmraoPrinciple of Integral Applications - Integral Calculus - by Arun Umrao
Principle of Integral Applications - Integral Calculus - by Arun Umrao
ssuserd6b1fd
 
Ad

Recently uploaded (20)

YSPH VMOC Special Report - Measles Outbreak Southwest US 4-30-2025.pptx
YSPH VMOC Special Report - Measles Outbreak  Southwest US 4-30-2025.pptxYSPH VMOC Special Report - Measles Outbreak  Southwest US 4-30-2025.pptx
YSPH VMOC Special Report - Measles Outbreak Southwest US 4-30-2025.pptx
Yale School of Public Health - The Virtual Medical Operations Center (VMOC)
 
How to Set warnings for invoicing specific customers in odoo
How to Set warnings for invoicing specific customers in odooHow to Set warnings for invoicing specific customers in odoo
How to Set warnings for invoicing specific customers in odoo
Celine George
 
Presentation on Tourism Product Development By Md Shaifullar Rabbi
Presentation on Tourism Product Development By Md Shaifullar RabbiPresentation on Tourism Product Development By Md Shaifullar Rabbi
Presentation on Tourism Product Development By Md Shaifullar Rabbi
Md Shaifullar Rabbi
 
THE STG QUIZ GROUP D.pptx quiz by Ridip Hazarika
THE STG QUIZ GROUP D.pptx   quiz by Ridip HazarikaTHE STG QUIZ GROUP D.pptx   quiz by Ridip Hazarika
THE STG QUIZ GROUP D.pptx quiz by Ridip Hazarika
Ridip Hazarika
 
Sinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_NameSinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_Name
keshanf79
 
apa-style-referencing-visual-guide-2025.pdf
apa-style-referencing-visual-guide-2025.pdfapa-style-referencing-visual-guide-2025.pdf
apa-style-referencing-visual-guide-2025.pdf
Ishika Ghosh
 
03#UNTAGGED. Generosity in architecture.
03#UNTAGGED. Generosity in architecture.03#UNTAGGED. Generosity in architecture.
03#UNTAGGED. Generosity in architecture.
MCH
 
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptxSCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
Ronisha Das
 
Biophysics Chapter 3 Methods of Studying Macromolecules.pdf
Biophysics Chapter 3 Methods of Studying Macromolecules.pdfBiophysics Chapter 3 Methods of Studying Macromolecules.pdf
Biophysics Chapter 3 Methods of Studying Macromolecules.pdf
PKLI-Institute of Nursing and Allied Health Sciences Lahore , Pakistan.
 
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - WorksheetCBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
Sritoma Majumder
 
Grade 2 - Mathematics - Printable Worksheet
Grade 2 - Mathematics - Printable WorksheetGrade 2 - Mathematics - Printable Worksheet
Grade 2 - Mathematics - Printable Worksheet
Sritoma Majumder
 
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
larencebapu132
 
Introduction-to-Communication-and-Media-Studies-1736283331.pdf
Introduction-to-Communication-and-Media-Studies-1736283331.pdfIntroduction-to-Communication-and-Media-Studies-1736283331.pdf
Introduction-to-Communication-and-Media-Studies-1736283331.pdf
james5028
 
To study the nervous system of insect.pptx
To study the nervous system of insect.pptxTo study the nervous system of insect.pptx
To study the nervous system of insect.pptx
Arshad Shaikh
 
2541William_McCollough_DigitalDetox.docx
2541William_McCollough_DigitalDetox.docx2541William_McCollough_DigitalDetox.docx
2541William_McCollough_DigitalDetox.docx
contactwilliamm2546
 
Engage Donors Through Powerful Storytelling.pdf
Engage Donors Through Powerful Storytelling.pdfEngage Donors Through Powerful Storytelling.pdf
Engage Donors Through Powerful Storytelling.pdf
TechSoup
 
Sugar-Sensing Mechanism in plants....pptx
Sugar-Sensing Mechanism in plants....pptxSugar-Sensing Mechanism in plants....pptx
Sugar-Sensing Mechanism in plants....pptx
Dr. Renu Jangid
 
Real GitHub Copilot Exam Dumps for Success
Real GitHub Copilot Exam Dumps for SuccessReal GitHub Copilot Exam Dumps for Success
Real GitHub Copilot Exam Dumps for Success
Mark Soia
 
"Basics of Heterocyclic Compounds and Their Naming Rules"
"Basics of Heterocyclic Compounds and Their Naming Rules""Basics of Heterocyclic Compounds and Their Naming Rules"
"Basics of Heterocyclic Compounds and Their Naming Rules"
rupalinirmalbpharm
 
Geography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjectsGeography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjects
ProfDrShaikhImran
 
How to Set warnings for invoicing specific customers in odoo
How to Set warnings for invoicing specific customers in odooHow to Set warnings for invoicing specific customers in odoo
How to Set warnings for invoicing specific customers in odoo
Celine George
 
Presentation on Tourism Product Development By Md Shaifullar Rabbi
Presentation on Tourism Product Development By Md Shaifullar RabbiPresentation on Tourism Product Development By Md Shaifullar Rabbi
Presentation on Tourism Product Development By Md Shaifullar Rabbi
Md Shaifullar Rabbi
 
THE STG QUIZ GROUP D.pptx quiz by Ridip Hazarika
THE STG QUIZ GROUP D.pptx   quiz by Ridip HazarikaTHE STG QUIZ GROUP D.pptx   quiz by Ridip Hazarika
THE STG QUIZ GROUP D.pptx quiz by Ridip Hazarika
Ridip Hazarika
 
Sinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_NameSinhala_Male_Names.pdf Sinhala_Male_Name
Sinhala_Male_Names.pdf Sinhala_Male_Name
keshanf79
 
apa-style-referencing-visual-guide-2025.pdf
apa-style-referencing-visual-guide-2025.pdfapa-style-referencing-visual-guide-2025.pdf
apa-style-referencing-visual-guide-2025.pdf
Ishika Ghosh
 
03#UNTAGGED. Generosity in architecture.
03#UNTAGGED. Generosity in architecture.03#UNTAGGED. Generosity in architecture.
03#UNTAGGED. Generosity in architecture.
MCH
 
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptxSCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
SCI BIZ TECH QUIZ (OPEN) PRELIMS XTASY 2025.pptx
Ronisha Das
 
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - WorksheetCBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
CBSE - Grade 8 - Science - Chemistry - Metals and Non Metals - Worksheet
Sritoma Majumder
 
Grade 2 - Mathematics - Printable Worksheet
Grade 2 - Mathematics - Printable WorksheetGrade 2 - Mathematics - Printable Worksheet
Grade 2 - Mathematics - Printable Worksheet
Sritoma Majumder
 
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
World war-1(Causes & impacts at a glance) PPT by Simanchala Sarab(BABed,sem-4...
larencebapu132
 
Introduction-to-Communication-and-Media-Studies-1736283331.pdf
Introduction-to-Communication-and-Media-Studies-1736283331.pdfIntroduction-to-Communication-and-Media-Studies-1736283331.pdf
Introduction-to-Communication-and-Media-Studies-1736283331.pdf
james5028
 
To study the nervous system of insect.pptx
To study the nervous system of insect.pptxTo study the nervous system of insect.pptx
To study the nervous system of insect.pptx
Arshad Shaikh
 
2541William_McCollough_DigitalDetox.docx
2541William_McCollough_DigitalDetox.docx2541William_McCollough_DigitalDetox.docx
2541William_McCollough_DigitalDetox.docx
contactwilliamm2546
 
Engage Donors Through Powerful Storytelling.pdf
Engage Donors Through Powerful Storytelling.pdfEngage Donors Through Powerful Storytelling.pdf
Engage Donors Through Powerful Storytelling.pdf
TechSoup
 
Sugar-Sensing Mechanism in plants....pptx
Sugar-Sensing Mechanism in plants....pptxSugar-Sensing Mechanism in plants....pptx
Sugar-Sensing Mechanism in plants....pptx
Dr. Renu Jangid
 
Real GitHub Copilot Exam Dumps for Success
Real GitHub Copilot Exam Dumps for SuccessReal GitHub Copilot Exam Dumps for Success
Real GitHub Copilot Exam Dumps for Success
Mark Soia
 
"Basics of Heterocyclic Compounds and Their Naming Rules"
"Basics of Heterocyclic Compounds and Their Naming Rules""Basics of Heterocyclic Compounds and Their Naming Rules"
"Basics of Heterocyclic Compounds and Their Naming Rules"
rupalinirmalbpharm
 
Geography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjectsGeography Sem II Unit 1C Correlation of Geography with other school subjects
Geography Sem II Unit 1C Correlation of Geography with other school subjects
ProfDrShaikhImran
 

Notes for C Programming for MCA, BCA, B. Tech CSE, ECE and MSC (CS) 1 of 5 by Arun Umrao

  • 1. 1 C PROGRAMMING AN INTRODUCTION Arun Umrao www.sites.google.com/view/arunumrao DRAFT COPY - GPL LICENSING
  • 2. 2 Contents 1 Basic C 3 1.1 Binary Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.1 Symbols & Charcodes . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.1.2 Decimal to Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Whole Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Decimal Fraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Indexing of Binary Digits . . . . . . . . . . . . . . . . . . . . . . . 8 1.1.3 Binary To Decimal . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Whole Binary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Binary Fraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.1.4 Memory Storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.2 Formatted I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.2.1 Print & Scan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 printf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 sprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Buffer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 scanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.2.2 Placeholders (Modifiers) . . . . . . . . . . . . . . . . . . . . . . . . 22 1.2.3 Escape Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 1.2.4 Quotes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 1.2.5 Comments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 1.2.6 Range Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 1.3 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 1.3.1 Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 Character & String Variables . . . . . . . . . . . . . . . . . . . . . 33 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 Integer Casting into Char . . . . . . . . . . . . . . . . . . . . . . . 38 Real Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 Float Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Double Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Long Decimals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 Long Double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Alias Data type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 Boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Declaration, Initialization & Assignment . . . . . . . . . . . . . . . 48 Float To Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 Signed & Unsigned Integer . . . . . . . . . . . . . . . . . . . . . . 57 Overflow of Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 Memory Size (sizeof) . . . . . . . . . . . . . . . . . . . . . . . . . . 63 Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 Scope of Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 1.3.2 Qualifiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 const Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 static Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
  • 3. 3 extern Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 volatile Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 auto Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 register Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 restrict Qualifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 attribute & pragma . . . . . . . . . . . . . . . . . . . . . . . . . 81 1.4 C Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 1.4.1 Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 1.4.2 Instructions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82 1.4.3 Unary Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 1.4.4 Binary Relation Operators . . . . . . . . . . . . . . . . . . . . . . 85 1.4.5 Comma Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 1.4.6 Bitwise Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 1.4.7 Logical Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 1.4.8 Shift Operator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 1.4.9 Condition & Relation Operators . . . . . . . . . . . . . . . . . . . 99 1.4.10 Lexical Comparison . . . . . . . . . . . . . . . . . . . . . . . . . . 100 1.4.11 Arithmetic Operators . . . . . . . . . . . . . . . . . . . . . . . . . 100 1.4.12 Relational Operators . . . . . . . . . . . . . . . . . . . . . . . . . . 103 1.4.13 Bit Field . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 1.5 Precedence of Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113 1.5.1 Precedence of Arithmetic Operators . . . . . . . . . . . . . . . . . 114 1.5.2 Precedence of Relational Operators . . . . . . . . . . . . . . . . . . 116 1.5.3 Precedence of All Operators . . . . . . . . . . . . . . . . . . . . . . 117 1.5.4 Precedence in Assignment . . . . . . . . . . . . . . . . . . . . . . . 118 1.5.5 Unary & Binary Operators . . . . . . . . . . . . . . . . . . . . . . 118 1.5.6 Associativity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 1.6 Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 1.6.1 If Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 1.6.2 If-else Condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 1.6.3 If-else-if Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 1.6.4 Switch & Case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126 1.6.5 Goto Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 1.6.6 Break Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 1.7 Iteration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 1.7.1 For Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 1.7.2 While Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135 1.7.3 For As While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 1.7.4 Do While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 1.8 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 1.8.1 Character Encoding . . . . . . . . . . . . . . . . . . . . . . . . . . 140 1.8.2 String Literal In Expression . . . . . . . . . . . . . . . . . . . . . . 140 1.8.3 String Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 strcat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 strchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 strcmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 strcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
  • 4. 4 strlen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147 strncat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 strncmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 strncpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 strrchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 strstr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 strtok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 strtod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 1.9 Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 1.9.1 Function Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . 157 1.9.2 Function Prototype . . . . . . . . . . . . . . . . . . . . . . . . . . 161 1.9.3 Function Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 1.9.4 Function Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . 167 1.9.5 Function As Argument . . . . . . . . . . . . . . . . . . . . . . . . . 169 1.9.6 Function Callback . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 1.9.7 Memory Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 mmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 File Access Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 memset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 memcpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 memmov . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 memchr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 memcmp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 1.9.8 Unicode Support . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 1.10 Procedures & Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 1.10.1 Code Optimisation . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 1.10.2 Increments & Decrements . . . . . . . . . . . . . . . . . . . . . . . 185 1.10.3 Static Function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190 1.10.4 Function with Variable Arguments . . . . . . . . . . . . . . . . . . 190 1.10.5 Indirect Call of Function . . . . . . . . . . . . . . . . . . . . . . . . 192 1.10.6 Preprocessor Macros . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Literals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193 Tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194 #if, #else, #elif, #endif . . . . . . . . . . . . . . . . . . . . . . . . 195 #ifdef & #ifndef . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197 #define . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 1.10.7 Type Converter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204 1.11 Parsing Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 1.11.1 Array To Integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208 1.12 Mathematis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209 1.12.1 Trigonometric Functions . . . . . . . . . . . . . . . . . . . . . . . . 210 cos, sin & tan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210 acos, asin & atan . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 cosh, sinh & tanh . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 acosh, asinh & atanh . . . . . . . . . . . . . . . . . . . . . . . . . . 213 1.12.2 Logarithm Function . . . . . . . . . . . . . . . . . . . . . . . . . . 213 Exponential & Logarithm . . . . . . . . . . . . . . . . . . . . . . . 213
  • 5. 5 1.12.3 Arithmetic Function . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Power . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Square Root . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215 Floor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216 Ceiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 Rounds Off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218 1.12.4 Float Point Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . 220 Operators in Float Points Arithmetic . . . . . . . . . . . . . . . . 222 Astray Result . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Double Floating Point . . . . . . . . . . . . . . . . . . . . . . . . . 224 1.12.5 Zero Crossing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 Limit At Zero . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224 1.12.6 Random Number Generator . . . . . . . . . . . . . . . . . . . . . . 225 2 Array & Pointer 227 2.1 Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227 2.1.1 Uni-Dimensional Array . . . . . . . . . . . . . . . . . . . . . . . . 227 2.1.2 Multi-Dimensional Array . . . . . . . . . . . . . . . . . . . . . . . 231 2.1.3 Array of Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 2.1.4 Array in Function . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 2.1.5 String As Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 2.1.6 Size of Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258 2.1.7 Vector & Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 2.1.8 Sparse Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 2.2 Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 2.2.1 Declaring pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 Assigning values to pointers . . . . . . . . . . . . . . . . . . . . . . 270 Pointer Dereferencing (Value Finding) . . . . . . . . . . . . . . . . 273 Addition of pointers . . . . . . . . . . . . . . . . . . . . . . . . . . 275 Passing of Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 2.2.2 Pointers and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 279 Pointers to Multidimensional Arrays . . . . . . . . . . . . . . . . . 283 Pointers as Function Argument . . . . . . . . . . . . . . . . . . . . 284 Address as Function Argument . . . . . . . . . . . . . . . . . . . . 288 Pointer Equivalent to Array . . . . . . . . . . . . . . . . . . . . . . 291 2.2.3 Pointers and Text Strings . . . . . . . . . . . . . . . . . . . . . . . 295 Pointers to Function . . . . . . . . . . . . . . . . . . . . . . . . . . 297 Casting of Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 Address Copying Vs Content Copying . . . . . . . . . . . . . . . . 303 2.2.4 Dangling & Wild Pointers . . . . . . . . . . . . . . . . . . . . . . . 304 2.2.5 Pointer, Variable & Address . . . . . . . . . . . . . . . . . . . . . . 305 2.2.6 Constant Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . 309 2.2.7 Memory Allocation . . . . . . . . . . . . . . . . . . . . . . . . . . . 312 Dynamic Memory Allocation . . . . . . . . . . . . . . . . . . . . . 312 Reallocate Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 2.2.8 Pointer Arithmetic . . . . . . . . . . . . . . . . . . . . . . . . . . . 316 2.2.9 Pointer Address . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
  • 6. 6 2.2.10 Pointer to Pointer . . . . . . . . . . . . . . . . . . . . . . . . . . . 325 int *p[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 int **p[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 int (*p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337 int (**p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 int *(*p)[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338 int (*p[ ])[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 int *p(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340 int (*p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 int (**p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 int *(*p)(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 int (*p())(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343 int (*p[ ])(); . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344 int (*p())[ ]; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 2.2.11 Pointer Casting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 346 2.2.12 Pointer as Structure . . . . . . . . . . . . . . . . . . . . . . . . . . 347 3 File & Data Structure 349 3.1 Input Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 3.1.1 Handling File Directory . . . . . . . . . . . . . . . . . . . . . . . . 349 3.1.2 Change Directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 3.1.3 FILE pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350 Locking & Unlocking a File . . . . . . . . . . . . . . . . . . . . . . 351 Reading/Scanning Directory . . . . . . . . . . . . . . . . . . . . . 353 Open a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 Close a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 356 Reading File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 Writing File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 Remove & Rename a File . . . . . . . . . . . . . . . . . . . . . . . 383 Resize a File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 File Pointer as Function Argument . . . . . . . . . . . . . . . . . . 386 Low Level Input/Output . . . . . . . . . . . . . . . . . . . . . . . 387 3.2 Symbol Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 3.3 Data Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 3.3.1 Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391 Nested Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 Structure As Arguments . . . . . . . . . . . . . . . . . . . . . . . . 408 Multi-Dimensional Struct . . . . . . . . . . . . . . . . . . . . . . . 410 Return Structure from Function . . . . . . . . . . . . . . . . . . . 414 3.3.2 Enumerate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415 3.3.3 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 3.3.4 Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 Push A Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Pop A Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421 Array in Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 String in Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 3.3.5 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
  • 7. 7 Create Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 Delete Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 Update Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 Access Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 3.3.6 Link List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 Linked List (Array) . . . . . . . . . . . . . . . . . . . . . . . . . . 427 Linked List (Pointer) . . . . . . . . . . . . . . . . . . . . . . . . . . 430 3.3.7 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 437 Construction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 438 Add/Insert an Element . . . . . . . . . . . . . . . . . . . . . . . . 438 Remove an Element . . . . . . . . . . . . . . . . . . . . . . . . . . 439 3.3.8 Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 Create Tree Structure . . . . . . . . . . . . . . . . . . . . . . . . . 440 Insert Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Display Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . 441 Delete Tree Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442 3.3.9 Binary Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 4 Miscellaneous 447 4.1 Error Handling Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 4.1.1 clearerr function . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 4.1.2 ferror function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 4.1.3 perror function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 4.1.4 Segmentation Fault . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 4.2 Reserved Keyword . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 4.3 Case Sensitivity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 4.4 Commenting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 5 Library 453 5.1 Through NetBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 5.1.1 Create Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 5.1.2 Link Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 5.2 From Command Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 5.2.1 Create Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454 5.2.2 Link Library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 455 5.3 Load Library Dynamically . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
  • 9. 1.1. BINARY ARITHMETIC 9 1Basic C C is a technically low level programming and backbone of computer & information technology. Every device has at least one part that functions on the platform of C. Now we will study the basic functionality and procedure of C. C must be practiced by every person who want to learn Computer Programming because C like procedure and functions are used in all languages developed on C Platform (like Matlab, Octave, Scilab, PHP, Java, Python, MySQL and Ruby etc). The compiler used in this book is ‘gcc’ in ‘cygwin’ environment. Algorithm is a prescription to solve a problem, which, provided it is faithfully executed yields the result in a finite number of steps. Programming Gives a means to translate the algorithm into a set of instructions that can be understood by the computer. 1.1 Binary Arithmetic A number that is formed by using digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 are called decimal numbers. A number consists only digits 0 and 1 are called binary number. Base of decimal number is 10, and base of binary number is 2. Some other numbers, those are used in computers are octal and hexadecimal numbers whose base is 8 and 16 respectively. The sequences of digits of a number system are used to form a number of that number system. For example, sequence of digits 9, 0, 1 and 2 of decimal number system form a number with face value 9012. Similarly, sequence of digits 1, 0, 1 and 0 of binary number system form a number with face value 1010. Number Digits In a number system, the distinct symbols or digits, which are used to construct a number of the number system are called number digits of that number. For example, in decimal form of number system, digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9 are used. In binary form of number system, digits 0 and 1 are used. Similarly, in octal form of number system, digits 0, 1, 2, 3, 4, 5, 6 and 7 are used. And in hexadecimal number system, digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e and f are used. Base of Number Base of a number system is number of distinct digits present in that number system. For example, there are ten distinct digits in decimal form of number system. Hence its base is ‘10’. In binary form of number system, there are two distinct digits, hence base of binary number system is ‘2’. Similarly, base of octal and hexadecimal form of number systems are ‘8’ and ‘16’ respectively. Place Value Place value of a digit of a number in a given number system, is digit times to the exponent power of its place index to base of the number system. Place index is an integer ranging from 0 to n from right to left for whole part of the number and −1 to −n from left to right for its fraction part. See the figure below:
  • 10. 10 Basic C 103 102 101 100 b 10−1 10−2 10−3 10−4 Figure 1.1: Place values in decimal form of number system. In above figure, dot (·) represents to decimal symbol separating whole part from fractional part of the given number. In decimal form of number system, the place value at an index is 10 times larger than its right side value and 10 times lesser than its left side value. If a given number is 213.45 then the place values of its digits are given by 2 × 102 2 1 × 101 1 3 × 100 3 b 4 × 10−1 4 5 × 10−2 5 Figure 1.2: Place values of digits of number 213.45. In above figure, dot (·) represents to decimal symbol separating whole part (213) from fractional part (45) of the given number 213.45. 1.1.1 Symbols & Charcodes In human languages, symbols are scripture when pronounced by those who can identify then gave unique sound or meaning. For example, in Hindi, character ‘ka’ gives unique sound and meaning when it is pronounced or written by anyone. The symbols are classified as alphabetic, numeric or special symbols etc. Alphabetic symbols are a to z, numeric symbols are 0 to 9 and special symbols are &, #, % etc. These symbols are identified by humans. In, computers, these symbols have no meaning. The computer communicates using electro-magnetic waves like t I A wave have two half cycles in which one is in positive y-axis side and other is in neg- ative y-axis side. Electronic devices observe these two half cycles during communication. The positive half cycle is denoted by ‘1’ and negative half cycle is denoted by ‘0’. Thus all the electronic symbols are constructed by using these two digits, commonly known as binary digits.
  • 11. 1.1. BINARY ARITHMETIC 11 t I digit 1 digit 0 In digital devices, communication waves are in square shape. Binary digits ‘1’ and ‘0’ are plotted in square wave form as shown below: t I digit 1 digit 0 These two binary digits are called bits. For human machine communication, i.e. communication between human symbols and electrics wave is done by digital coding of the symbols. In the following table, all human readable symbols are coded from 1 to 128 with numeric base 10. Dec Description Dec Description Dec Description 0 Null character 11 Vertical Tab 22 Synchronous idle 1 Start of Header 12 Form feed 23 End of transmission block 2 Start of Text 13 Carriage return 24 Cancel 3 End of Text 14 Shift Out 25 End of medium 4 End of Transmission 15 Shift In 26 Substitute 5 Enquiry 16 Data link escape 27 Escape 6 Acknowledgment 17 Device control 1 28 File separator 7 Bell 18 Device control 2 29 Group separator 8 Backspace 19 Device control 3 30 Record separator 9 Horizontal Tab 20 Device control 4 31 Unit separator 10 Line feed 21 Negative acknowledgement 127 Delete Table 1.1: Non Printable Character Codes (ASCII)
  • 12. 12 Basic C Dec Sym Sym Dec Sym Dec Sym Dec Sym Dec Sym Dec 32 48 0 64 @ 80 P 96 ‘ 112 p 33 ! 49 1 65 A 81 Q 97 a 113 q 34 50 2 66 B 82 R 98 b 114 r 35 # 51 3 67 C 83 S 99 c 115 s 36 $ 52 4 68 D 84 T 100 d 116 t 37 % 53 5 69 E 85 U 101 e 117 u 38 & 54 6 70 F 86 V 102 f 118 v 39 ’ 55 7 71 G 87 W 103 g 119 w 40 ( 56 8 72 H 88 X 104 h 120 x 41 ) 57 9 73 I 89 Y 105 i 121 y 42 * 58 : 74 J 90 Z 106 j 122 z 43 + 59 ; 75 K 91 [ 107 k 123 { 44 , 60 ¡ 76 L 92 108 l 124 | 45 - 61 = 77 M 93 ] 109 m 125 } 46 . 62 ¿ 78 N 94 ˆ 110 n 126 ∼ 47 / 63 ? 79 O 95 111 o 127 Table 1.2: Printable Character Codes (ASCII) In above table, each symbol is coded as decimal number and this decimal code is called character code of the given symbol. In mathematics, numbers are convertible between different bases. For example, decimal numbers have base ‘10’ while binary numbers have base ‘2’. Base of a number is that count upto which numeric digits are available to con- struct a number. For decimal numbers, there are ten digits available for construction of numbers. Similarly for binary numbers, there are two digits; for hexadecimal numbers, there are sixteen digits and for octal numbers there are eight digits available for construc- tion of respective numbers. A well known number conversion is decimal to binary and vice-versa. During communication, when we press a symbol, it is lookup into the symbol-decimal table. The character codes of the pressed symbol is converted into equivalent binary number. Now, a signal wave is generated representing the binary number. This signal wave is accepted by computer assuming that it is that symbol which was pressed by user. To understand the above statements, we will solve few problems. Solved Problem 1.1 Draw a plot showing binary digits ‘1’ and binary digit ‘0’ assuming wave width for one bit as one centimeter. Solution The plot for digits ‘1’ and binary digit ‘0’ assuming wave width one cen-
  • 13. 1.1. BINARY ARITHMETIC 13 timeter is shown below: t I 1 1 0 1 0 Solved Problem 1.2 Using the symbol-code table, find the character code of the symbols ‘c’, ‘C’ and ‘k’. Solution From the ASCII character table, the character codes of symbols ‘c’, ‘C’ and ‘k’ are 99, 67 and 107 respectively. 1.1.2 Decimal to Binary As computer can understood only binary numbers hence conversion of humane under- standable numbers into computer understandable number is required. In following sec- tions, method of number conversion is given. Whole Integer If decimal number is a whole decimal number then it can be converted into binary number by dividing it by 2 and writing remainders in reverse direction. First the number is divided by 2 and the quotients are also subsequently divided by 2 until, quotient becomes zero. See example of conversion of (25)10 into binary number. 25/2 12/2 6/2 3/2 1/2 0 Quotient 12 6 3 1 0 Remainder 1 0 0 1 1 Bit Order ←− Table 1.3: Decimal to binary conversion. Now write the remainders in reverse order. The binary equivalent to the decimal 25 is 2510 = 0110012 (1.1) Decimal Fraction If number is in decimal fraction, then decimal to binary conversion is take place by multiplying fraction with two and writing whole number as binary bit and fraction again as decimal fraction. This process undergoes until fraction becomes zero or a ordered
  • 14. 14 Basic C sequence is obtained. An example of binary conversion of decimal number 0.2510 is given below. 0.25 × 2 0.5 × 2 0.0 × 2 Result 0.5 1.0 0.0 Fraction Part 0.5 0 Whole Part 0 1 Bit Order −→ Table 1.4: Decimal fraction to binary conversion. Now write the remainders in forward order by prefixing decimal sign ·. The binary equivalent to the decimal fraction 0.25 is 0.2510 = 0.012 (1.2) Indexing of Binary Digits Binary digits are used in computer science. The normal object counting is started from 1 to n if there are object other wise objects are assumed as zero or nil. But, in computer science, the counting is started from 0 to n not from 1 to n if there are objects otherwise objects are assumed as NULL. In computer science zero is nil and NULL is never exist. Hence Least Significant Bit (LSB) digits is always indexed as 0 and Most Significant Bit (MSB) digits is indexed as n − 1 in n bits binary number. The ordered counting or place counting of binary bits in a binary number is always started from zero index. D7 D6 D5 D4 D3 D2 D1 D0 MSB LSB 1 1 1 1 1 1 1 1 Table 1.5: 8 bits binary number. Bits are indexed from D0 to D7. Solved Problem 1.3 Identify the D5 bit in the binary number 1101102. Solution In the binary number 1101102, the D5 bit is bit 1. For more clarity, see the below bits arrangement. D7 D6 D5 D4 D3 D2 D1 D0 MSB LSB 0 0 1 1 0 1 1 0 Table 1.6: 8 bits binary number. Bits are indexed from D0 to D7.
  • 15. 1.1. BINARY ARITHMETIC 15 Solved Problem 1.4 Convert decimal number 124 into binary number and identify the 5th bit or D4 bit from LSB side. Solution In the decimal 124 on binary conversion gives 11111002. The 5th bit or D4 bit from LSB side is bit 1. For more clarity, see the below bits arrangement. D7 D6 D5 D4 D3 D2 D1 D0 MSB LSB 0 1 1 1 1 1 0 0 Table 1.7: 8 bits binary number. Bits are indexed from D0 to D7. 1.1.3 Binary To Decimal Binary to decimal conversion of numbers is required to understand computer’s numerical easily by humans. Binary to decimal conversion for whole and fraction binary number is discussed in followings sections. Whole Binary Suppose we have a binary number 1010012 and it is to be converted into decimal equiv- alent. Now we do following process in binary to decimal conversion. 1010012 = 1 × 25 + 0 × 24 + 1 × 23 + 0 × 22 + 0 × 21 + 1 × 20 = 32 + 0 + 8 + 0 + 0 + 1 = 4110 (1.3) In binary to decimal conversion power of base 2 increases from zero to one less in maximum bit numbers, i.e. if there are n bits in a binary number then power of base 2 increases from 0 to n − 1. Zero power in base, is raised in right most bit and max power is raised in left most bit. Binary Fraction Suppose we have a fraction binary number 0.1012 and it is to be converted into decimal equivalent. Now we do following process in binary to decimal conversion. 0.1012 = 1 × 2−1 + 0 × 2−2 + 1 × 2−3 = 0.5 + 0 + 0.125 = 0.62510 (1.4) In binary to decimal conversion power of base 2 decreases from negative one to the negative of bits in fraction binary number, i.e. if there are n bits in a fraction binary number then power of base 2 decreases from −1 to −n. (−1) power in base, is raised in left most bit
  • 16. 16 Basic C and (−n) power is raised in right most bit. If binary number is in compound form i.e. 11010.11012 then it can be converted into equivalent decimal number by solving whole part and fraction part separately or by commonly. Decimal conversion in separation of whole part 110102 and fraction part 0.11012 can done by method described above. If we have to convert compound binary number as a whole then 1010.112 = 1 × 23 + 0 × 22 + 1 × 21 + 0 × 20 + 1 × 2−1 + 1 × 2−2 = 8 + 0 + 2 + 0 + 0.5 + 0.25 = 10.7510 (1.5) In above conversion, power of base 2 successively increases according to the number line when we observe it from right to left. Solved Problem 1.5 Using the symbol-code table, find the character code of the symbols ‘C’ and convert into equivalent binary number. Solution The character code of symbol ‘C’ in decimal number is 67. Its binary equivalent is 010000112. Solved Problem 1.6 Using the symbol-code table, find the character code of the symbols ‘Z’ and convert into equivalent binary number and signal wave assuming wave width for one bit as one centimeter. Solution The character code of symbol ‘Z’ in decimal number is 90. Its binary equivalent is 010110102. The equivalent signal waveform is given below: t I 0 1 0 1 1 0 1 0 1.1.4 Memory Storage Binary data of computers stored in permanent memory in binary form as shown in the following figure. 1000101000111110101011101010111010101000 This arrangement of binary digits has no meaning. This is due to mainly two reasons (i) how many bits should be taken to reconstruct the character code which was converted into binary digits and stored in the memory and (ii) the binary data is not readable. It has no limiting value. To overcome these problem, binary data is grouped into fixed number of bits. These groups are called datatypes. See the table given below:
  • 17. 1.1. BINARY ARITHMETIC 17 Bits Data Type Size (bytes) 1 Bit 4 Nibble 8 Byte 1 16 Short 2 32 Integer 4 64 Long, double 8 Table 1.8: Data Types. The primary unit of memory space is byte, and each byte acts as a memory cell, housing 8 bits data. If above memory data is arranged in bytes, then it looks like. 10001010 00111110 10101110 10101110 10101000 Though the data is arranged in cells of fixed size. But location of data is undefined. Thus each memory cell is assigned an address which is unique location of the memory cell. 0×51 0×52 0×53 0×54 0×55 10001010 00111110 10101110 10101110 10101000 Now we can read or write data on the memory cell which is identified by its address. Note that, a byte is group of 8 bits, hence data types like bit and nibble are used to access the bits within a memory cell (byte) and data types like byte, integer etc are used to access data between the cells (bytes). Data types do not change data while reading it from memory but they interpret it differently. For example, in the memory arrangement 0×51 0×52 0×53 0×54 0×55 10001010 00111110 10101110 10101110 10101000 if data type is byte, then it read data byte by byte. Starting from the address 0×51, it reads binary data from one byte at address 0×51, i.e. 100010102 and convert it into equivalent decimal number, which is 13810. Now, computer returns character symbol whose character code is 138. Further we can read next data bytes. If data type is integer type, then it reads four bytes at once. So, starting from the address 0×51, it reads binary data from four bytes at once, i.e. 100010100011111010101110101011102 and convert it into equivalent decimal number, which is 231936375810. It can not be converted into equivalent character symbol as it is beyond the size of characters. Note that, each variable starts reading data from its first address and it reads data upto number of bytes which is equal to the size of the variable data type. Hence only first byte address is important.
  • 18. 18 Basic C Solved Problem 1.7 The binary data 1001010110000101010000012 is stored in memory from the address 0×0501. A variable of short data type access this data from the address 0×0502. What will be the value assigned to this variable? Solution The variable of short type will read data in group of two bytes. 0×0500 0×0501 0×0502 0×0503 0×0504 10010101 10000101 01000001 So, it will read two bytes data started from the address of 0×0502. The value assigned to this variable will be 10000101010000012 in binary or in equivalent decimal 854110. 1.2 Formatted I/O A program can received input from its console and puts result in the console after pro- cessing. In C, printf is used to put the formatted data in output stream and scanf is used to receive data from input stream. 1.2.1 Print & Scan Here we will study the inbuilt functions of C which are used to take and put data from console. Later, we construct own functions. Here is simple C program. ✞ 1 /* Include header files , It have predefined functions .*/ #include <stdio.h> 3 int main (void ) { 5 /* print at console */ printf("Hello , world!n"); 7 /* return true value*/ 9 return 0; } ✌ ✆ When program runs, output of the program appears in console window. Here it is ✞ Hello , world! ✌ ✆ In above example, ✞ 1 #include <stdio.h> ✌ ✆ tells to C compiler to find the standard header file stdio.h globally and include it to the program. stdio.h contains description of standard input/output functions which we can use to sent messages to a user or to read input from a user. ✞ 1 #include <stdio.h> #include "stdio.h" ✌ ✆
  • 19. 1.2. FORMATTED I/O 19 If a header file is encapsulated between < and > symbols, then compiler searches the header file in default header directory. Similarly, if the header file is encapsulated between double quotes (“ ... ”), then compiler searches the header file in local program/project directory. ✞ int main (void ) ✌ ✆ is the main function which is automatically invoked when program runs. It is also an entry point of the program, from where a program starts running. In other words, the mnemonic instructions of program are executed from the beginning of address of main() function. Prefix int to main() function has meaning that main() function will return an integer to the operating system when it is finished. Though the default return value of main() function is integer but return value as void is also acceptable. The returns value of main() function tells the OS about the run state of the program. On successful complete run of the program, it returns 0 otherwise it returns error code. The compiler shows warning when return value from the main function is not integer. ✞ 1 printf("Hello , world!"); ✌ ✆ is the statement that actually puts the message to the screen. printf is the formatted printing function that is declared in the header file stdio.h. ✞ 1 return 0; ✌ ✆ will return zero to the operating system. ‘Return of 0 is indication of successful execution of program. Return value other than ‘0’ indicates run failure or error in execution of program. C uses conventional code grouping structure. A function or a code block are grouped by curly braces, ie {...}. All the variable defined inside the group {...} have local scope. A semicolon is used to terminate the line. ✞ 1 /* The main function */ int main (void ){ 3 /* This is the beginning of a ‘block’*/ int i = 6; /* It is first variable of this ‘block’*/ 5 { /* Start of new block. */ /* This is a new ‘block’, and because it’s * 7 * a different block it has its own scope. */ 9 /* This is also a variable called ‘i’, * * but in a different ‘block ’, because * 11 * it’s in a different ‘block’ than the * * old ’i’, it doesn’t affect the old one!*/ 13 int i = 5; printf("%dn", i); /* Prints ‘5’ in the screen */ 15 } /* End of new block. */ 17 /* Now we’re back into the old block */ printf("%dn", i); /* Prints ‘6’ in the screen */ 19 return 0;
  • 20. 20 Basic C 21 } ✌ ✆ Also see the example given below. ✞ 1 #include <stdio.h> 3 int main () { int x = 1; /* Original x */ 5 printf("x in outer block: %dn", x); 7 { /* Begin of new block. */ int x = 2; /* New x, hides original x */ 9 printf("x in inner block: %dn", x); } /* End of new block. */ 11 printf("x in outer block: %dn", x); for(;x < 5;x++){ /* Original x */ 13 int x = 10; /* New x, hides original x */ x++; 15 printf("x in while loop : %dn", x); } 17 printf("x in outer block: %dn", x); return 0; 19 } ✌ ✆ ✞ x in outer block: 1 x in inner block: 2 x in outer block: 1 x in while loop : 11 x in while loop : 11 x in while loop : 11 x in while loop : 11 x in outer block: 5 ✌ ✆ printf This function is used to print stuff in console output. Use of this function is shown in the example given below: ✞ #include <stdio.h> 2 int main (void ) { printf("Hello , world!n"); 4 return 0; } ✌ ✆ On execusion of the program output will be looked like ✞ Hello , world! ✌ ✆
  • 21. 1.2. FORMATTED I/O 21 sprintf It composes a formatted string and instead printing it in console. It copies string into buffer. It takes values of third parameter in accordance to its second parameter and converts result into string (i.e. sequece of characters). Now, finally, the converted string is copied into the buffer parameter. The syntax of this function is given below: ✞ 1 n = sprintf (<buff >, <format >, <inputs >) ✌ ✆ The size of the buffer should be large enough so that it can contain the entire resulting string. A terminating null character is automatically appended after the content. If formatted string is copied into buffer successfully, length of copied string is returned by the function. On failure negative integer is returned. ✞ 1 #include <stdio.h> 3 int main () { char buffer [20]; 5 int n, a = 2, b = 3; n = sprintf (buffer , "%d * %d = %d", a, b, a * b); 7 printf("Length of string [%s] is %d.n", buffer , n); return 0; 9 } ✌ ✆ ✞ Length of string [2 * 3 = 6] is 9. ✌ ✆ Same example with change in format of inputs, gives completely different result. ✞ 1 #include <stdio.h> 3 int main () { char buffer [50]; 5 double n, a = 2, b = 3; n = sprintf (buffer , "%f * %f = %f", a, b, a * b); 7 printf("Length of string [%s] is %f.n", buffer , n); return 0; 9 } ✌ ✆ ✞ Length of string [2.000000 * 3.000000 = 6.000000] is 30.000000. ✌ ✆ Here, decimal zeros are also converted into their respective characters. In the following example, sprintf function replaces the desired character or string with supplied character or string. In this example recursive replacement of a character or string takes places until all characters are replaced. ✞ 1 #include <stdio.h> #include <string.h> 3 int main (int argc , char *argv [ ]) { 5 char st [100] = "This is my string.";
  • 22. 22 Basic C char r_it [2] = "s"; 7 char repl [12] = "1.2"; char buffer [4096]; 9 char *ch; // printf ("b:%sn", st); 11 while (ch = strstr(st , r_it )) { strncpy (buffer , st , ch - st); 13 // printf("d:%sn", buffer); buffer[ch - st] = 0; 15 sprintf (buffer + (ch - st), "%s%s", repl , ch + strlen(r_it )); 17 if (ch != NULL ) strcpy(st , buffer); 19 } printf("The makeup string is :n %s", buffer); 21 return 0; } ✌ ✆ ✞ Thi 1.2 i1.2 my 1.2 tring. ✌ ✆ This makeup of string is very useful in the mathematical computation. In algebraic equations, the variables and constants are required to be replaced by their numerical values. Buffer “Buffer” is one of the common words used in C programs. Now a question rises about the buffer, its constitution and its applications. Buffer is specific region of memory where data is stored temporarily for internal processes and after processes it is flushed in instream or outstream of the system. For example, consider a small program, ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 int i, j; i = 10; 7 j = 2*i; return 0; 9 } ✌ ✆ in which two integer type variables ‘i’ and ‘j’ stores value 10 and 20. We want to get output be printed in output console as ✞ 10,20 ✌ ✆ Here, first we have to store value of ‘i’ temporarily in memory but should not be appeared in output console. For this, we have to create a memory array space of sufficient size (here 10 bytes long).
  • 23. 1.2. FORMATTED I/O 23 ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 char buff [10]; char tb [4]; 7 int i, j; i = 10; 9 return 0; } ✌ ✆ The memory space shall be looked like, 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49 buff Now, store value of ‘i’ in this created memory space at the beginning of the buff pointer. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { char buff [10];// space of 11 bytes 6 char tb [4]; int i, j; 8 i = 10; sprintf (tb , "%d", i);// formatted string ’10’ 10 strncpy (buff , tb , 4);// copy into buff from tb return 0; 12 } ✌ ✆ sprintf function converts an integer value into sequence of one byte long characters. For example, 4 bytes long integer, i.e. ‘10’ is converted into string of characters ‘1’ and ‘0’ respectively. Note that, previously, integer ‘10’ occupies four bytes as it was an integer value, now occupies only two bytes as it is converted into sequence of characters depicting a strings. The memory space shall be looked like, 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49 buff 00000001 00000000 Now, store comma after the memory cell where value of ‘i’ is stored in the buffer memory as desired output is required. ✞ #include <stdio.h>
  • 24. 24 Basic C 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { char buff [10];// space of 11 bytes 6 char tb [4]; int i, j; 8 i = 10; sprintf (tb , "%d", i); 10 strncpy (buff , tb , 4); sprintf (tb , "%c", ’,’);// append comma 12 strcat(buff , tb); // concatenate string return 0; 14 } ✌ ✆ The memory space shall be looked like, 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49 buff 00000001 00000000 00101100 Now, store value of 2 × i after the memory cell where character comma is stored in memory. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { char buff [10];// space of 11 bytes 6 char tb [4]; int i, j; 8 i = 10; sprintf (tb , "%d", i); 10 strncpy (buff , tb , 4); sprintf (tb , "%c", ’,’); 12 strcat(buff , tb); sprintf (tb , "%d", 2 * i); 14 strcat(buff , tb); // append ’20’ return 0; 16 } ✌ ✆ The memory space shall be looked like, 0×40 0×41 0×42 0×43 0×44 0×45 0×46 0×47 0×48 0×49 buff 00000001 00000000 00101100 00000010 00000000 Our buffer of desired shape is generated. Now, it can be flushed into output stream so that, it may appear in output console.
  • 25. 1.2. FORMATTED I/O 25 ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (int argc , char ** argv ) { char buff [10];// space of 11 bytes 6 char tb [4]; int i, j; 8 i = 10; sprintf (tb , "%d", i); 10 strncpy (buff , tb , 4); sprintf (tb , "%c", ’,’); 12 strcat(buff , tb); sprintf (tb , "%d", 2 * i); 14 strcat(buff , tb); printf("%sn", buff ); // get buffer string 16 return 0; } ✌ ✆ The desired output is ✞ 10,20 ✌ ✆ scanf On simplest invocation, the scanf format string holds a single placeholder representing the type of value that will be entered by the user. scanf examines the input characters from input stream and ignores space, tab, newline, enter and for feed characters etc. ✞ 1 #include <stdio.h> 3 int main (void ) { int a; 5 printf("Write an integer : "); /*& operator is used to assign * 7 *address to the integer value.*/ scanf("%d", &a); 9 printf("Integer value entered is %d.n", a); return 0; 11 } ✌ ✆ Output of the programm is ✞ Write one integer value :1 Integer value passed by you is 1. ✌ ✆ If a string is scanned by using scanf, ‘&’ operator is not prefixed to the character variable. A utility program, that is not designed with printf and scanf mechanism, when it is compiled and run then what ever is written in the output console in a line is read and scanned by the utility. To terminate an input line in output console, enter key is
  • 26. 26 Basic C pressed. To get output Ctrl+Z or Ctrl+C or Ctrl+X is pressed. If scanf is used to scan a string or an array to the character variable ‘str’, then it is used as ✞ scanf("%s", str) ✌ ✆ It is equivalent to array scanning ✞ 1 scanf("%s", &str [0]) ✌ ✆ If the function is used like ✞ 1 scanf("%s", &str) ✌ ✆ then to scanf, string is passed to a pointer-to-char[256], but it points to the same place. As scanf stops input stream when it encounters with tab, newline, enter etc. Similarly, when scanf starts scanning a string having with white spaces then scanf stops reading string when it encounters white space. See the example below: ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { char str [10]; 5 printf("Enter string : "); int n = scanf("%s", str); 7 printf("Status and string is :=> "); printf("%d : %sn", n, str); 9 return 0; } ✌ ✆ ✞ Enter string : arun kr Status and string is :=> 1 : arun ✌ ✆ To overcome this problem, scanf is used as ✞ scanf("%[^< input terminating character >]", <var >); ✌ ✆ Here, less than and greater than signs represent beginning and ending of terminating character. The line terminating character must be preceded by carat character ‘ˆ’ and both should be enclosed in square braces. See the example below ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { char str [10]; 5 printf("Enter string ending with ~ : "); /* Scan the string until ~ not found.*/ 7 int n = scanf("%[^~]", str); printf("Status and string is :=> "); 9 printf("%d : %sn", n, str); return 0; 11 } ✌ ✆
  • 27. 1.2. FORMATTED I/O 27 The input string on console is “i am king∼” and output is printed as ✞ Enter string ending with ~ : i am king ~ Status and string is :=> 1 : i am king ✌ ✆ scanf also accepts escape characters for termination of inputs. When escape character is found by scanf, it stops scanning of inputs. See the example given below: ✞ #include <stdio.h> 2 int main (int argc , char *argv [ ]) { 4 char str [30]; printf("Enter string & press enter key : "); 6 /* Scan the string until new line * *escape character is not found.*/ 8 int n = scanf("%[^ n]", str); printf("Status and string is :=> "); 10 printf("%d : %sn", n, str); return 0; 12 } ✌ ✆ ✞ Enter string & press enter key : This is my key Status and string is :=> 1 : This is my key ✌ ✆ Another example with tab escape character, which is used as termination of input for scanf function. ✞ #include <stdio.h> 2 int main (int argc , char *argv [ ]) { 4 char str [30]; printf("Enter string & press enter key : "); 6 /* Scan the string until tabular * *escape character is not found.*/ 8 int n = scanf("%[^ t]", str); printf("Status and string is :=> "); 10 printf("%d : %sn", n, str); return 0; 12 } ✌ ✆ ✞ Enter string & press enter key : This is my string Status and string is :=> 1 : This is ✌ ✆ Asterisk character ‘*’ when placed between the ‘%’ sign and typedef character then the corresponding input is ignored. ✞ #include <stdio.h> 2 int main (int argc , char *argv [ ]) { 4 int i, j, k;
  • 28. 28 Basic C printf("Enter three integers with spaces : "); 6 scanf("%d %d %*d", &i, &j, &k); printf("Integers are n"); 8 printf("%dt%dt%dn", i, j, k); return 0; 10 } ✌ ✆ ✞ Enter three integers with spaces : 12 58 4 Integers are 12 58 0 ✌ ✆ As third input ‘k’ is ignored by scanf hence address of the ‘k’ variable or 0 is printed rather than its value. 1.2.2 Placeholders (Modifiers) Placeholders are group of symbol(s) and are used to put the values at the place of place- holder as per specified modifiers. For example, ‘%d’ is used to put integers, ‘%ld’ for long integers, ‘%lli’ for long long integer, ‘%f’ for float integers, ‘%lf’ for double integers, ‘%c’ for characters, ‘%s’ for strings and ‘%x’ for hexadecimal. ✞ 1 #include <stdio.h> 3 int main (void ){ int i; 5 for(i = 0; i<2; i++) printf("Integer value is %d.n", i); 7 return 0; } ✌ ✆ Output of above script is ✞ Integer value is 0. Integer value is 1. ✌ ✆ Integer can also be written in its equivalent ascii character. To do this we have to just change the integer modifier ‘%d’ by character modifier ‘%c’. ✞ #include <stdio.h> 2 int main (){ 4 int i; for (i = 65; i <= 68; ++i){ 6 printf("Integer %d is equivalent to : %c.", i, i); printf("n"); 8 } } ✌ ✆ Output of above script is
  • 29. 1.2. FORMATTED I/O 29 Symbolic Constant Represents %a Floating-point number, hexadecimal digits and p- notation. %A Floating-point number, hexadecimal digits and P- notation. %c Single character. %d Signed decimal integer. %e Floating-point number in e-notation form. %E Floating-point number in e-notation form. %f Floating-point number in decimal notation form. %g If the exponent is less than 4 or greater than or equal to the precision %e used otherwise %f is used. %G If the exponent is less than 4 or greater than or equal to the precision %E used otherwise %F is used. %i Signed decimal integer. %o Unsigned octal integer. %p A pointer. %s Character string. %u Unsigned decimal integer. %x Unsigned hexadecimal integer using hex digits 0f. %X Unsigned hexadecimal integer using hex digits 0F. %% Prints a percent sign. Table 1.9: Conversion specifiers.
  • 30. 30 Basic C ✞ Integer 65 is equivalent to : A. Integer 66 is equivalent to : B. Integer 67 is equivalent to : C. ✌ ✆ In C, modifiers are used to print formatted outputs. A modifier ‘%s’ simply puts the string by creating space equal to the length of string. If this modifier is redefined like ‘%20s’ (a positive integer between % and ‘s’ symbols), then space for 20 characters is created. If string length is less than 20 characters then ‘ ’ (space) is prefixed to the string to increase its length to 20. If number in modifier is less than the length of string then nothing is done. ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { 5 printf(""%s" secured numbers "%d"n", "Arun Kumar", 100); printf(""%20s" secured numbers "%5 d"n", "Arun Kumar", 100) ; 7 return 0; } ✌ ✆ ✞ "Arun Kumar" secured numbers "100" " Arun Kumar" secured numbers " 100" ✌ ✆ In case of string modifier, prefixed spaces can not be filled by any other character. In case of numeric modifier, if a ‘.’ (ie full stop) is placed just after the ‘%’ symbol then prefixed space is filled by ‘zero’ as shown in example below. ✞ #include <stdio.h> 2 #include <string.h> 4 int main () { printf(""%5 s" secured numbers "%5 d"n", "Arun Kumar", 100) ; 6 printf(""%.20s" secured numbers "%.5d"n", "Arun Kumar", 100) ; return 0; 8 } ✌ ✆ ✞ "Arun Kumar" secured numbers " 100" "Arun Kumar" secured numbers "00100" ✌ ✆ The same output is found when space specifier is prefixed by zero. For example, ✞ #include <stdio.h> 2 int main (void ) { 4 printf("%05dt %0.5 dn", 100, 200) ; return 0; 6 } ✌ ✆
  • 31. 1.2. FORMATTED I/O 31 ✞ 00100 00200 ✌ ✆ For numeric modifiers, total spaces and filled space can also be used simultaneously if modifier is modified like ‘%10.6d’. Here number ‘10’ will create 10 spaces (field of length 10) for placing a number and if digits in number is less than ‘6’ then ‘0’ will be prefixed with the number. ✞ 1 #include <stdio.h> #include <string.h> 3 int main () { int i; 5 printf("%5s%10s%10sn", "Num", " Square", "Cubic"); for (i = 90; i < 92; i++) { 7 printf("%5.3 d%10.6d%10.6dn", i, i*i, i * i * i); } 9 return 0; } ✌ ✆ ✞ Num Square Cubic 090 008100 729000 091 008281 753571 ✌ ✆ ✞ 1 #include <stdio.h> #include <limits.h> // integer limits 3 #include <float.h> // floating -point limits 5 int main (void ) { printf("Biggest int: %dn", INT_MAX ); 7 return 0; } ✌ ✆ ✞ Biggest int: 2147483647 ✌ ✆ There are several methods of modifier conversions. Modifiers accept bits equivalent to their size. Other bits during the modifier conversion is truncated. ✞ 1 #include <stdio.h> #define NUM 61000 3 int main (void ) { 5 printf("Num as int , short int and char : %d, %hd , %cn", NUM , NUM , NUM); 7 return 0; } ✌ ✆ ✞ Num as int , short int and char : 61000 , -4536, H ✌ ✆
  • 32. 32 Basic C ‘+’ in placeholders prints a plus sign if the value is positive. ‘-’ causes left justify to the result. Single Quotes (’) Separate the digits into groups as specified by the locale specified. ‘O’ pads the field with zeros instead of spaces. ✞ 1 #include <stdio.h> 3 int main (void ) { printf("|%-10d|%10 d|%-5d|n", 500000 , -1000, 200) ; 5 printf("|%+10d|%-10d|%05 d|n", 500000 , -1000, 200) ; printf("|%’10d|%10 d|%-5d|n", 500000 , -1000, 200) ; 7 return 0; } ✌ ✆ ✞ |500000 | -1000|200 | | +500000| -1000 |00200| | 500000| -1000|200 | ✌ ✆ There is a common error that arises from the format mismatch. for example, when we try to print an integer as float without casting, compiler shows warning of mismatch format and it gives strange output. See the example below: ✞ 1 #include <stdio.h> 3 int main (void ) { int a=10,b; 5 b=a/7; printf("%f",b); 7 return 0; } ✌ ✆ ✞ 0.00000 ✌ ✆ This is why, to prevent the format mismatch error, we should either cast the variable or should use proper variable declarations. 1.2.3 Escape Characters Escape characters are used to perform action even if they are used as string. For example ✞ 1 #include <stdio.h> int main (void ) { 3 printf("Hello , world!n"); return 0; 5 } ✌ ✆ n at the end of printf function would add a new line after “Hello world!”. The output of the program is ✞ Hello , world! ✌ ✆
  • 33. 1.2. FORMATTED I/O 33 Other escape characters are Escape Character Hex Value Meaning a 07 Add CPU alert b 08 Backspace t 09 Adding a tab n 0A Start a new line v 0B Vertical tab f 0C Form feed r 0D Carriage return " 22 Double quote (”) ’ 27 Single quote (’) ? 3F Question mark (?) 5C Backslash () 1.2.4 Quotes Character inside single quote (’) represents its character code in the machine. For example ‘A’ is equivalent to ‘65’ of the machine code. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { printf("%d", ’A’); 6 return EXIT_SUCCESS ; } ✌ ✆ ✞ 65 ✌ ✆ A multi-character string constants can be used inside the single quotes (‘ ’) while assigning the value to an integer variable. First, all characters are converted into their equivalent machine codes, then they are put in memory space one by one in their binary equivalent form. While copying, characters are taken from the right to left direction and put in four bytes memory space from right to left respectively (this method of computation is machine dependent). After that, corresponding 4 bytes long binary sequence pointed by the declared variable is converted into equivalent number and assigned to the declared integer variable. See the example below: ✞ 1 #include <stdio.h> 3 int main (void ) {
  • 34. 34 Basic C /* Declare i as integer */ 5 int i = ’aa’; printf("Value of i is : %d n", i); 7 return 0; } ✌ ✆ The value ‘aa’ is stored in memory as shown below: 01100001 ‘a’ 01100001 ‘a’ i The decimal equivalent of binary sequence 01100001 01100001 is 24929. The output of above program is ✞ Value of i is : 24929 ✌ ✆ The effective length of single quotes string is the size of data type of the declared variable. For integer, it is four bytes. So only first four bytes of string are assigned to variable i in the following example, rest of values are not accepted. ✞ 1 #include <stdio.h> 3 int main (void ) { /* Declare i as integer */ 5 int i = ’aabb ’; printf("Value of i is : %d n", i); 7 return 0; } ✌ ✆ Single quoted string, ‘aabb’, is stored in memory as shown below: 01100001 ‘a’ 01100001 ‘a’ 01100010 ‘b’ 01100010 ‘b’ i The output of above program after computing the four bytes long binary sequence is ✞ Value of i is : 1633772130 ✌ ✆ ✞ 1 #include <stdio.h> 3 int main (void ) { /* Declare i as integer */ 5 int i = ’aabbcc’; printf("Value of i is : %d n", i); 7 return 0; } ✌ ✆
  • 35. 1.2. FORMATTED I/O 35 Single quoted string, ‘aabbcc’, is stored in memory as shown below: 01100001 ‘a’ 01100001 ‘a’ 01100010 ‘b’ 01100010 ‘b’ 01100011 ‘c’ 01100011 ‘c’ i The output of above program after computing the four bytes long binary sequence is ✞ Value of i is : 1650615139 ✌ ✆ Notice that, here as shown in above figure, in character to integer computation takes only those four bytes which are started from the pointer of ‘i’. Rest are neglected. Char- acter inside double quote (”) represents to a array of character i.e. a string. 1.2.5 Comments Commenting is most useful feature of the C programming. It is used to write comments before or after a function or variable. Stuff within the commenting delimiters is ignored during compilation of the program. There are two type of commenting delimiters. First, single line commenting delimiter and second, multi-line commenting delimiter. For single line commenting ‘//’ is used and for multi-line commenting ‘/* ... */’ is used. ✞ 1 #include <stdio.h> int main (void ) { 3 /* Here printf prints string multiple times.* *Loop is used for multiple output lines. */ 5 for(ix =1; ix <=2; ix ++){ printf("%d - Hello , world!",ix); 7 } return 0; 9 } ✌ ✆ The output of above program is ✞ 1 - Hello , world! 2 - Hello , world! ✌ ✆ 1.2.6 Range Operator C language supports declaration of range by using ‘...’ operator. For example, range from 1 to 10 is declared as “1 ... 10”. The range operator may be used either with case statement or in definition of the function arguments. See the example below: ✞ #include <stdio.h> 2 int main () { 4 int i = 5; switch (i) { 6 case 1 ... 10:
  • 36. 36 Basic C printf("Within range from 1 to 10. n"); 8 break; default : 10 printf("Not supposed .n"); break; 12 } } ✌ ✆ ✞ Within range from 1 to 10. ✌ ✆ 1.3 Variables Variables are multicharacter names used to refer to some locations in memory that holds a value to which we are working. Variables are multicharacter names used to refer to some locations in memory that holds a value to which we are working. A data type is type of data that can be assigned to a variable. We know that data is stored in memory in groups, commonly known as bytes. When a small number like, 20 or 30 is stored, it consumes hardly one byte as they are binary equivalent to 10100 or 11110 respectively. So, data can be easily read or write in the data memory byte. 0×20 0×21 0×22 0×23 0×24 00010100 00011110 i = 20 i = 30 If number is large, say 1024, then it needs two bytes memory space as it is binary equivalent to 10000000000, which is spread between two bytes. 0×20 0×21 0×22 0×23 0×24 00000100 00000000 i = 1024 In C, to deal with this data span, grouping of memory bytes is allowed. This grouping is called data type. For example, single memory byte is said as character data type. Group of two bytes is called short data type, group of four bytes is called integer data type etc. Grouping of bytes is fixed to maintain system independent uniformity and as the number of bytes in a group increases, group able to store larger binary data. Note that, data in each type of group is read and write at once. For example, binary data 101100010111010001010 spread in three bytes. 0×20 0×21 0×22 0×23 0×24 00110110 00101110 10001010 i = 9842186
  • 37. 1.3. VARIABLES 37 If this is integer type data then each time all these bits are read at once and will be converted into decimal number which is 9842186. Any data type does not allow partial read or write of data. The datatypes in C are char-one byte long, int-four bytes long, float-four bytes long and double-eight bytes long. long data type is used to change the byte length of float and double. The derived datatypes are arrays, structure, pointer, function etc. The short, long, signed and unsigned are used as type modifier. Variables are not values by itself but points to values. A variable is equivalent to its assigned value. A variable may be alphanumeric name with underscore character. First numeric character of a variable name is not acceptable. Spaces and special characters which are reserved for internal operations of C are illegal. Similarly, use of comma, dot, symbol of question mark, symbols reserved for relation operations, symbols reserved for bitwise operations, colon and line terminating symbol are also considered as illegal if used in variable names. Key words specially reserved for internal programming of C, can not be used like variable name. A list of reserved keyword is given in section 4.2. ✞ 1 int A1; // Legal and acceptable . int 1A; // Illegal , first character is numeric 3 int A_1;// Legal , _ is acceptable int A$1;// Legal , $ is not reserved character 5 int A#1;// Illegal , # reserved for header inclusion int A 1;// Illegal , space is not acceptable 7 int for;// Illegal , for is reserved keyword ✌ ✆ A variable declared once can not be re-declared again within the same scope. Scope of a variable is segment of a code, from where variable is accessible. By default, a local variables get garbage value and global variables get a value 0 by default on declaration. Sometime, words, “argument” and “parameter” are used in the C programming. The word “argument” denotes the value that is passed to a function whereas word “parameter” denotes the name by which the value is referred to in the body of the function. 1.3.1 Address A most commonly used word in C programming is ‘address’. By definition, “address” is the location of memory where either data is stored or from where data is retrieved. An address is a multibytes value that refers to a certain memory location rather than the value stored at that location. Take a memory map of matrix 10 × 8 size as shown below: 11 12 13 14 15 16 17 18 21 22 23 24 25 26 27 28 31 32 33 34 35 36 37 38 41 42 43 44 45 46 47 48 51 52 53 54 55 56 57 58 61 62 63 64 65 66 67 68 0×00 0×01 0×02 0×03 0×04 0×05 0×06 0×07 Low bytes 0×00 0×01 0×02 0×03 0×04 0×05 High bytes Here, memory addressed are two bytes long and it depends on system to system. The
  • 38. 38 Basic C first byte represents to high byte (i.e. rows in above matrix) and second byte represents to low byte (i.e. column in the above matrix). For example an address 0×0304 represents to the memory cell at 4th row and 5th column. This value indicates to location of memory not to value at that location. From the above matrix, at 4th row and 5th column cell, value stored is 45 not 0×0304 (address). In C we do not deals directly with addresses but a variable name is assigned to the address. For example, if a variable ✞ 1 int i = 45; ✌ ✆ is declared and assigned a value equal to encircled value in above memory matrix. For this value, address of variable ‘i’ shall be 0×0304. Address assigned to variable is always hidden and can be retrieved by using addressof (‘&’) symbol. ✞ 1 #include <stdio.h> 3 int main () { unsigned int i=45; 5 printf("%x", &i); return 0; 7 } ✌ ✆ ✞ 0304 ✌ ✆ Here address variable is of 2 bytes long. Note that address of operator can not be used with constants and variable that is declared using register storage class. A question rises here that why address is assigned to a variable not the value itself. Its answer is, value assigned to variable is of any size and for long values, it is impossible to assign directly to the variable. This is why, pointers or variables are let to point the address the first byte of the memory location where data is stored. 0×00 0×01 0×02 0×03 0×04 0×05 0×06 0×07 0×08 0×09 Low bytes 0×00 0×01 0×02 0×03 0×04 0×05 High bytes T w o P e n s 0 Str Assume a variable ‘Str’ which is assigned a string “Two Pens”. This is eight bytes long data. So a variable can not store this data directly. Therefore, the string is stored in the temporary memory as shown in above figure. The variable ‘Str’ points to first byte of the string, i.e. to ‘T’. The scope of ‘Str’ variable ended at the next null char ‘0’. The memory address of ‘T’ is 0×0201. Hence, variable ‘Str’ points to memory address 0×0201 from where the string started and ‘Str’ does not points to the string itself.
  • 39. 1.3. VARIABLES 39 Character & String Variables char is used to initialize a character or character string. A char data type variable which can be initialized only for one character is declared and initialized as ✞ 1 /* Declaration .*/ char c;/* Char variable one byte long */ 3 /* Declaration & Initialization .*/ char c=’K’;/* Single quote one byte long value.*/ ✌ ✆ Character string can be initialized as an array or pointer. The size of char data type is 1 byte. In following figure, the memory byte B[3] is reserved for character variable c (value stored at this memory byte is K) and memory byte B[4] is reserved for character variable s (value stored at this memory byte is L). B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11] K L c s In case of character string, as shown in the syntax given below, ✞ char *s="abcd "; ✌ ✆ variable s is a pointer and points to the address of first element, i.e. ‘a’ of the string “abcd”. B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11] a b c d s The memory location used to store this string is from B[5] to B[8]. B[5] stores to first character, ‘a’ of the string, B[6] stores to second character, ‘b’ of the string, B[7] stores to third character, ‘c’ of the string and B[8] stores to fourth character, ‘d’ of the string. By default, a char is signed unless unsigned keyword is not used. ✞ 1 /* Group of characters in double quotes , i.e. string */ char *<var name >="This is string."; 3 char <var name >[ ]="This is string."; ✌ ✆ ✞ 1 #include <stdio.h> 3 int main () { /* Single quote to single char .*/ 5 char c = ’a’; /* Double quote to single char .*/ 7 char ch [2] = "b";/* String size is 2. One byte for b* *and one byte for null terminator */ 9 char *s = "This is my string.";/* Pointer to string.*/
  • 40. 40 Basic C printf("c is %cn", c); /* Print char */ 11 printf("ch is %sn", ch);/* Print string*/ printf("s is %sn", s); /* Print string.*/ 13 return 0; } ✌ ✆ ✞ c is a ch is b s is This is my string. ✌ ✆ A single character when it is in single quote is consider as a character while the same character when is in double quote, it is considered as a string. A group of characters has string length, equal to one more to the number of character. The last byte of string is for string terminator ‘0’. A char variable without initialization stores null character. ✞ 1 #include <stdio.h> 3 int main () { /* Declare char variable . Not initialized .*/ 5 char *ch; printf("Value of ch : %sn", ch); 7 return 0; } ✌ ✆ ✞ Value of ch : (null ) ✌ ✆ The null terminator terminates a string. Value to a character data type may be assigned by two ways. One, by using bymbol and other by using equivalent character code. See the example below: ✞ 1 #include <stdio.h> 3 int main () { char c[5], s[5]; 5 c[0]=0; /* Assign null character by* * using char code value. */ 7 printf("%s",c); s[0]= ’0’; /* Assign null character by * 9 * using single quoted symbol.*/ printf("%s",s); 11 return 0; } ✌ ✆ Output of above program is null or empty string. See another example, in which character array is initialized with empty string (NOT NULL). Remember that ‘0’ and “0” are both same as single backslash is used to represent escape characters. To print the backslash symbol at output stream, it is used in double, i.e. “”. ✞ #include <stdio.h>
  • 41. 1.3. VARIABLES 41 2 int main () { 4 char c[5], s[5], s2 [5]; c[0]=0; // Assign null char by using char code value. 6 printf("%s",c); s[0]= ’0’; // Assign null char by using single quoted symbol. 8 printf("%s",s); s2 [0]= "0";/* Assign null character by using double * 10 *quoted backslash and 0 (escape character ).*/ printf("%s",s2); 12 return 0; } ✌ ✆ NULL or empty string is also represented by “” (nothing within double quote symbols). ✞ 1 #include <stdio.h> 3 int main () { /* Variable initialized with EMPTY value.*/ 5 char *ch = ""; /* Prints empty character .*/ 7 printf("ch as character : %sn", ch); 9 /* Prints integer value. Here empty character has * *charcode 0. It is not ZERO char of charcode 48.*/ 11 printf("ch as integer : %dn", *ch); return 0; 13 } ✌ ✆ ✞ ch as character : ch as integer : 0 ✌ ✆ Though the compiler assigned dynamically available memory address to the pointer type variable declaration, yet we can assign designated address to the variable as shown below: ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main () { char value = *( char *)0xA0008; 6 printf("%c", value); return 0; 8 } ✌ ✆ The output of this program may or may not correct and depends on platform and mostly, it returns “Segmentation Fault (SIGSEGV)” error. To read data from allowed memory address and desired result, see the following example. ✞ #include <stdio.h> 2 #include <stdlib.h>
  • 42. 42 Basic C 4 int main (int argc , char ** argv ) { char x[20] = "This is my string"; 6 printf("Char at address of x is :%cn", *x); printf("Char at address of (x + 1) is :%cn", *(x + 1)); 8 printf("Char at address of (x + 2) is :%cn", *(x + 2)); printf("Address of x is :%xn", x); 10 /*In my machine , address of x is 0x22cd40 */ printf("Char at address of (0 x22cd40 +0x1) is :%cn", 12 *( char *) (0 x22cd40 + 0x1)); return (EXIT_SUCCESS ); 14 } ✌ ✆ ✞ Char at address of x is :T Char at address of (x + 1) is :h Char at address of (x + 2) is :i Address of x is :22 ccb0 Char at address of (0x22 cd 40+0 x1) is :h ✌ ✆ NULL (0), a Magic Symbol Let we have a special file which contains our secret passphrase, keywords including secret passwords. When this file is deleted, only name variable, that points to the address of the file data, is removed from the file table. Data stored in permanent memory remains intact. If someone scan the whole memory of the storage device, he may able to retrieve your secret passphrase or passwords. Then, how do we make a safe removal of the data file? We can do it my flushing file data with 0 (NULL character) by mapping whole file (using mmap function) in the memory before its removal. Now, if anyone scan the storage memory, he will get only garbage data. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 #include <sys/mman .h> #include <fcntl.h> 5 int main (int argc , char *argv []) { 7 int fd , i; char *data ; 9 if ((fd = open ("a.txt", O_RDWR)) == -1) { printf("Unable to open file .n"); 11 return 1; } 13 /* Put mmap in loop for large size file mapping */ data = mmap (0, 1024, PROT_READ |PROT_WRITE , MAP_SHARED , fd , 0); 15 if (* data == -1) { printf("Unable to map file .n"); 17 return 1; } 19 for(i=0; i < 1024; i++) data [i]=’0’; // replace data with garbage 21 return 0; }
  • 43. 1.3. VARIABLES 43 ✌ ✆ Now open and see the experimental file. Integers A 4 bytes long numerical value can be declared and initialized by using int data type. In following figure, bytes B[3] to B[6] are reserved for storing integer value assigned to the integer variable i and B[7] to B[10] are reserved for storing integer value assigned to the integer variable j. B[2] B[3] B[4] B[5] B[6] B[7] B[8] B[9] B[10] B[11] xxxx xxxx xxxx xxxx yyyy yyyy yyyy yyyy i j When a real number is initialized to a integer variable, then its fraction part is trun- cated. A valid integer type is either a whole number of a whole number with suffix ‘L’. An integer variable is declared and initialized as shown below: ✞ int <var name >; /* Declared .*/ 2 int <var name >=<value >; /* Initialized .*/ ✌ ✆ An example is given below: ✞ #include <stdio.h> 2 int main () { 4 int i = 10; int iL = 11L; 6 int j = 12.5; /* Print whole integer i.*/ 8 printf("i : %dn", i); /* Print whole integer iL.*/ 10 printf("iL : %dn", iL); /* Truncated to decimal part of j.*/ 12 printf("j : %dn", j); return 0; 14 } ✌ ✆ ✞ i : 10 iL : 11 j : 12 ✌ ✆ Similarly, if a double or float number is casted as integer then again its decimal part is truncated. Remember float number larger than that of size of integer cause overflow. ✞ 1 #include <stdio.h> 3 int main () {
  • 44. 44 Basic C double i = 10.25; 5 float j = 12.75; printf("i : %dn", (int) i); 7 printf("j : %dn", (int) j); printf("j as float : %fn", (int) j); 9 return 0; } ✌ ✆ ✞ i : 10 j : 12 j as float : -0.000000 ✌ ✆ Note that, prepend zeros in the values of integer type variables, cast the values into octal number form. In C, prepend zeroes has significant meaning here. ✞ 1 #include <stdio.h> 3 int main () { int a = 010; // Declare & assign octal 010 to variable a 5 a = a + 10; // Ouput is a = 10 + 8 = 18 in decimal . printf("%d", a); 7 return 0; } ✌ ✆ ✞ 18 ✌ ✆ Here, output is decimal 18 and octal 010 is equivalent to decimal 8. Therefore, be cautious while using prepend zeros in the numeric values. Integer Casting into Char Here is a question that how a numerical value is stored as integer and as string and what is different in these two storing modes. For example, assume a numeric value 62, which is to be stored as integer and as string. The numeric value 62, as integer, it is equal to binary value ‘00111110’ and it is stored in the first byte of four byte long storage memory allocated for integer variable. ✞ 1 #include <stdio.h> 3 int main () { int i = 62; /* Four byte long data type */ 5 /*x Point to first byte of address of i*/ char *x = (char *) &i; 7 printf("First byte %dn", x[0]) ; printf("Second byte %dn", x[1]) ; 9 printf("Third byte %dn", x[2]) ; printf("Fourth byte %dn", x[3]) ; 11 return 0; } ✌ ✆
  • 45. 1.3. VARIABLES 45 ✞ First byte 62 Second byte 0 Third byte 0 Fourth byte 0 ✌ ✆ In this case, numeric value is stored as integer needs only one byte (as numeric value is small) of four bytes allocated memory for integer variable. Remember that, an integer is four bytes long data. x[3] x[2] x[1] x[0] i : Value at byte : Pointer x : 00000000 00000000 00000000 00111110 0 0 0 62 62 is small number hence it is accommodated in one byte. If this value is larger then it need two or more bytes to store it. Assume a number 12345. In binary form, it is “110000 00111001” and accommodated in 4 bytes long memory as shown below: x[3] x[2] x[1] x[0] i : Value at byte : Pointer x : 00000000 00000000 00110000 00111001 0 0 48 57 ✞ #include <stdio.h> 2 int main () { 4 int i = 12345; /* Four bytes long */ /*x Point to first byte of address of i*/ 6 char *x = (char *) &i; printf("First byte %dn", x[0]) ; 8 printf("Second byte %dn", x[1]) ; printf("Third byte %dn", x[2]) ; 10 printf("Fourth byte %dn", x[3]) ; return 0; 12 } ✌ ✆ ✞ First byte 57 Second byte 48 Third byte 0 Fourth byte 0 ✌ ✆ In image processing, the image data is written byte by byte as group of two, three, four or more bytes. Four bytes long integers are also written as byte by byte while they are read as four byte long data. Therefore, pointing to an integer as character by character has great significance in image processing. Now, in the case, when 62 is stored as a group of characters, i.e. in form of string, it becomes “62” (a group of character “6” and character “2”).
  • 46. 46 Basic C ✞ #include <stdio.h> 2 int main () { 4 char *s = "62"; /* Two bytes long */ char *x = s; /* Points to first byte .*/ 6 printf("First byte : %d=’%c ’n", x[0], x[0]) ; /* Char code of 6*/ printf("Second byte : %d=’%c ’n", x[1], x[1]) ; /* Char code of 2*/ 8 return 0; } ✌ ✆ ✞ First byte : 54=’6’ Second byte : 50=’2’ ✌ ✆ Here, the numeric value 62, is stored as string “62”, it needs two bytes long memory. One byte for character ‘6’ (char code 54, binary equivalent to 00110110) and one byte for character ‘2’ (char code 50, binary equivalent to 00110010). x[0] x[1] s : Value at byte : Pointer x : 00110110 00110010 6 2 This is the main difference in storage of integers and strings in computer memory. Note that the same binary data in a memory byte has different meaning for different data type. For example, binary value 00110010 is equal to symbol ‘2’ (numeric digit two) for character data type. The same binary value is equal to number ‘50’ (equal to char code) for integer data type. Thus each data type has different way of reading and interpreting binary data. Little Endian & Big Endian Little and big endian are two ways of storing multibyte data, i.e. int, float, etc. In little endian machines, least significant byte of binary rep- resentation of the multibyte data is stored first, i.e. at lowest address of the memory. In big endian machines, most significant byte of binary representation of the multibyte data is stored first, i.e. at lowest address of the memory. For example, a multi byte data 12D589A116 is written in the machine as big endian as shown in the following table Address Value 1000 12 1001 D5 1002 89 1003 A1 The same multibyte data is written in the machine as little endian as shown in the following table
  • 47. 1.3. VARIABLES 47 Address Value 1000 A1 1001 89 1002 D5 1003 12 The program that can check the machine as little endian or big endian is given below: ✞ #include <stdio.h> 2 int main (void ) { 4 int *T; 6 T = (int *) " 01000000000000000"; if (*T == 1) 8 printf("Machine is High -Endian .n"); else 10 printf("Machine is Low -Endian .n"); return 0; 12 } ✌ ✆ According to this program, my machine is ✞ Machine is High -Endian. ✌ ✆ Real Numbers A real number has decimal point. Thus 12.0 and 12 are not equal characteristically but they are equal numerically. In C, some operators like modulo, left and right shift, etc do not work with real numbers. In the following example, modulo of 12 by 5 is 2. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 printf("12 %% 5 = %d n", 12 % 5); return (EXIT_SUCCESS ); 7 } ✌ ✆ ✞ 2 ✌ ✆ But in the following example, there is error. ✞ 1 #include <stdio.h> #include <stdlib.h> 3
  • 48. 48 Basic C int main (int argc , char ** argv ) { 5 printf("12.0 %% 5 = %d n", 12.0 % 5); return (EXIT_SUCCESS ); 7 } ✌ ✆ The reason behind these difference is treatment of value 12, i.e. how the bits of memory bytes stored 12 or 12.0 are grouped, interpreted and converted into numbers. In first case, it was an integer and all bits in four bytes of integer data type were part of the integer value. But in above code, 12.0 is a float type values. The bits in four bytes float data type are treated differently. Few bits are used as mantissa and rest are used for characteristics. Similarly, left or right bit shift operator do. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (int argc , char ** argv ) { 5 printf("12.0 << 5 = %d n", 12.0 << 5); return (EXIT_SUCCESS ); 7 } ✌ ✆ Above code shows error. In left bit shift or right bit shift of real numbers, mentisaa and characteristics bits trespass each others places. This is why, some operators are illegal with real numbers. Float Decimals This data type is floating-point type. It usually referred to as a single-precision floating- point. Float-to-integer or integer-to-float type conversion of numbers take place by casting the number. It is 4 byte long. Its range varies from 1.2×10−38 to 1.2×1038 . The precision of the float data type is upto 6 decimal places. Syntax for the float data type is ✞ 1 float <var name >; float <var name >=< decimal value >; ✌ ✆ See the example below. ✞ #include <stdio.h> 2 int main () { 4 float i = 10.25; int j = 15; 6 printf("i as float : %fn", i); printf("i as integer : %dn", (int) i); 8 printf("Int j as float : %fn", ( float) j); return 0; 10 } ✌ ✆ ✞ i as float : 10.250000 i as integer : 10 Int j as float : 15.000000 ✌ ✆
  • 49. 1.3. VARIABLES 49 A floating point is represented in scientific notation form by using ‘e’ (here ‘e’ is exponent and is equivalent to ‘10’) as ✞ 1 float 125e-n float 125e+n ✌ ✆ A positive power ‘+n’ shifts the decimal point from left to right and negative power ‘– n’ shifts the decimal point from right to left. For example, −12345e + 5 in C notation is equivalent to −12345 × 10+5 in mathematics. Similarly, 12345e − 5 in C notation is equivalent to 12345 × 10−5 in mathematics. See the example given below: ✞ #include <stdio.h> 2 int main () { 4 float i = -12345e+5; float j = 12345e-5; 6 printf("i is %f n", i); printf("j is %f n", j); 8 return 0; } ✌ ✆ ✞ i is -1234499968.000000 j is 0.123450 ✌ ✆ A float is 32 bits long and has three components, (i) a sign bit (first bit from left side), (ii) exponent (next 8 bits from left side) and (iii) mantissa (rest of 23 bits). A floating point number is written as f = ±m × b±e Here, m is mantissa of the number, b is base either ‘10’ or ‘e’ or ‘2’ and n is exponent of the floating type number. In computers, the base is ‘2’. Double Decimals This data type is floating-point type. It usually referred to as a double-precision floating- point. Double-to-integer or integer-to-double type conversion of numbers take place by casting of the number. It is 8 bytes long. Its range is from 2.3 × 10−308 to 2.3 × 10308 . The precision of the double data type is upto 15 decimal places. Syntax for the double data type is ✞ double <var name >; 2 double <var name >=< decimal value >; ✌ ✆ See the example below. ✞ #include <stdio.h> 2 int main () { 4 double i = 10.25; printf("i as double : %fn", i);
  • 50. 50 Basic C 6 printf("i as integer : %dn", (int) i); return 0; 8 } ✌ ✆ ✞ i as double : 10.250000 i as integer : 10 ✌ ✆ A double is 64 bits long and has three components, (i) a sign bit (first bit from left side), (ii) exponent (next 11 bits from left side) and (iii) mantissa (rest of 52 bits). A double point floating point number is written as f = ±m × b±e Here, m is mantissa of the number, b is base either ‘10’ or ‘e’ or ‘2’ and n is exponent of the floating type number. In computers, the base is ‘2’. double data type is preferred over float in numerical programming to avoid variance and kept precision in results. ✞ #include <stdio.h> 2 int main () { 4 printf("%fn", (float) 343434333.98) ; printf("%fn", (float) 545454323.31) ; 6 printf("%fn", (double) 343434333.98) ; printf("%fn", (double) 545454323.31) ; 8 return 0; } ✌ ✆ ✞ 343434336.000000 545454336.000000 343434333.980000 545454323.310000 ✌ ✆ Long Decimals long is long integer type. It is capable of containing any integer value within the range from 2147483647 to +2147483647. It is a 32 bits or 4 bytes long in size. Long-to-integer or integer-to-long type conversion of numbers is done by casting. ✞ long <var name >; 2 long <var name >=< decimal value >; ✌ ✆ See the example below. ✞ #include <stdio.h> 2 int main () { 4 long i = 10.25; int j = 15;
  • 51. 1.3. VARIABLES 51 6 printf("i as long : %ldn", i); printf("i as integer : %dn", (int) i); 8 printf("Int j as long : %ldn", (long ) j); return 0; 10 } ✌ ✆ ✞ i as long : 10 i as integer : 10 Int j as long : 15 ✌ ✆ Long Double It is 10 bytes long data type. Its range is from 3.4×10−4932 to 3.4×104932 . The precision of the long double data type is upto 19 decimal places. Syntax for the long double data type is ✞ 1 long double <var name >; long double <var name >=< decimal value >; ✌ ✆ The example is ✞ #include <stdio.h> 2 int main (void ) { 4 long double x = -5.32e-5; printf("x = %LEn", x); 6 return 0; } ✌ ✆ ✞ x = -5.320000 E-05 ✌ ✆ Alias Data type typedef is used to create an alias name for any other data type. As such, it is often used to simplify the syntax of declaring complex data structures consisting of struct and union types, but is just as common in providing specific descriptive type names for integer datatypes of varying lengths. The syntax of typedef is given by ✞ 1 typedef <old type name > <new alias >; ✌ ✆ Redefining the long long data type with new variable as given below. ✞ 1 typedef long long <major unit >; typedef int <minor unit >; ✌ ✆ An example is given below.
  • 52. 52 Basic C ✞ #include <stdio.h> 2 typedef long long km; 4 typedef int mm; 6 int main (void ) { km dis = 10; 8 printf("Distance is %d km.n", dis); return 0; 10 } ✌ ✆ ✞ Distance is 10 km. ✌ ✆ typedef can also be used to define alias names to a structure. See the example given below: ✞ 1 #include <stdio.h> 3 typedef struct Coord { int x; 5 int y; } c; 7 int main () { 9 c coord1 = {2, -5}; // Assign default values c coord2 = coord1; // Copy coord1 into coord2 11 printf("%d", coord2.y); // get value return 0; 13 } ✌ ✆ ✞ -5 ✌ ✆ Always remember that, alias names created by using typedef keyword, are used to create new instances of structure. They do not act as instances themselves. So, accessing the elements of a structure, as given in above example, like ✞ 1 c.x; c.y; ✌ ✆ are invalids and give compile time error. Boolean C has no dedicated boolean variable. Hence a comparison between variable and return value can not be performed. In C, the true and false numeric values are depend on the implementation concepts by the program writer. For example, if two strings are exactly same, then their comparison by strcmp() function is true and it returns ‘0’. It returns any number if two strings are not exactly same, i.e. the false case. Similarly, scanf returns
  • 53. 1.3. VARIABLES 53 1 if it success to scan a value according to modifiers otherwise 0 on failure. So, we can say that boolean returned values are dependent to success or error or failure states or implementation of user’s function. In following example, we check whether there are spaces in a string or not. ✞ #include <stdio.h> 2 /* Space function . */ /* Return 0 if no spaces otherwise > 0.*/ 4 int has_space (char *s) { int num = 0; 6 while (*s++ != ’0’) { if (*s == ’ ’) { 8 num ++; } 10 } return num; 12 } 14 int main (int argc , char ** argv ) { char *s = "This is pen."; 16 printf("Spaces : %dn", has_space (s)); return 0; 18 } ✌ ✆ In concept implementation, function has space() returns the number of space occurring in the string. It means, if return value is ‘0’ then there are no spaces in the string. Other positive integer values tells the number of spaces in the string. It means presence of space, i.e. true state has any positive integer value while false state has ‘0’ value. In following example, a totally different concept implemented for return value for true or false state. ✞ #include <stdio.h> 2 /* Return 0 if only numeric otherwise > 0.*/ int is_only_numeric (char s[ ]) { 4 int num = 0, i = 0; while (s[i] != ’0’) { 6 if (s[i] < 48 || s[i] > 59) { num ++; 8 } i++; 10 } return num; 12 } 14 int main (int argc , char ** argv ) { char *s = "341"; 16 printf("Numeric only : %dn", is_only_numeric (s)); return 0; 18 } ✌ ✆ In above function, return value is zero, if string has only numeric digits ranging from 0 to 9. If there are other characters or symbols, the return value is greater than zero. The
  • 54. 54 Basic C type comparison like ✞ if(has_space (s) == 0) ✌ ✆ shall be true if there are no spaces in string ‘s’. Again, the type comparison like ✞ 1 if(has_space (s) > 0) ✌ ✆ shall be true if there are spaces in string ‘s’. But ✞ 1 if(has_space (s) != 0) ✌ ✆ can’t be implemented. Boolean in C depends on implementation and varies from library to library. In mathematics library, true is any number while false is zero. ✞ 1 #include <stdio.h> 3 int main () { int b = 2, c = 3; 5 printf("%dn", (c > b)); // true case printf("%dn", (c < b)); // false case 7 return 0; } ✌ ✆ ✞ 1 0 ✌ ✆ Declaration, Initialization & Assignment A variable in C can be assigned as integer, if syntax is defined as given below: ✞ int variable_name ; ✌ ✆ It means there is some space declared somewhere to store integer value. Multiple variables can be assigned in single line or successive way like ✞ 1 int variable_a , variable_b , variable_c ; ✌ ✆ A variable in C is said to be initialized if a numeric or an alphabetic value is assigned to it. For example variable a is initialized by ✞ 1 int variable_a = <value >; ✌ ✆ To distinct the words of a variable, underscore symbol (‘ ’) is used. Anytime within a program in which we specify a value explicitly instead of referring to a variable or some other form of data, that value is referred as a literal. Literals can either take a form defined by their type, or one can use hexadecimal (hex) notation to directly insert data into a variable regardless of its type. Hex numbers are always preceded with ‘0×’. There
  • 55. 1.3. VARIABLES 55 are five major datatypes which are given in the following table. C also allow suitable combinations of numeric datatypes for long numerical values. Data type Meaning int Integer char Character long Long integer float Floating data with single digit precision double Floating data with double digit precision The length of data type is measured its byte length. The data type may be signed or unsigned. In signed data type, the MSB is used for sign declaration and rest of the bits are used for data value. In unsigned data type, all the bits are used for data value. The byte length of different data type are given in following table. Type Storage size Format Specifier char 1 byte %c un-signed char 1 byte %c (%hhu for numerical output) signed char 1 byte %c (%hhi for numerical output) int 2 or 4 bytes %i or %d unsigned int 2 or 4 bytes %u unsigned short 2 bytes %hu short 2 bytes %hi long 4 bytes %li unsigned long 4 bytes %lu long long 8 bytes %lli long long int 8 bytes %lli or %Ld unsigned long long 8 bytes %llu double 8 bytes %f long double 10 bytes %Lf Table 1.10: Declaration type and their storage size in byte. Example, that scans a 8 bytes long integer by using ‘%Ld’ format specifier. ✞ 1 #include <stdio.h>
  • 56. 56 Basic C 3 int main (){ long long int a; 5 scanf("%Ld" ,&a); if(a%6==0 || a%6==1 || a%6==3){ 7 printf("YES"); }else { 9 printf("NO"); } 11 return 0; } ✌ ✆ ✞ 2154478958845 YES ✌ ✆ Example for long double data type. ✞ #include <stdio.h> 2 #include <math .h> 4 int main () { long double x; 6 printf("%lfn",pow (2 ,50)); return 0; 8 } ✌ ✆ ✞ 1125899906842624.000000 ✌ ✆ Sometime, variables are declared but not initialized and further used. Integer type data variables if declared as static or global, they store zero by default. ✞ 1 #include <stdio.h> 3 int main () { int i; 5 printf("%dn", i); return 0; 7 } ✌ ✆ ✞ 0 ✌ ✆ Though, the non-initialized integers are zero by default, yet the initialization of integer variables are required. If not initialized, the result is garbage. ✞ 1 #include <stdio.h> 3 int main () { int i; 5 int j; while (i < 5) {
  • 57. 1.3. VARIABLES 57 7 j = i + j; i++; 9 } printf("i:%d, j:%dn", i, j); 11 return 0; } ✌ ✆ ✞ i:5, j: -1081549298 ✌ ✆ The same problem gives desired result if a printf function is placed inside while loop. ✞ 1 #include <stdio.h> 3 int main () { int i; 5 int j; while (i < 5) { 7 j = i + j; printf("i:%d, j:%dn", i, j); 9 i++; } 11 printf("i:%d, j:%dn", i, j); return 0; 13 } ✌ ✆ ✞ %Inner loop printf% i:0, j:0 i:1, j:1 i:2, j:3 i:3, j:6 i:4, j:10 %Outer loop printf% i:5, j:10 ✌ ✆ In the following example, ‘res’ variable is not initialized. Hence the result is not as we required. ✞ #include <stdio.h> 2 int main () { 4 char intg [ ] = "1234233 "; /* res is not initialised and assumed as zero */ 6 int i = 0, res; while (intg [i] != ’0’) { 8 /* Product of res with 10 is null .*/ res = res * 10 + (intg [i] % 48); 10 i++; } 12 printf("%dn", res); return 0;
  • 58. 58 Basic C 14 } ✌ ✆ ✞ -678766791 ✌ ✆ But when res in above example is initialized then answer is that as we required. ✞ 1 #include <stdio.h> 3 int main () { char intg [ ] = "1234233 "; 5 /* Res is not initialised to 0.*/ int i = 0, res =0; 7 while (intg [i] != ’0’) { /* Product of res with 10 is null .*/ 9 res = res * 10 + (intg [i] % 48); i++; 11 } printf("%dn", res); 13 return 0; } ✌ ✆ ✞ 1234233 ✌ ✆ Observing above examples given for un-initialized variables, it is recommended that each variable should be initialized before its use to avoid unpredictable results. See the follow- ing example, in which variable ‘i’ is not initialized inside the XYZ() function. i.e. ✞ 1 int i; ✌ ✆ The while function does not give any output. ✞ 1 #include <stdio.h> 3 int XYZ() { int i; /*i is NOT initialized .*/ 5 int loops = 5; while (i < loops) { 7 /* It shall NOT be printed at output console .*/ printf("i is %dn", i); 9 i++; } 11 return 0; } 13 int main (void ) { 15 /* Call XYZ() function .*/ XYZ(); 17 return 0; } ✌ ✆
  • 59. 1.3. VARIABLES 59 When we initialized the variable ‘i’ inside the XYZ() function as given below. ✞ int i=0; ✌ ✆ The while function gives desired output. ✞ 1 #include <stdio.h> 3 int XYZ() { int i=0; /*i is initialized .*/ 5 int loops = 5; while (i < loops) { 7 /* It shall be printed at output console.*/ printf("i is %dn", i); 9 i++; } 11 return 0; } 13 int main (void ) { 15 /* Call XYZ() function .*/ XYZ(); 17 return 0; } ✌ ✆ ✞ i is 0 i is 1 i is 2 i is 3 i is 4 ✌ ✆ In the C language’s grammar, a scalar initializer may be enclosed in any number of curly brace pairs. ✞ 1 int x = 12; int y = { 23 }; // valid , no warning ✌ ✆ Most compilers issue a warning if there is more than one such pair. ✞ int z = { { 34 } }; // valid , expects a warning ✌ ✆ If there are multiple values being assigned to a variable and are comma separated then assignment of value to the variable is take place in Right-to-Left order. For example ✞ 1 int i=10, 20, 30; // valid ✌ ✆ always assigns value 10 to i. Structures, unions and arrays stores data of variable numbers and size. These can be initialized in their declaration using an initializer list. Without designator, the initialization of a structure, union or array is sequential. To initialize a successive element, the preceding element must be initialized by assigning a value either empty, null or zero. For example, take the structure as
  • 60. 60 Basic C ✞ 1 struct st{ int x; 3 float y; char *z; 5 }; ✌ ✆ To initialize z without designation, initializer list is used like ✞ 1 /* Following type of declaration is invalid* * as its first element must be an integer */ 3 struct st k = {"Konark Temple" }; /* Following declaration is invalid and * 5 * unacceptable . Its first and second * * elements must be an integer or a float*/ 7 struct st k = {4, "Konark Temple" }; /* Following declarations are valid */ 9 struct st k = {3, 4, "Konark Temple" }; struct st k = {0, 0, "Konark Temple" }; ✌ ✆ Here is the complete example in which struct table is initialized with integers and strings. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 struct st { int x; 6 float y; char *z; 8 }; 10 int main (void ) { struct st k = {"Konark Temple"}; /* Illegal assignment */ 12 printf("Temple name is %sn", k.z); return EXIT_SUCCESS ; 14 } ✌ ✆ ✞ Temple name is null ✌ ✆ The above example is modified for different output. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 struct st { 5 int x; float y; 7 char *z; }; 9 int main (void ) {
  • 61. 1.3. VARIABLES 61 11 /* valid assignment */ struct st k = {0, 0, "Konark Temple"}; 13 printf("%dn", k.x); printf("Temple name is %sn", k.z); 15 return EXIT_SUCCESS ; } ✌ ✆ ✞ 0 Temple name is Konark Temple ✌ ✆ To overcome this strict initialization, designated initializers are used like ✞ /* valid and acceptable */ 2 struct st k = {.z="Konark Temple" }; ✌ ✆ ✞ #include <stdio.h> 2 #include <stdlib.h> 4 struct st { int x; 6 float y; char *z; 8 }; 10 int main (void ) { // valid designator initializer 12 struct st k = {.z=" Konark Temple" }; printf("Temple name is %sn", k.z); 14 return EXIT_SUCCESS ; } ✌ ✆ ✞ Temple name is Konark Temple ✌ ✆ Designated initializers allow its members to be initialized by name, in any order, and without explicitly providing the preceding values. Compound designators can be used to provide explicit initialization. ✞ 1 struct { int a[3], b; } w[ ] = { 3 { { 1, 0, 0 }, 0 }, { { 2, 0, 0 }, 0 } 5 }; ✌ ✆ Compound literals are often combined with designated initializers to make the declaration more readable: ✞ 1 pi = (struct s){ .z = "Pi", .x = 3, .y = 3.1415 }; ✌ ✆
  • 62. 62 Basic C ✞ 1 #include <stdio.h> #include <stdlib.h> 3 struct st { 5 int x; float y; 7 char *z; }; 9 int main (void ) { 11 struct st k; k = ( struct st){ .z = "Konark Temple", .x = 1, .y = 1.51 }; 13 printf("Temple name is %sn", k.z); return EXIT_SUCCESS ; 15 } ✌ ✆ ✞ Temple name is Konark Temple ✌ ✆ By default, strings are addresses of memory where strings are stored. Integer variables are not so. This is why to get the address of integer value, integer variables are prefixed with ‘&’ symbol. ✞ 1 int i=10; 3 /*It is address of integer i* *where value 10 is stored. */ 5 int *j=&i; 7 char j[10]="Harappa";/*j is address itself.*/ ✌ ✆ See the following example, which is complete code of the above code snippet. ✞ 1 #include <stdio.h> 3 int print(int *i) { printf("%d", *i); 5 return 0; } 7 int main () { 9 int i = 10; int *j = &i; 11 print(j); return 0; 13 } ✌ ✆ ✞ 10 ✌ ✆
  • 63. 1.3. VARIABLES 63 Float To Integer Variable type ‘int’ stores data with zero digit precision while ‘float’ stores data with single digit precision. When a floating point number is assigned to an integer type variable then only whole part of the floating point number is assigned to the integer variable, and its fraction part is truncated. See the example below. ✞ 1 #include <stdio.h> 3 int main () { float x; 5 printf("Enter a number : "); scanf("%f", &x); 7 int y = x; float z = (x - y); 9 printf("Whole part is %dn", y); printf("Fraction part is %fn", z); 11 return 0; } ✌ ✆ The output of this program is ✞ Enter a number : 2.5 Whole part is 2 Fraction part is 0.500000 ✌ ✆ Signed & Unsigned Integer A byte is 8 bits long memory space. The size of int is 4 byte, i.e. 32 bits. In a signed integer, first bit, from MSB side is considered as sign bit and remaining 31 bits are used for storing of an integer value. If integer is defined as unsigned then all 32 bits are used for storing of an integer value. For convenience of understanding, assume that we are storing small integer type value, and it is one byte long as shown below: 1 1 1 1 1 1 1 1 Sign bit 1 Byte As the above byte is signed integer byte, hence its MSB bit represents to sign of the integer. Bit 1 represents to negative sign and bit 0 represents to positive sign. This is why, above binary data is equivalent to -127 decimal value. 1 1 1 1 1 1 1 0 Sign bit 1 Byte
  • 64. 64 Basic C As the above byte is signed integer byte, hence its MSB bit represents to sign of the integer. Bit 1 represents to negative sign and bit 0 represents to positive sign. This is why, above binary data is equivalent to -127 decimal value. ✞ 1 //+--------------------- Sign bit (1) 1111111 b =>-127 d // Signed 8 bits long integer 3 11111111 b => 255d // Unsigned 8 bits long integer ✌ ✆ 1 1 1 1 1 1 1 1 1 Byte As the above byte is unsigned integer byte. This is why, above binary data is equivalent to 255 decimal value. A signed integer ranges from -2147483647 to 2147483647 while unsigned integer ranges from 0 to 4294967294. In the C, bit ‘0’ is used for positive sign and bit ‘1’ is used for negative sign. Now, a question is here that what will happen if we store a negative number to the unsigned variable? For example, ✞ 1 unsigned char i=-16; // char type for one byte long data ✌ ✆ The answer is that, here, compiler uses one’s complement method to store the negative value. It means first, 16 is converted into binary data and then it is complemented and added by bit 1. The result thus obtained is stored in the memory address pointed by the variable. 1 Byte 0 0 0 1 0 0 0 0 = 1610 1 Byte 1 1 1 0 1 1 1 1 = 23910 Complement 1 Byte 1 1 1 1 0 0 0 0 = 24010 Complement + 1 Now, an unsigned variable (one byte long here) stores value -16 in memory as binary 11110000b. See the example given below: ✞ 1 #include <stdio.h> 3 int main () { unsigned char c = -16; 5 printf("%dn", c); return 0; 7 } ✌ ✆
  • 65. 1.3. VARIABLES 65 ✞ 240 ✌ ✆ Overflow of Data A variable declared as integer, long, float or double integer and character has capacity to store a specific size of data. An integer variable can not store data as long as float variable. This is why, a variable shall be declared of proper size for storing a data. To understand the overflow, consider a variable ‘k’ of virtual data type, DATATYPE, that can store only one byte long data. This variable ‘k’ may be signed or unsigned. First assume it is unsigned, then the largest decimal value, that can be stored by it is 255. Initially, ‘k’ is declared and initialized with decimal value 254. ✞ 1 DATATYPE k; k = 254d = 11111110 b; /*8 bit result */ ✌ ✆ Here, suffix ‘d’ represents the decimal form of number and ‘b’ represents to binary form of number. Now, ‘k’ is incremented by 1, it becomes ✞ k = 255d = 11111111 b; /*8 bit result */ ✌ ✆ Again, ‘k’ is incremented by 1, it becomes ✞ 1 k = 256d = 1 00000000 b; /*9 bit result */ ✌ ✆ The bit size of result is larger than one byte. The value of ‘k’ is reset to zero due to overflow. Here, overflow carry is ‘1’. Similarly a positive signed value becomes negative signed value if it is incremented beyond the signed data range. Taking the same data type DATATYPE, and variable ‘k’ with signed value. ✞ 1 /* Bit inside parentheses represents to sign .*/ signed DATATYPE k; 3 k = 127d = (0) 1111111b; ✌ ✆ Here, suffix ‘d’ represents the decimal form of number and ‘b’ represents to binary form of number. Now, ‘k’ is incremented by 1, the result becomes ✞ 1 /* Bit inside parentheses represents to sign .*/ k = -0d = (1) 0000000b; ✌ ✆ It becomes negative zero. Again, if ‘k’ is incremented by 1, the result becomes ✞ /* Bit inside parentheses represents to sign .*/ 2 k = -1d = (1) 0000001b; ✌ ✆ Which is -1. Here, again ‘k’ is overflowed.
  • 66. 66 Basic C 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 kth Byte + 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 kth Byte lth Byte Maximum size of one byte long data is decimal 255. When it is binary added by bit 1. The result becomes 256. The bit arrangement of result 256 is shown in above figure. Additive carry bit 1, is stored in another byte while actual byte has all 0 bits. One byte long data type variable (say ‘i’) that points to this byte takes additive carry bit as overflow bit and it is un-used for this variable. Therefore, the value of variable ‘i’ becomes zero. ✞ #include <stdio.h> 2 int main () { 4 int i; /* Four bytes long */ unsigned char *x; /* One byte long */ 6 for (i = 255; i <= 256; i++) { /* Points to each byte independently of integer i.*/ 8 x = (char *) &i; /* Print little endian byte only of integer i.*/ 10 printf("x[0] byte of integer %d is %dn", i, x[0]) ; } 12 return 0; } ✌ ✆ Little endian byte access by variable ‘x’ of above example is illustrated in the following figure. 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 x[0] Byte + 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 x[0] Byte Output of above example is shown below: ✞ x[0] byte of integer 255 is 255 x[0] byte of integer 256 is 0 ✌ ✆ See another example given below, in which result is not as required due to bigger size of data as the integer variable can store. An integer can store 2 or 4 byte long data. In
  • 67. 1.3. VARIABLES 67 numerical equivalent the maximum unsigned number can be stored by an integer variable is ‘2147483647’. If number is larger than it, the result is wiered. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { /* Signed value of an integer ranges * 6 * from -2147483648 to 2147483647. If * * integer value become larger than * 8 * 2147483647 it overflows by one bit * * and integer value becomes largest * 10 * negative number. */ signed int i = 2147483645; 12 int j; for (j = 0; j < 5; j++) 14 printf("%dn", i + j); return EXIT_SUCCESS ; 16 } ✌ ✆ ✞ 2147483645 2147483646 2147483647 -2147483648 -2147483647 ✌ ✆ The unsigned integers were standard in ISO C90. In later C standards, an integer is implicitly is a signed integer. Following example will give a strange result though the integer value is less than the largest unsigned integer value. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 /* Unsigned value of an integer* * ranges from 0 to 4294967295. */ 7 signed int i = 4294967293; int j; 9 for (j = 0; j < 5; j++) printf("%dn", i + j); 11 return EXIT_SUCCESS ; } ✌ ✆ ✞ -3 -2 -1 0 1 ✌ ✆
  • 68. 68 Basic C So, the double data type is used in place of unsigned int to used integers larger than 2147483647. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 /* Unsigned value of an integer* * ranges from 0 to 4294967295. */ 7 double i = 4294967293.00; double j; 9 for (j = 0; j < 5; j++) printf("%fn", i + j); 11 return EXIT_SUCCESS ; } ✌ ✆ ✞ 4294967293.000000 4294967294.000000 4294967295.000000 4294967296.000000 4294967297.000000 ✌ ✆ Following is another good example. ✞ 1 #include <stdio.h> 3 int Fac(int i) { int j = 1; 5 while (i > 0) { j = j*i; 7 i--; } 9 return j; } 11 int main () { 13 int i = 10; while (i < 15) { 15 printf("Factorial of %d is %dn", i, Fac(i)); i++; 17 } return 0; 19 } ✌ ✆ The output of the program is ✞ Factorial of 10 is 3628800 Factorial of 11 is 39916800 Factorial of 12 is 479001600 %Actual Factorial of 13 is 6227020800 Factorial of 13 is 1932053504 %Wiered result
  • 69. 1.3. VARIABLES 69 %Actual Factorial of 14 is 87178291200 Factorial of 14 is 1278945280 %Wiered result ✌ ✆ Memory Size (sizeof) sizeof () function is used to find the memory used by a variable, pointer, array or structure. Its result is used in implementation process. The return value of this function is either unsigned long or unsigned int. In the following example, memory spaced allocated or to be allocated for pointer-to-integer variables or pointer-to-arrays is obtained by using sizeof (). ✞ 1 #include <stdio.h> #include <limits.h> 3 int main (void ) { 5 int *a;/* Single pointer -to -integer variable */ printf("Storage size for a : %d n", sizeof (a)); 7 int *b[10];/* pointer -to -integer array with 10 elements */ printf("Storage size for b : %d n", sizeof (b)); 9 int *c[20];/* pointer -to -integer array with 20 elements */ printf("Storage size for c : %d n", sizeof (c)); 11 int *d[30];/* pointer -to -integer array with 30 elements */ printf("Storage size for d : %d n", sizeof (d)); 13 return 0; } ✌ ✆ The output is ✞ Storage size of a : 4 Storage size of b : 40 Storage size of c : 80 Storage size of d : 120 ✌ ✆ When sizeof is used to get the size of an array it returns one more than the actual size of array (size is sum of number of array elements and following null terminating character). It always returns size of first associated element if its argument is dereference to a pointer variable. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 /* arr[ ] points to the string , Hello.*/ const char arr[ ] = "Hello"; 6 /* *cp points to the address of char , H*/ const char *cp= "Hello"; 8 int main () { 10 /* Returns size of whole string including terminating char .*/ printf("Size of array %lun", (unsigned long ) sizeof (arr)); 12 /* Returns size of first character of string. It is char size .*/
  • 70. 70 Basic C printf("Size of *cp %lun", (unsigned long ) sizeof (*cp)); 14 exit ( EXIT_SUCCESS ); } ✌ ✆ ✞ Size of array 6 Size of *cp 1 ✌ ✆ Similarly for integer pointers ✞ #include <stdio.h> 2 /* *cp points to the address of integer */ 4 const int *cp = {10}; 6 int main () { /* Returns size of first element of integer array.*/ 8 printf("Size of *cp %lun", (unsigned long ) sizeof (*cp)); return 0; 10 } ✌ ✆ ✞ Size of *cp 4 ✌ ✆ Similarly, memory space used by an integer array can also be obtained. Remember that, size of a pointer is fixed for a compiler. All pointer types take same number of bytes for a compiler. That is why, we get the size of pointer ‘pi’ and ‘pc’ as 4 bytes in the following example. ✞ 1 #include <stdio.h> 3 int main () { /* Array of integers .*/ 5 int i[ ] = {1, 2, 3}; /* Point to address of first integer element .* 7 *Here pi is pointer to the integer array i.*/ int *pi = i; /* Size of pointer is fixed*/ 9 /* Array of characters .*/ 11 char c[ ] = {1, 2, 3}; /* Point to address of first character element .* 13 *Here pc is pointer to the character array c.*/ char *pc = c; /* Size of pointer is fixed*/ 15 printf("Size of i[ ] = %d n", sizeof (i)); 17 printf("Size of pi = %d nn", sizeof (pi)); 19 printf("Size of c[ ] = %d n", sizeof (c)); printf("Size of pc = %d n", sizeof (pc)); 21 return 0; 23 } ✌ ✆
  • 71. 1.3. VARIABLES 71 ✞ Size of i[ ] = 12 Size of pi = 4 Size of c[ ] = 3 Size of pc = 4 ✌ ✆ The safe way to use sizeof operator is; either cast the return value to unsigned long or to use the defined type size t provided in the ‘stddef.h’ header file. ✞ 1 #include <stddef.h> #include <stdio.h> 3 #include <stdlib.h> 5 main () { size_t sz; 7 sz = sizeof (sz); printf("Size of sizeof is %lun", 9 (unsigned long ) sz); exit ( EXIT_SUCCESS ); 11 } ✌ ✆ ✞ Size of sizeof is 4 ✌ ✆ Here is another example. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 const char *list [ ] = {"Red", "Green", "Blue ", "Black", "White"}; #define LIST_SIZE (sizeof(list )/sizeof(list [0]) ) 5 int main (int argc , char *argv [ ]) { 7 int ix; for (ix = 0; ix < LIST_SIZE ; ix ++) { 9 printf("%sn", list [ix]); } 11 return 0; } ✌ ✆ ✞ Red Green Blue Black White ✌ ✆ A function, equivalent to sizeof() function is explained in following example. ✞ 1 #include <stdio.h> 3 int main () {
  • 72. 72 Basic C /* Pointer ’s name . */ 5 char *ptA , *ptB; char fl; 7 /* Get initial pointer location for character */ ptA = &fl; 9 /* Get next pointer location for character . * * Addition of 1 in pointer , pointer jumps * 11 * equivalent to the zide of data type . */ ptB = (&fl + 1); 13 /* Size of character . */ printf("Size of char is %u", ptB - ptA); 15 return 0; } ✌ ✆ ✞ Size of char is 4 ✌ ✆ In case of numerical array, the argument of sizeof () function may be first element value itself of its data type. Both gives same result. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { float A[ ] = {10.10 , 50.50 , 4.57, 1.21}; 5 float B[ ] = {10.10 , 50.50 , 4.57, 1.21, 2.21}; printf("Elements in array A are : %dn", sizeof(A)/sizeof(float)); 7 printf("Elements in array A are : %dn", sizeof(A)/sizeof(A[0]) ); printf("Elements in array B are : %dn", sizeof(B)/sizeof(float)); 9 printf("Elements in array B are : %dn", sizeof(B)/sizeof(B[0]) ); return 0; 11 } ✌ ✆ ✞ Elements in array A are : 4 Elements in array A are : 4 Elements in array B are : 5 Elements in array B are : 5 ✌ ✆ Casting We knew that, a data type arranges memory bytes to be read or write at once. For example, the character data type read and write one character in one byte at once. Integer data type uses four bytes at once to read or write one integer value, and so on. Casting is performed to convert a value of one data type into other form of data type. For example, conversion of integer data type into float or double data type, or conversion
  • 73. 1.3. VARIABLES 73 of integer data type into character data type. Actually, casting rearranges the number of bytes being read or write by a variable. i : 0×00 0×00 0×00 0×04 char c=(char) i; c : 0×00 0×00 0×00 0×04 In above figure, an integer ‘i’ is casted into character data type, i.e. data which was represented by group of four bytes is now arranged into data represented by group of one byte. Now, the character data type ‘c’ points to array of four bytes. In casting only way of grouping of bytes changes, while the number of bytes remain same. In C, there are two types of castings, (i) implicit casting and (ii) explicit casting. Implicit type casting is automatically handled by compiler i.e. when two or more datatypes are under execution. The final data-type will be that data type which is declared. ✞ // integer data type variable declared & initialized 2 int i = 2; // double data type variable declared & initialized 4 double j = 2; // integer i is casted as double and used 6 double k = j/i; ✌ ✆ An explicit type cast is a cast that should we specifically invoked with either of the cast. The compiler does not automatically invoke to resolve the data type conversion. ✞ // integer data type variable declared & initialized 2 int i = 2; double j = i; // implicit casting 4 double k = (double) i; // explicit casting or forced casting ✌ ✆ In casting, data of one data type is converted into data of other data type. Therefore, there is loss of data. Loss of data is due to way and length of reading data stored in the memory. The same binary data of memory bytes are read in different way for character data type or integer data type or in float data type. For example, if double data type is casted as integer data type, then compiler shows warning. ✞ // double data type variable declared & initialized 2 double i = 2.0; int j = i; /* warning !! as double (8 bytes size ) * 4 *is casted to integer (4 bytes size ). * *Possible loss of data */ ✌ ✆ In case of referencing, implicit casting results warning, while explicit casting is acceptable without warning. ✞ 1 // integer data type variable declared & initialized int i = 2; 3 // double data type variable declared & initialized double j = 2.5;
  • 74. 74 Basic C 5 double *k = &j; // explicit casting or forced casting i = k; // warning !! assignment makes integer from 7 // pointer without a cast i = (int) k;// explicit casting , acceptable ✌ ✆ See an example for casting that is given below: ✞ #include <stdio.h> 2 void main () { 4 /* Integer type values.*/ int m1 = 70, m2 = 70, m3 = 100, total; 6 /*’per ’ variable is float type .*/ float per; 8 /* Total is integer type .*/ total = m1 + m2 + m3; 10 /* Result ’per’ variable is of integer type .* *as all the variables are integer type . */ 12 per = total / 300 * 100; /*’per ’ are called as float while * 14 *all the variables are integer type .*/ printf("The perc is %f", per); 16 printf("n"); /* Result ’per’ variable is integer type . * 18 *’total’ is cast as float. So that result * *via ’per’ variable convert to float type .*/ 20 per = (float) total / 300 * 100; // Explicit casting /*’per ’ are called as float.*/ 22 printf("The perc is %f", per); printf("n"); 24 } ✌ ✆ Output of above program is ✞ The perc is 0.000000 The perc is 80.000000 ✌ ✆ The casting data type is always put inside the parentheses otherwise compiler tries to re-declare existing variable again and shows compile time error. Scope of Variables A variable has either global or local scope. A variable declared at the header of program has global access restrict to the code file. A variable declared inside a function has scoped only within the function. A variable declared within braced block has scope within the block only. ✞ #include <stdio.h> 2 int i = 0; /* Global scope of variable .*/ 4 int main () {
  • 75. 1.3. VARIABLES 75 int j = 10; /* Local scope within main ()*/ 6 { /* Start of new block 1*/ int j = 20; /* Local scope within block 1*/ 8 printf("j inside block 1 is %dn", j); { /* Start of new block 2*/ 10 int j = 30; /* Local scope within block 2*/ printf("j inside block 2 is %dn", j); 12 } /* End of the block 2*/ printf("j inside block 1 is %dn", j); /*j=2*/ 14 } /* End of the block 1*/ printf("j within main () is %dn", j); 16 printf("i within main () is %dn", i); printf("Updated j within main () is %dn", ++j); 18 printf("Updated i within main () is %dn", ++i); /* Try to update value of i. Compile error * 20 *as i has local scope within braced block*/ //i = 3; 22 // printf (" Updated i is %dn", i); return 0; 24 } ✌ ✆ ✞ j inside block 1 is 20 j inside block 2 is 30 j inside block 1 is 20 j within main () is 10 i within main () is 0 Updated j within main () is 11 Updated i within main () is 1 ✌ ✆ A variable declared as extern qualifier has global access to whole program. Using extern qualifiers we can access the variables declared in other code files of a program. 1.3.2 Qualifiers Qualifiers are those keywords which are used to restrict the nature of a variable. A variable declared as const type can not be updated later. Similarly, a variable declared as extern can access to variable declared in other code files within the program. const Qualifier When the const qualifier is used, the declared variable must be initialized at declaration. It is then not allowed to be changed. const declaration creates the declared variable as read only. The method of const declaration is ✞ 1 const int i = 12; // OK ✌ ✆ The constant variable must be defined when they are declared as shown above. Therefore, it is not allowed to declare const variable as given below.
  • 76. 76 Basic C ✞ 1 const int i; i=12; // Not OK ✌ ✆ An array can also be declared const that can not be altered later. For example ✞ const int mdays[12] = {31 ,28 ,31 ,30 ,31 ,30 ,31 ,31 ,30 ,31 ,30 ,31}; ✌ ✆ A pointer can also be declared as constant. ✞ 1 const float * ptrf ; /* ptrf points to a constant float value */ ✌ ✆ In following example, i is declared as constant integer equal to 10. It is printed int the output console. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { /* Declare i as constant integer .* 5 * And initialize it at here . */ const int i = 10; 7 printf("i is %dn", i); return 0; 9 } ✌ ✆ ✞ i is 10 ✌ ✆ But changing the value of variable i is not allowed. In following example, compiler shows error at i++; ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { /* Declare i as constant integer .* 5 * And initialize it at here . */ const int i = 10; 7 printf("i is %dn", i); /* Increment of i is not allowed.*/ 9 i++; /* Illegar expression . Will show error.*/ printf("i++ is %dn", i); 11 return 0; } ✌ ✆ The const type variable can not be assigned new values. But value can be changed by other code or pointer. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main () { const volatile int i = 10;
  • 77. 1.3. VARIABLES 77 6 printf("i is %d n", i); int *mod = (int*) &i; 8 *mod = 20; printf("Now , i is %d n", i); 10 return (EXIT_SUCCESS ); } ✌ ✆ ✞ i is 10 Now , i is 20 ✌ ✆ A structure is declared as const type and may or may not initialized. Further, the data members of the instances can not be modified later. If we try to modify them, a compile time error (‘assignment to read-only type variable’) is shown by the compiler. See the example below: ✞ #include <stdio.h> 2 #include <stdlib.h> 4 struct myS { int i; 6 int j; }; 8 int main (void ) { 10 /* struct instances s is declared & * *assigned values to its members */ 12 struct myS s = {9, 19}; printf("s : %d, %dn", s.i, s.j); 14 /* Update member values of s*/ s.i = 10; 16 s.j = 20; printf("s : %d, %dn", s.i, s.j); 18 /* struct instances t is declared here as const* *and it is initialized with initial values. */ 20 const struct myS t = {15, 25}; printf("t : %d, %dn", t.i, t.j); 22 /* Update member values of const type t* *It returns errors at compile time . */ 24 //t.i = 16;// Uncomment line to see the error return 0; 26 } ✌ ✆ ✞ s : 9, 19 s : 10, 20 t : 15, 25 ✌ ✆
  • 78. 78 Basic C static Qualifier When we declare a function or global variable as static it becomes internal. We cannot access the function or variable through the extern keyword from other files. When we declare a local variable as static, it is created just like any other variable. However, when the variable goes out of scope the variable stays in memory, retaining its value, until the program ends. Variables declared static are initialized to zero (or for pointers, NULL) by default. ✞ 1 #include <stdio.h> 3 /* This variable is accessed by both up() and down () functions .*/ static int j = 0; 5 void up(void ) { 7 /*k is set to 0 when the program starts. The line * *is then "ignored" for the rest of the program . * 9 *(k is not set to 0 every time up() is called) */ static int k = 0; 11 j++; k++; 13 printf("up() called. k= %2d, j= %2dn", k, j); } 15 void down (void ) { 17 static int k = 0; j--; 19 k--; printf("down () called. k= %2d, j= %2dn", k, j); 21 } 23 int main (void ) { int i; 25 /* Call the up function 3 times , then the down function 2 times*/ for (i = 0; i < 3; i++) 27 up (); for (i = 0; i < 2; i++) 29 down (); return 0; 31 } ✌ ✆ Output of above function is ✞ up() called. k=1, j=1 up() called. k=2, j=2 up() called. k=3, j=3 down () called. k=-1, j=2 down () called. k=-2, j=1 ✌ ✆ The ‘j’ variable is accessible by both up and down and retains its value. The ‘k’ variables also retain their value, but they are two different variables, one in each of their scopes. Static variables are a good way to implement encapsulation.
  • 79. 1.3. VARIABLES 79 Property Default Value Keyword used static Storage Memory Default value Zero Scope Local to the block in which it is declared Life Time Value persists between different function calls Optionality Mandatory to use the keyword Table 1.11: Features of static variable. When a variable is declared as static, it is assigned value ‘0’ automatically. ✞ 1 #include <stdio.h> 3 int main () { static int i; 5 int j; printf("%dn", i); // prints 0 7 printf("%dn", j); //j acts as wild pointer , prints garbage return 0; 9 } ✌ ✆ ✞ 0 1629773328 ✌ ✆ Static variable initialized once can not be re-initialized, but the variable can store new value. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 void print(void ) { /* Static initialization of a*/ 6 static int a = 0; /* Print value of a*/ 8 printf("%dn", a); /* Increment of the static value*/ 10 a++; } 12 int main (void ) { 14 print(); //a is initialized in this function call print(); //a is NOT reinitialized but stores a+1 value 16 print(); //a is NOT reinitialized but stores a+2 value return 0; 18 } ✌ ✆
  • 80. 80 Basic C ✞ 0 1 2 ✌ ✆ C does not advocate to return the address of a local variable to outside of the function. Hence it is recommended that the local variable should be defined as static variable. Take and example as given below: ✞ 1 #include <stdio.h> int * myF( ) { 3 int r[1]; r[0]=10; 5 return r; } 7 int main () { int *p; 9 p = muF(); printf("%dn", *p); 11 return 0; } ✌ ✆ On compilation of above program, the result shall be shown correctly but the compiler shall warn about that the function returns address of local variable. Output of above example is looked like ✞ warning: function returns address of local variable [-Wreturn -local -addr ] return r; ^ 10 ✌ ✆ When integer variable ‘r’ is declared as static, the compiler gives output without warning. ✞ #include <stdio.h> 2 int * myF( ) { static int r[1]; 4 r[0]=10; return r; 6 } int main () { 8 int *p; p = muF(); 10 printf("%dn", *p); return 0; 12 } ✌ ✆ ✞ 10 ✌ ✆
  • 81. 1.3. VARIABLES 81 extern Qualifier extern is used when a file needs to access a variable in another file that it may not have #include directly. Therefore, extern does not actually carve out space for a new variable, it just provides the compiler with sufficient information to access the remote variable. Property Default Value Keyword used extern Storage Memory Default value Zero Scope Global (all over the program) Life Time Value persists till the program’s execution Optionality Optional if declared outside all the functions Table 1.12: Features of extern variable. The syntax of this qualifier is ✞ 1 /* Implicit declaration of variable , this only described * * and assumed allocated elsewhere , normally from include */ 3 extern int AVar ; /* Custom function that will increase external variable by one*/ 5 void MyFunc(void ) { ++ AVar ; 7 } ✌ ✆ Assume a simple program which has three code files. First main file ‘main.c’, second header file ‘myH.h’ and third function file ‘Incr.c’. The codes in header file ‘myH.h’, are ✞ 1 void Incr (); ✌ ✆ The codes in function file ‘Incr.c’, are ✞ 1 int in =0; void Incr (){ 3 in ++; } ✌ ✆ The codes in main file ‘main.c’, are ✞ #include <stdio.h> 2 #include "myH.h" int main () { 4 /* Try to access the ’in’ variable * *declared in other program file .*/ 6 extern int in; Incr ();/* Increments to ‘in’ declared in ‘Incr .c’ file .*/
  • 82. 82 Basic C 8 printf("%d", in);/* Prints result of external ‘in’*/ return 0; 10 } ✌ ✆ By using extern qualifier, we can access to the variable ‘in’ declared and initialized in function file ‘Incr.c’. The function ‘Incr()’ increments to the variable which is printed in output by using printf function. The output of the above program is ✞ 1 ✌ ✆ If the code line ✞ 1 extern int in; ✌ ✆ given in above ‘main.c’ file is rewritten as ✞ 1 int in; ✌ ✆ then, the program output shall be ‘0’. It is because ‘Incr()’ function increments to the variable declared in its ‘Incr.c’ file. Inside the main() function of ‘main.c’ file, we print output by using printf function and by this function value of locally declared ‘in’ variable is ptrinted, which is 0 by default. See the modified codes of ‘main.c’ file ✞ 1 #include <stdio.h> #include "myH.h" 3 int main () { /*‘in ’ variable is declared locally here .*/ 5 int in; Incr ();/* Does not increment to locally declared ‘in’*/ 7 printf("%d", in);/* Prints result of local ‘in’*/ return 0; 9 } ✌ ✆ ✞ 0 ✌ ✆ volatile Qualifier volatile is a special type modifier which informs the compiler that the value of the variable may be changed by external entities other than the program itself. The value of volatile variable may change between two successive readings of the variable even though program has not modify the value of volatile type variable. It is good practice to read the variable value each time before program tries to accessing it. volatile is relevant with embedded systems. In embedded systems a program has not have complete control on a variable. The syntax for volatile qualifier is ✞ 1 int volatile i; ✌ ✆ See the example below in which a variable ‘i’ is declared as constant. The value of the variable ‘i’ can not be changed by program itself.
  • 83. 1.3. VARIABLES 83 ✞ 1 #include <stdio.h> 3 int main (void ) { /* Declare i as constant integer */ 5 const int i = 10; int *j = (int*) &i; 7 printf("Value of i is : %d n", i); /* Try to modify value of i*/ 9 *j = 100; printf("New value of i is : %d n", i); 11 return 0; } ✌ ✆ ✞ Value of i is : 10 New value of i is : 10 ✌ ✆ Now, the same variable ‘i’ is declared as constant and volatile. The value of the variable ‘i’ can be changed by program itself. ✞ #include <stdio.h> 2 int main (void ) { 4 /* Declare i as constant integer */ const volatile int i = 10; 6 int *j = (int*) &i; printf("Value of i is : %d n", i); 8 /* Try to modify value of i*/ *j = 100; 10 printf("New value of i is : %d n", i); return 0; 12 } ✌ ✆ ✞ Value of i is : 10 New value of i is : 100 ✌ ✆ auto Qualifier auto is a modifier which specifies an “automatic” variable that is automatically created when in scope and destroyed when out of scope. If you think this sounds like pretty much what you’ve been doing all along when you declare a variable, you’re right: all declared items within a block are implicitly “automatic”. For this reason, the auto keyword is more like the answer to a trivia question than a useful modifier, and there are lots of very competent programmers that are unaware of its existence. The automatic variable is not initialized at all.
  • 84. 84 Basic C Property Default Value Keyword used auto Storage Memory Default value Garbage value or random value Scope Local to the block in which it is defined Life Time Value persists till the control remains within the block Optionality Optional Table 1.13: Features of auto variable. In following example, ‘b’ has declared as automatic variable and it has scope only inside the block where it is declare. Here, ‘b’ is declared outside the main function block, so on compilation, it shows an error. ✞ #include <stdio.h> 2 /* Automatic variable b*/ auto int b = 10; 4 int main () { 6 auto int a = 5; a++; 8 printf("%dn", a); printf("%dn", b); 10 return 0; } ✌ ✆ In following example, variable ‘b’ is global integer while a is defined as automatic inside the main() function. Hence variable ‘a’ and ‘b’ are accessible inside the main() function. ✞ 1 #include <stdio.h> /*b has declared as global.*/ 3 int b = 10; 5 int main () { auto int a = 5; 7 a++; printf("a : %dn", a); 9 printf("b : %dn", b); return 0; 11 } ✌ ✆ ✞ a : 5 b : 10 ✌ ✆
  • 85. 1.3. VARIABLES 85 When defining a variable, we dont actually need to state its type explicitly when it can be deduced from the auto initializer. With auto, we use equal (=) syntax because there is no type conversion involved that might cause problems. See the example below: ✞ #include <stdio.h> 2 int main () { 4 auto i = ’c’; printf("%c ", i); 6 return 0; } ✌ ✆ ✞ c ✌ ✆ register Qualifier Storing and retrieving of data in memory is slower than storing and retrieving of data from CPU resistors. Hence, sometime storing and retrieving of data from resistor makes a program run faster. register is a hint to the compiler to attempt to optimize the storage of the given variable by storing it in a register of the computer’s CPU when the program is run. Most optimizing compilers do this anyway, so use of this keyword is often unnecessary. In fact, ANSI C states that a compiler can ignore this keyword if it so desires and many do. Property Default Value Keyword used register Storage CPU registers (values can be retrieved faster than from memory) Default value Garbage value Scope Local to the block in which it is defined Life Time Value persists till the control remains within the block Optionality Mandatory to use the keyword Table 1.14: Features of register variable. Example for register type variable is given below. ✞ 1 #include <stdio.h> 3 int main () { register int i; 5 for (i = 0; i < 5; i++) {
  • 86. 86 Basic C 7 printf("Value is %d n", i); } 9 } ✌ ✆ ✞ Value is 0 Value is 1 Value is 2 Value is 3 Value is 4 ✌ ✆ When a C-program is run, the main() function refers to two special purpose registers, i.e. ‘rbp’ and ‘rsp’. ‘rbp’ is the base pointer, which points to the base of the current stack frame, and ‘rsp’ is the stack pointer, which points to the top of the current stack frame. When a variable is added in stack, ‘rbp’ increments by one and points to next memory cells to store next variable value. In GCC, register keyword with asm keyword provides access to these special purpose registers directly as shown in the following example. ✞ 1 #include <stdio.h> #include <stdlib.h> 3 int main (void ) { 5 register long rsp asm("rsp"); register long rbp asm("rbp"); 7 int i = 10; // value at rbp -0x4 int j = 20; // value at rbp -0x8 9 int k = 30; // value at rbp -0 x12 printf("rpb = %lxn", rbp); /* Current pointer of rbp * 11 * points next empty cell */ printf("a = %dn", *( int *) ((( char *) rbp) - 0x4)); 13 printf("b = %dn", *( int *) ((( char *) rbp) - 0x8)); printf("c = %dn", *( int *) ((( char *) rbp) - 0xc)); 15 printf("rsp = %lxn", rsp); return (0); 17 } ✌ ✆ ✞ rpb = 22cd 68 a = 10 b = 20 c = 30 rsp = 22cd 40 ✌ ✆ See another example, in which accumulator register is accessed through register keyword. ✞ 1 #include <stdio.h> 3 int main () { int out; 5 register char bx asm("ebx"); /* Add 10 and 20 and store * 7 *result into register %eax*/
  • 87. 1.3. VARIABLES 87 __asm__ ("movl $10 , %% eax;" 9 "movl $20 , %% ebx;" "addl %%ebx , %% eax;" 11 : "=a" (out) ); 13 printf("Sum is %dn", out); printf("bx register has %dn", bx); 15 return 0; } ✌ ✆ ✞ Sum is 30 bx register has 20 ✌ ✆ restrict Qualifier restrict keyword is used with pointers only. It restricts the access of the object pointed by pointer only through the pointer pointing to that object. It helps compiler for not further checks. If this keyword is not used properly, result becomes undefined. This keyword is used to optimize the assembler codes. attribute & pragma pragma and attribute directives are used to tell the program that which parts of the codes shall be executed before (at run) or after (at exit) running of the main program. #pragma does not support by gcc compiler. The use of #pragma and attribute direc- tives is given below: ✞ #pragma startup <func1 > 2 #pragma exit <func2 > // 4 void __attribute__ (( constructor )) <func1() >; void __attribute__ (( destructor )) <func2() >; ✌ ✆ See the program given below: ✞ 1 #include <stdio.h> 3 void myFuncA (); void myFuncB (); 5 void __attribute__ (( constructor )) myFuncA (); 7 void __attribute__ (( destructor )) myFuncB (); 9 void myFuncA () { printf("Inside my function A.n"); 11 } 13 void myFuncB () { printf("Inside my function B.n");
  • 88. 88 Basic C 15 } 17 int main () { printf("Inside main ()n"); 19 return 0; } ✌ ✆ ✞ Inside my function A. Inside main () Inside my function B. ✌ ✆ These directives are used to warn users about the dependencies or pre-requirements of specific libraries for the given program. 1.4 C Operators 1.4.1 Expression An expression is a combination of one or more explicit values, constants, variables, op- erators, and functions. The evaluated value of expression is assigned to another variable or printed in output stream. If a function is present in an expression and the function is declared as void return type, then returned value is discarded in that expression. For example y = x2 + b ∗ x + 9 is an expression of variables ‘x’ and ‘y’ while ‘b’ and ‘9’ are constants. ‘y’ is dependent variable and other variables are either constant or independent. The terms of expression are evaluated as their mathematical operations. Here ‘ˆ’ means power rather than bitwise operator. ‘b’ and ‘x’ are in product (‘*’ means multiplication) and all the terms in right hand side are in summation. The expression with function is declared as y = x2 + myF(x) Where ‘myF()’ is user defined function. 1.4.2 Instructions There are three types of instructions in C. Declaration instruction, arithmetic instruction and control instruction. Declaration instructions are used in declaration of data type, assigning values and evaluation of operators. ✞ 1 int i; // Declaration Instruction int j=0; // Declaration Instruction ✌ ✆ Arithmetic instructions are used to perform arithmetic operations on variables and con- stants. ✞ int i; // Declaration Instruction 2 int j=0; // Declaration Instruction int k = i + j; // Arithmetic Instruction ✌ ✆
  • 89. 1.4. C OPERATORS 89 Control instructions are used to control the flow of program. The control instructions are if, if-else, switch statements and other conditional operators. ✞ 1 int k = 1; // Declaration Instruction if(k>2){ // Control Instruction statement 3 printf("True "); }else { 5 printf("False"); } ✌ ✆ 1.4.3 Unary Operators In a unary operation, operator has only one operand. The unary operators used in C are given in table below. Type Representation Increment ++x, x++ Decrement – – x, x – – Address &x Indirection *x Positive +x Negative –x Ones’ complement ∼x Logical negation !x Sizeof sizeof x, sizeof (type-name) Cast (type-name) cast-expression In above table, ‘type-name’ is variable type, like int, char, long, double etc. ‘cast- expression’ is variable that is being converted from one data type to other data type. ✞ #include <stdlib.h> 2 int main () { 4 printf("Negative of 2 is %dn", -2); return 0; 6 } ✌ ✆ ✞ Negative of 2 is -2 ✌ ✆ Increment operator ‘++’ is used either as prefix or suffix to a variable. Both are not same. When ‘++’ operator is prefixed to variable then value of the variable is first incremented
  • 90. 90 Basic C and then used. Similarly, when ‘++’ operator is suffix to a variable then value of variable is used first then it is incremented. ✞ 1 /* Use then increment */ i ++; 3 /* Increment then use*/ ++ i; /* Equals to i = i + 1; */ ✌ ✆ Equivalent example for i + + is given below: ✞ #include <stdio.h> 2 int main () { 4 int i = 9; {/* Begin of i++ block*/ 6 printf("i is %dn", i);/* Use i*/ i = i + 1; /* Then increment it*/ 8 }/* End of i++ block*/ return 0; 10 } ✌ ✆ ✞ i is 9 ✌ ✆ Equivalent example for + + i is given below: ✞ 1 #include <stdio.h> 3 int main () { int i = 9; 5 {/* Begin of ++i block*/ i = i + 1; /* Increment i*/ 7 printf("i is %dn", i); /* Then use it*/ 9 }/* End of ++i block*/ return 0; 11 } ✌ ✆ ✞ i is 10 ✌ ✆ If increment or decrement operator is used with function parameter in a function call, then at first variable is computed and then its value is passed to the fuction as its argument. ✞ 1 #include <stdio.h> 3 int get(int i){ return i+1; 5 } 7 int main () { int i = 2;
  • 91. 1.4. C OPERATORS 91 9 /*Here , ++i = 3 and next ++i = 4. Now , i is replaced * *by 4. The value 4*4=16 is passed for function call */ 11 printf("%d", get (++i * ++i)); // Prints 17 return 0; 13 } ✌ ✆ ✞ 17 ✌ ✆ If one of the operand of a valid operator is another valid operator then it acts as unary operator as shown in the following example. ✞ 1 #include <stdio.h> 3 int main () { int z = 4 * -3 / -2; 5 printf("%d", z); return 0; 7 } ✌ ✆ ✞ 6 ✌ ✆ In this example, minus sign (–) is unary operator as its preceding operand is a valid multiplication operator. Hence, it makes number 3 and number 2 as negative numbers. 1.4.4 Binary Relation Operators Binary operators are those operators which require two operands. These operators are addition, subtraction, multiplication, division, less than, greater than, equals to etc. The relational binary operators are Operator Description < Less than > Greater than ≤ Less than or equal to ≥ Greater than or equal to == Equals ! = Not equals In relation, a < b indicates that ‘a’ is less than ‘b’ and ‘a’ may have infinite numbers of values which are lesser than ‘b’, i.e. (−∞, b). The value of ‘a’ shall be positive or negative depends on the value of ‘b’. a ≤ b is similar to a < b except ‘a’ can also be equal to ‘b’, i.e. (−∞, b]. a == b indicates than ‘a’ is exactly equal to ‘b’ and ‘a’ have no other value than ‘b’. a! = b means ‘a’ never be equal to ‘b’. ‘a’ may be lesser than or greater than ‘b’, i.e. (−∞, ∞)-(b).
  • 92. 92 Basic C ✞ 1 #include <stdio.h> #include <string.h> 3 int main (void ) { 5 int a = 5; int b = 2; 7 int c = 5; if (a < b) 9 printf("%d is less than %d.n", a, b); if (a > b) 11 printf("%d is greater than %d.n", a, b); if (a <= c) 13 printf("%d is either less than or equal to %d.n", a, c); if (a == c) 15 printf("%d is exactly equal to %d.n", a, c); if (a != b) 17 printf("%d is not equal to %d.n", a, b); return 0; 19 } ✌ ✆ Output of above program is ✞ 5 is greater than 2. 5 is either less than or equal to 5. 5 is exactly equal to 5. 5 is not equal to 2. ✌ ✆ Remember that ‘=’ and ‘==’ are not same. ‘=’ is used to assign a value to a variable and ‘==’ is used for comparison. For example, ‘c=20’ assigned the value 20 to variable c and returns true in output rather than comparing of c to 20. This is why, because C does not have a dedicated boolean type. So ‘0’ means false and anything else is true. ✞ int a = 20; // constant initialized 2 /* constant reassigned as 10 and* *a becomes 10 and returns true */ 4 if (a = 10) printf("Stuff"); // printing of this value. ✌ ✆ ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 20; if (i = j)// its true though i is not equal to j. 7 printf("i is equal to j.n"); // will be printed . if (i == j) 9 printf("i is perfectly equal to j.n"); // will be printed . } ✌ ✆
  • 93. 1.4. C OPERATORS 93 ✞ i is equal to j. i is perfectly equal to j. ✌ ✆ Again to be noted that, the equal operator (‘==’) is applicable between two values or between two variables or between a value and a variable. It is not applicable with references, i.e. pointers as they points to address not to values. For example ✞ #include <stdio.h> 2 int main () { 4 int *a, *b; // two integer type pointers a = malloc (4); // allocate memory for ptr a 6 b = malloc (4); // allocate memory for ptr b *a = 10; // store value for a 8 *b = 10; // store value for b if (a == b) { // REFERENCE comparison 10 printf("Equaln"); } else { 12 printf("Not Equaln"); } 14 return 0; } ✌ ✆ ✞ Not Equal ✌ ✆ Now above example is modified as shown below: ✞ 1 #include <stdio.h> 3 int main () { int *a, *b; // two integer type pointers 5 a = malloc (4); // allocate memory for ptr a b = malloc (4); // allocate memory for ptr b 7 *a = 10; // store value for a *b = 10; // store value for b 9 if (*a == *b) { // VALUE comparison printf("Equaln"); 11 } else { printf("Not Equaln"); 13 } return 0; 15 } ✌ ✆ ✞ Equal ✌ ✆ Similarly we should avoid comparison like ✞ 1 #include <stdio.h> int main () {
  • 94. 94 Basic C 3 int v = 20; if (0 < v < 10) { 5 printf("Stuff"); }else { 7 printf("noStuff "); } 9 return 0; } ✌ ✆ ✞ Stuff ✌ ✆ In above example, ‘v’ is greater than 0. Hence in first comparison, construct assign value 1 to variable ‘v’. Now, value of variable ‘v’ is compared to 10, which is true, so the statement block of if construct is executed. The appropriate form of comparison is shown in below example. ✞ 1 #include <stdio.h> int main () { 3 int v = 20; if (0 < v && v < 10) { 5 printf("Stuff"); }else { 7 printf("noStuff "); } 9 return 0; } ✌ ✆ ✞ noStuff ✌ ✆ 1.4.5 Comma Operator Comma operator (,) is a binary operator that evaluates its first operand and discards the result, and then evaluates the second operand and returns this value. In strings, comma operator acts as a separator. If comma separated expressions are enclosed inside the parentheses, then last expression is evaulated. The comma operator has the lowest precedence. When comma operator is combined with semicolon, then semicolon has lower precedence than comma. ✞ 1 a, b; c, d; => (a, b); (c, d); ✌ ✆ Example, when expression is separated by comma and enclosed within parantheses ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 5; /* First expression is evaluated and its result is discarded */
  • 95. 1.4. C OPERATORS 95 7 printf("%d", (i, j)); return 0; 9 } ✌ ✆ ✞ 5 ✌ ✆ Example, when expression is separated by comma and not enclosed within parantheses ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 5; printf("%d", i, j);// First expression is evaluated here 7 return 0; } ✌ ✆ ✞ 10 ✌ ✆ Above result is obtained with compilar warning. Another example ✞ 1 #include <stdio.h> 3 int main () { int i = 10; 5 int j = 5; /* First expression is evaluated and its * 7 * result is discarded but its result is * * used in evaluation of second expression .*/ 9 printf("%d", (i, i+j)); return 0; 11 } ✌ ✆ ✞ 15 ✌ ✆ If multiple expressions separated by comma operator, are returned by return keyword, then only last expression is returned while others are just discarded. ✞ 1 #include <stdio.h> 3 int myRet(){ return 1, 2, 3;// Last expression is evaluated 5 // and returned by return } 7 int main () { printf("%d", myRet()); 9 return 0; } ✌ ✆
  • 96. 96 Basic C ✞ 3 ✌ ✆ If multiple expressions separated by comma operator, are assigned to a variable then only last expression is assigned while others are just discarded. ✞ 1 #include <stdio.h> 3 int main () { // Last expression is assigned to i 5 int i = (1, 2, 3); printf("%d", i); 7 return 0; } ✌ ✆ 1.4.6 Bitwise Operator A bitwise OR (|) gives result ‘1’ if either one or both bits are ‘1’ otherwise result is zero. A bitwise AND (&) gives result ‘1’ if both bits are ‘1’ otherwise result is zero. A bitwise XOR (ˆ) results ‘1’ if only either of two bits1 are ‘1’ otherwise result is zero. A bitwise NOT (∼) or complement, is a unary operation that performs logical negation on each bit, forming the ones’ complement of the given binary value. Bits those are 0 become 1, and those that are 1 become 0. ✞ #include <stdio.h> 2 int main () { 4 /*10 is Binary equivalent to 1010 */ int i = 10; 6 /*5 is Binary equivalent to 0101 */ int j = 5; 8 /* --------------------------** Bitwise OR Operation is 10 1010 0101 12 ------ 1111 = 15 14 **-------------------------- */ printf("Bitwise OR of %d, %d is %d.n", i, j, (i | j)); 16 /* ----------------------------** Bitwise AND Operation is 18 1010 0101 20 ------ 0000 = 0 22 **---------------------------- */ printf("Bitwise AND of %d, %d is %d.n", i, j, (i & j)); 24 /* ----------------------------** 1 If both bits are opposite bits.
  • 97. 1.4. C OPERATORS 97 Bitwise XOR Operation is 26 1010 0101 28 ------ 1111 = 15 30 **---------------------------- */ printf("Bitwise XOR of %d, %d is %d.n", i, j, (i ^ j)); 32 /* -----------------------------------------** Bitwise NOT Operation is 34 00001010 = 10 (decimal) ------------------------------------- 36 11110101 = 117 (signed)=117 -128= -11 **----------------------------------------- */ 38 printf("Bitwise NOT of %d is %d.n", i, ~i); return 0; 40 } ✌ ✆ ✞ Bitwise OR of 10, 5 is 15 Bitwise AND of 10, 5 is 0. Bitwise XOR of 10, 5 is 15. Bitwise NOT of 10 is -11. ✌ ✆ The precedence for evaluation of Boolean expression are parentheses, NOT, AND and OR bitwise operators from high to low. Normally, bitwise & operator returns the value equal to or less than the lesser operand. This is why & operator is used to restrict the upper limit of the random result. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) { int i = 0; 6 while (i < 10) { printf("%d&%d=>%d, t", i, 5, i & 5); 8 i++; } 10 printf("n"); return EXIT_SUCCESS ; 12 } ✌ ✆ ✞ 0&5 => 0, 1&5 => 1, 2&5 => 0, 3&5 => 1, 4&5 => 4, 5&5 => 5, 6&5 => 4, 7&5 => 5, 8&5 => 0, 9&5 => 1, ✌ ✆ While bitwise | operator returns the value equal to or larger than the largest operand. This is why | operator is used to restrict the lower limit of random result. ✞ #include <stdio.h> 2 #include <stdlib.h> 4 int main (void ) {
  • 98. 98 Basic C int i = 0; 6 while (i < 10) { printf("%d|%d=>%d, t", i, 5, i | 5); 8 i++; } 10 printf("n"); return EXIT_SUCCESS ; 12 } ✌ ✆ ✞ 0|5=>5, 1|5=>5, 2|5=>7, 3|5=>7, 4|5= >5 5|5=>5, 6|5=>7, 7|5=>7, 8|5=>13, 9|5= >13 ✌ ✆ 1.4.7 Logical Operator C has no dedicated boolean type. This is why, it returns 0 on true state and any other value on false state. In C, the false state returns certain error codes. These certain codes are either pre-implemented in libraries are user implemented in the user defined functions. For example, in strcmp() function, when two strings as arguments of this function are exactly same then it returns 0 otherwise it returns -1. In C, Logical operators are those operators which compare the variables logically. Operator Description && Logical AND. If both the operands are non-zero, then condition becomes true. The two operands may be equal or unequal || Logical OR. If any of the two operands are non-zero, then condition becomes true. It is not matter that both operands are equal or not. ! Logical NOT. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. The precedence for evaluation of Boolean expression are parentheses, NOT, AND and OR logic operators from high to low. ✞ #include <stdio.h> 2 int main () { 4 int i = 10; /* Not zero , hence true value.*/ int j = 20; /* Not zero , hence true value.*/ 6 int k = 0; /* Zero , hence false value.*/ /* print "1" if both integers are not zero .*/ 8 printf("&& relation between %d, %d is %d.n", i, j, i && j); /* print "0" if any of two integers are zero .*/ 10 printf("&& relation between %d, %d is %d.n", i, k, i && k);
  • 99. 1.4. C OPERATORS 99 /* print "1" if any of two integers are not zero .*/ 12 printf("|| relation between %d, %d is %d.n", i, j, i || j); return 0; 14 } ✌ ✆ ✞ && relation between 10, 20 is 1. && relation between 10, 0 is 0. || relation between 10, 20 is 1. ✌ ✆ It is remembered that bitwise operation is performed between bits of binary numbers while logical operation is performed between two operand either binary or integer. Logical expressions are evaluated from left to right. Evaluation stops as soon as something is discovered that renders the expression false. ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { /* Here 6 is greater than 2. And it is true .* 5 * true value is logically ANDED with 3 and * * if result is equal to 3 then print value * 7 * is 1 otherwise print value is 0. */ printf("Expression result is %dn", 6 > 2 && 3 == 3); 9 return 0; } ✌ ✆ ✞ Expression result is 1 ✌ ✆ ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { int x=6; 5 /* Here x is equal to 6. So , the relation * 7 * x != 6 is false. Now second relation * * x / 2 < 5 is not evaluated here . So , * 9 * the result is 0. */ 11 printf("Expression result is %dn", x != 6 && x / 2 < 5); return 0; 13 } ✌ ✆ ✞ Expression result is 0 ✌ ✆ ✞ 1 #include <stdio.h> 3 int main (int argc , char *argv [ ]) { int x=4;
  • 100. 100 Basic C 5 /* Here x is not equal to 6. So , that * 7 * x != 4 is true . Now second relation * * x / 2 < 5 is logically ANDED with * 9 * the result of x != 6. Here x/2 is 2* * and 2 is less than 5, so logical * 11 * AND of left and right values is 1 */ 13 printf("Expression result is %dn", x != 6 && x / 2 < 5); return 0; 15 } ✌ ✆ ✞ Expression result is 1 ✌ ✆ A point shall be remember here, that evaluation of an expression is discontinued if the value of a conditional expression is determined early. See the example below: ✞ 1 #include <stdio.h> 3 int main () { int i; 5 int j = 0; for (i = 0; i < 5; i++) { 7 if ((i > 3) || (j > 4)) printf("Sr No %d, first line n", i); 9 else printf("Sr No %d, second line n", i); 11 } } ✌ ✆ In above example, ‘i’ is incremented from 0 to 4, while ‘j’ keep always equal to 0. This is why, j > 0 is always false. While ‘i’ is less than or equal to 3, if () condition remains false and codes within else block are executed. When ‘i’ becomes larger than 3, codes within if () block are executed even when condition or j remains false. This is due that OR operator returns true result. The output of this program is ✞ Sr No 0, second line Sr No 1, second line Sr No 2, second line Sr No 3, second line Sr No 4, first line ✌ ✆ 1.4.8 Shift Operator The logical shift operators defined in C are shown in the following table.