University Textbook โข EduArtha
Computer Programming in C
Master C programming โ data types, operators, control flow, functions, arrays, pointers, strings, structures, file handling, linked lists & more.
๐ 10 Chapters โข 200+ MCQs โข 12 Lab Experiments โข Real-life & Industry Problems
Foundations of C Programming
Character set, data types, operators & expressions
Basics and Introduction to C
Learning Objectives
- Understand the history and features of the C programming language
- Describe the structure of a C program
- Identify the C character set, identifiers, and all 32 keywords
- Declare variables and use all fundamental data types
- Work with constants, expressions, and all categories of operators
- Apply type casting โ both implicit and explicit
- Write, compile, and execute your first C program
1.1 History of C
The C programming language was developed by Dennis Ritchie at Bell Laboratories (AT&T) in 1972. It evolved from two earlier languages โ BCPL (Basic Combined Programming Language, by Martin Richards, 1967) and B (by Ken Thompson, 1970). C was originally designed to re-implement the UNIX operating system, which had previously been written in assembly language.
| Year | Language | Developer |
|---|---|---|
| 1967 | BCPL | Martin Richards |
| 1970 | B | Ken Thompson |
| 1972 | C | Dennis Ritchie |
| 1978 | K&R C | Kernighan & Ritchie (book) |
| 1989 | ANSI C (C89) | ANSI Committee |
| 1999 | C99 | ISO/IEC |
| 2011 | C11 | ISO/IEC |
| 2018 | C17 | ISO/IEC |
| 2024 | C23 | ISO/IEC |
1.2 Features of C
- Middle-level language โ combines features of high-level and low-level languages
- Structured programming โ supports functions and blocks
- Portability โ C programs can be compiled on different platforms with minimal changes
- Rich operator set โ arithmetic, bitwise, logical, relational, and more
- Pointers โ direct memory access and manipulation
- Fast execution โ compiled to machine code, close to hardware
- Extensible โ new functions can be added to the library
- Recursion โ functions can call themselves
1.3 Applications of C
C is used to build: Operating systems (Linux, Windows kernel), Embedded systems (microcontrollers, IoT), Compilers (GCC), Database engines (MySQL, PostgreSQL), Game engines, Device drivers, and Networking tools.
1.4 Structure of a C Program
C
/* Documentation Section (optional) */
/* Preprocessor Directives */
#include <stdio.h>
/* Global Declarations (optional) */
int globalVar = 10;
/* Main Function */
int main() {
/* Local Declarations */
int a = 5;
/* Executable Statements */
printf("Hello, World!\n");
return 0;
}
/* User-defined Functions (optional) */
Every C Program Must Have main()
The main() function is the entry point of every C program. The operating system calls main() when the program starts. return 0; indicates successful execution.
1.5 The C Character Set
| Category | Characters |
|---|---|
| Uppercase Letters | A B C D โฆ Z (26) |
| Lowercase Letters | a b c d โฆ z (26) |
| Digits | 0 1 2 3 4 5 6 7 8 9 (10) |
| Special Characters | ~ ! @ # $ % ^ & * ( ) _ + - = { } [ ] | \ : " ; ' < > ? , . / |
| Whitespace | Space, Tab (\t), Newline (\n), Carriage Return (\r) |
1.6 Identifiers and Naming Rules
An identifier is a name given to variables, functions, arrays, or any user-defined item. Rules:
- Must begin with a letter (A-Z, a-z) or underscore (_)
- Can contain letters, digits (0-9), and underscores
- Cannot start with a digit
- Cannot use C keywords as identifiers
- C is case-sensitive:
ageandAgeare different - No limit on length (but first 31 characters are significant in C89)
| Valid | Invalid | Reason |
|---|---|---|
count | 2count | Starts with digit |
_temp | int | Reserved keyword |
total_marks | total marks | Contains space |
MAX_SIZE | my-var | Contains hyphen |
1.7 Keywords in C
C has 32 reserved keywords (C89/C90). These cannot be used as identifiers.
| All 32 C Keywords | |||||||
|---|---|---|---|---|---|---|---|
auto | break | case | char | const | continue | default | do |
double | else | enum | extern | float | for | goto | if |
int | long | register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void | volatile | while |
1.8 Data Types
C provides several fundamental data types. The size may vary by platform; the table below shows typical sizes on a 32/64-bit system.
| Data Type | Size (bytes) | Range | Format Specifier |
|---|---|---|---|
char | 1 | -128 to 127 | %c |
unsigned char | 1 | 0 to 255 | %c |
short | 2 | -32,768 to 32,767 | %hd |
int | 4 | -2,147,483,648 to 2,147,483,647 | %d |
unsigned int | 4 | 0 to 4,294,967,295 | %u |
long | 4 or 8 | ยฑ2 billion (32-bit) or larger | %ld |
long long | 8 | -9.2ร10ยนโธ to 9.2ร10ยนโธ | %lld |
float | 4 | 3.4ร10โปยณโธ to 3.4ร10ยณโธ (6-7 digits precision) | %f |
double | 8 | 1.7ร10โปยณโฐโธ to 1.7ร10ยณโฐโธ (15-16 digits) | %lf |
long double | 12 or 16 | Extended precision | %Lf |
void | 0 | No value | โ |
C
#include <stdio.h>
int main() {
printf("Size of char: %zu byte\n", sizeof(char));
printf("Size of int: %zu bytes\n", sizeof(int));
printf("Size of float: %zu bytes\n", sizeof(float));
printf("Size of double: %zu bytes\n", sizeof(double));
printf("Size of long long: %zu bytes\n", sizeof(long long));
return 0;
}
1.9 Constants
Integer Constants
Decimal: 42, Octal (prefix 0): 052, Hexadecimal (prefix 0x): 0x2A
Suffixes: 10L (long), 10U (unsigned), 10UL (unsigned long), 10LL (long long)
Floating-Point Constants
3.14, 2.0e5 (= 200000.0), 1.5E-3 (= 0.0015). Default type is double; suffix f for float: 3.14f
Character Constants
A single character in single quotes: 'A', '9', '$'. Stored as ASCII integer value.
| Escape Sequence | Meaning | ASCII |
|---|---|---|
\n | Newline | 10 |
\t | Horizontal Tab | 9 |
\0 | Null character | 0 |
\\ | Backslash | 92 |
\' | Single quote | 39 |
\" | Double quote | 34 |
\a | Alert (bell) | 7 |
\b | Backspace | 8 |
\r | Carriage return | 13 |
String Constants
A sequence of characters in double quotes: "Hello". Automatically terminated with \0.
1.10 Variables
A variable is a named location in memory that holds a value which can change during program execution.
C
int age = 21; // Declaration + Initialization
float gpa; // Declaration only (contains garbage)
gpa = 8.75; // Assignment
char grade = 'A'; // Character variable
const int MAX = 100; // Constant โ cannot be changed
1.11 Expressions and Statements
An expression is a combination of variables, constants, and operators that evaluates to a value: a + b * c. A statement is a complete instruction ending with a semicolon: x = a + b;
1.12 Arithmetic Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
+ | Addition | 5 + 3 | 8 |
- | Subtraction | 5 - 3 | 2 |
* | Multiplication | 5 * 3 | 15 |
/ | Division | 5 / 3 | 1 (integer!) |
% | Modulus | 5 % 3 | 2 |
Integer Division Gotcha
5 / 3 gives 1, not 1.666! When both operands are integers, C performs integer division (truncates decimal). Use 5.0 / 3 or (float)5 / 3 to get 1.666667.
C
#include <stdio.h>
int main() {
int a = 17, b = 5;
printf("a + b = %d\n", a + b);
printf("a - b = %d\n", a - b);
printf("a * b = %d\n", a * b);
printf("a / b = %d\n", a / b); // Integer division
printf("a %% b = %d\n", a % b);
printf("a / b = %.2f\n", (float)a / b); // Float division
return 0;
}
1.13 Unary Operators
| Operator | Meaning | Example |
|---|---|---|
++x | Pre-increment (increment, then use) | x=5; y=++x; โ x=6, y=6 |
x++ | Post-increment (use, then increment) | x=5; y=x++; โ x=6, y=5 |
--x | Pre-decrement | x=5; y=--x; โ x=4, y=4 |
x-- | Post-decrement | x=5; y=x--; โ x=4, y=5 |
-x | Unary minus (negation) | x=5; -x โ -5 |
+x | Unary plus | x=5; +x โ 5 |
!x | Logical NOT | !0 โ 1, !5 โ 0 |
~x | Bitwise NOT (complement) | ~0 โ -1 (all bits flipped) |
sizeof(x) | Size in bytes | sizeof(int) โ 4 |
&x | Address of x | Returns memory address |
*p | Dereference pointer p | Returns value at address |
C
#include <stdio.h>
int main() {
int a = 5, b, c;
b = ++a; // Pre: a becomes 6, then b = 6
printf("After ++a: a=%d, b=%d\n", a, b);
a = 5;
c = a++; // Post: c = 5, then a becomes 6
printf("After a++: a=%d, c=%d\n", a, c);
printf("!0 = %d, !5 = %d\n", !0, !5);
printf("~0 = %d\n", ~0);
return 0;
}
1.14 Relational Operators
Relational operators compare two values and return 1 (true) or 0 (false).
| Operator | Meaning | Example (a=10, b=20) | Result |
|---|---|---|---|
== | Equal to | a == b | 0 (false) |
!= | Not equal to | a != b | 1 (true) |
< | Less than | a < b | 1 (true) |
> | Greater than | a > b | 0 (false) |
<= | Less than or equal | a <= b | 1 (true) |
>= | Greater than or equal | a >= b | 0 (false) |
1.15 Logical Operators
| Operator | Meaning | Example | Result |
|---|---|---|---|
&& | Logical AND | (5 > 3) && (2 < 4) | 1 (both true) |
|| | Logical OR | (5 > 3) || (2 > 4) | 1 (one true) |
! | Logical NOT | !(5 > 3) | 0 (negation) |
Short-Circuit Evaluation
In A && B, if A is false, B is never evaluated. In A || B, if A is true, B is never evaluated. This is called short-circuit evaluation and is often used for safe pointer checks: if (ptr != NULL && *ptr == 5)
1.16 Assignment Operators
| Operator | Example | Equivalent |
|---|---|---|
= | x = 10 | Assign 10 to x |
+= | x += 5 | x = x + 5 |
-= | x -= 3 | x = x - 3 |
*= | x *= 2 | x = x * 2 |
/= | x /= 4 | x = x / 4 |
%= | x %= 3 | x = x % 3 |
<<= | x <<= 2 | x = x << 2 |
>>= | x >>= 1 | x = x >> 1 |
&= | x &= 0xF | x = x & 0xF |
|= | x |= 0x1 | x = x | 0x1 |
^= | x ^= 0xFF | x = x ^ 0xFF |
1.17 Conditional (Ternary) Operator
C
int a = 10, b = 20;
int max = (a > b) ? a : b; // max = 20
printf("Max = %d\n", max);
// Equivalent to:
if (a > b) max = a;
else max = b;
1.18 Bitwise Operators
Bitwise operators work on individual bits of integer values.
| Operator | Name | Example (a=5 โ 0101, b=3 โ 0011) | Result |
|---|---|---|---|
& | AND | 5 & 3 โ 0101 & 0011 | 0001 = 1 |
| | OR | 5 | 3 โ 0101 | 0011 | 0111 = 7 |
^ | XOR | 5 ^ 3 โ 0101 ^ 0011 | 0110 = 6 |
~ | NOT | ~5 โ ~00000101 | 11111010 = -6 |
<< | Left Shift | 5 << 1 โ 0101 << 1 | 1010 = 10 |
>> | Right Shift | 5 >> 1 โ 0101 >> 1 | 0010 = 2 |
C
#include <stdio.h>
int main() {
int a = 5, b = 3; // a = 0101, b = 0011
printf("a & b = %d\n", a & b); // 0001 = 1
printf("a | b = %d\n", a | b); // 0111 = 7
printf("a ^ b = %d\n", a ^ b); // 0110 = 6
printf("~a = %d\n", ~a); // -6
printf("a << 1 = %d\n", a << 1); // 1010 = 10
printf("a >> 1 = %d\n", a >> 1); // 0010 = 2
return 0;
}
Left Shift = Multiply by 2โฟ, Right Shift = Divide by 2โฟ
x << n is equivalent to x ร 2โฟ. x >> n is equivalent to x / 2โฟ (integer division). This is much faster than multiplication/division and is used extensively in embedded systems and game engines.
1.19 Operator Precedence and Associativity
| Precedence | Operator | Description | Associativity |
|---|---|---|---|
| 1 (highest) | () [] -> . | Postfix | Left to Right |
| 2 | ++ -- + - ! ~ * & sizeof (type) | Unary/Prefix | Right to Left |
| 3 | * / % | Multiplicative | Left to Right |
| 4 | + - | Additive | Left to Right |
| 5 | << >> | Shift | Left to Right |
| 6 | < <= > >= | Relational | Left to Right |
| 7 | == != | Equality | Left to Right |
| 8 | & | Bitwise AND | Left to Right |
| 9 | ^ | Bitwise XOR | Left to Right |
| 10 | | | Bitwise OR | Left to Right |
| 11 | && | Logical AND | Left to Right |
| 12 | || | Logical OR | Left to Right |
| 13 | ?: | Ternary | Right to Left |
| 14 | = += -= *= /= %= etc. | Assignment | Right to Left |
| 15 (lowest) | , | Comma | Left to Right |
1.20 Type Casting
Implicit Casting (Widening / Type Promotion)
C automatically converts a smaller type to a larger type: char โ int โ long โ float โ double
C
int x = 10;
float y = 3.5;
float result = x + y; // x is promoted to float: 10.0 + 3.5 = 13.5
Explicit Casting (Narrowing)
C
float pi = 3.14159;
int truncated = (int)pi; // truncated = 3 (decimal lost!)
int a = 7, b = 2;
float div = (float)a / b; // 7.0 / 2 = 3.5 (not 3!)
Temperature Converter
A program that converts between Celsius and Fahrenheit โ commonly used in weather apps and IoT sensors.
C
#include <stdio.h>
int main() {
float celsius, fahrenheit;
int choice;
printf("=== Temperature Converter ===\n");
printf("1. Celsius to Fahrenheit\n");
printf("2. Fahrenheit to Celsius\n");
printf("Enter choice: ");
scanf("%d", &choice);
if (choice == 1) {
printf("Enter Celsius: ");
scanf("%f", &celsius);
fahrenheit = (celsius * 9.0 / 5.0) + 32;
printf("%.2fยฐC = %.2fยฐF\n", celsius, fahrenheit);
} else if (choice == 2) {
printf("Enter Fahrenheit: ");
scanf("%f", &fahrenheit);
celsius = (fahrenheit - 32) * 5.0 / 9.0;
printf("%.2fยฐF = %.2fยฐC\n", fahrenheit, celsius);
}
return 0;
}
Simple Calculator
C
#include <stdio.h>
int main() {
double a, b, result;
char op;
printf("Enter expression (e.g. 5 + 3): ");
scanf("%lf %c %lf", &a, &op, &b);
switch (op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '*': result = a * b; break;
case '/':
if (b != 0) result = a / b;
else { printf("Error: Division by zero!\n"); return 1; }
break;
case '%': result = (int)a % (int)b; break;
default: printf("Invalid operator!\n"); return 1;
}
printf("%.2lf %c %.2lf = %.2lf\n", a, op, b, result);
return 0;
}
Bit Manipulation for Embedded Systems Flags
In embedded systems (e.g., microcontrollers), hardware registers use individual bits as flags. Bitwise operators are essential for setting, clearing, and checking these flags without affecting others.
C
#include <stdio.h>
// Device status flags (each bit = one flag)
#define FLAG_POWER (1 << 0) // Bit 0: 0x01
#define FLAG_WIFI (1 << 1) // Bit 1: 0x02
#define FLAG_BLUETOOTH (1 << 2) // Bit 2: 0x04
#define FLAG_GPS (1 << 3) // Bit 3: 0x08
#define FLAG_ERROR (1 << 7) // Bit 7: 0x80
void printStatus(unsigned char reg) {
printf("Status: Power=%d WiFi=%d BT=%d GPS=%d Error=%d\n",
(reg & FLAG_POWER) ? 1 : 0,
(reg & FLAG_WIFI) ? 1 : 0,
(reg & FLAG_BLUETOOTH) ? 1 : 0,
(reg & FLAG_GPS) ? 1 : 0,
(reg & FLAG_ERROR) ? 1 : 0);
}
int main() {
unsigned char deviceReg = 0x00; // All off
// SET flags (turn ON): use OR
deviceReg |= FLAG_POWER;
deviceReg |= FLAG_WIFI;
printf("After power + wifi ON:\n");
printStatus(deviceReg);
// CLEAR a flag (turn OFF): use AND NOT
deviceReg &= ~FLAG_WIFI;
printf("After wifi OFF:\n");
printStatus(deviceReg);
// TOGGLE a flag: use XOR
deviceReg ^= FLAG_GPS;
printf("After GPS toggle:\n");
printStatus(deviceReg);
// CHECK a flag
if (deviceReg & FLAG_POWER)
printf("Device is powered ON\n");
return 0;
}
Multiple Choice Questions โ Chapter 1
Q1. Who developed the C programming language?
- Bjarne Stroustrup
- James Gosling
- Dennis Ritchie
- Ken Thompson
Q2. Which of the following is NOT a valid C identifier?
- _count
- 2ndValue
- total_marks
- MAX_SIZE
Q3. What is the size of int on most 32/64-bit systems?
- 1 byte
- 2 bytes
- 4 bytes
- 8 bytes
Q4. What is the output of printf("%d", 5/2);?
- 2.5
- 2
- 3
- 2.500000
Q5. What is the value of x after: int x=5; int y=x++;?
- 5
- 6
- 4
- Undefined
Q6. Which operator has the highest precedence?
+*()=
Q7. What is the result of 5 & 3 in binary?
- 7
- 6
- 1
- 8
Q8. The % operator works with:
- float operands only
- integer operands only
- any data type
- double operands only
Q9. What does sizeof(char) always return?
- 0
- 1
- 2
- Platform dependent
Q10. Which of the following is a valid float constant?
3.14f3.14.15314f..f
Q11. What is !0 in C?
- 0
- 1
- -1
- Undefined
Q12. Which storage is used for const int x = 10;?
- x can be modified later
- x is stored in ROM
- x cannot be modified after initialization
- x is stored in register
Q13. What is the output: printf("%d", (int)3.9);?
- 4
- 3
- 3.9
- Error
Q14. How many keywords does standard C (C89) have?
- 16
- 24
- 32
- 64
Q15. What is 5 << 2?
- 10
- 20
- 25
- 2
Q16. The ternary operator ?: is equivalent to:
- for loop
- while loop
- if-else
- switch
a ? b : c is shorthand for if-else.Q17. In the expression a + b * c, which operation happens first?
- Addition
- Multiplication
- Left to right
- Depends on compiler
Q18. What is the escape sequence for a tab character?
\n\t\b\r
Q19. C is considered a:
- High-level language only
- Low-level language only
- Middle-level language
- Machine language
Q20. What does & do in scanf("%d", &x);?
- Logical AND
- Bitwise AND
- Returns address of x
- Dereferences x
Chapter 1 Summary
- C was created by Dennis Ritchie at Bell Labs in 1972 for UNIX
- C has 32 keywords and is case-sensitive
- Primary data types:
int(4B),float(4B),double(8B),char(1B) - Operators: Arithmetic, Unary, Relational, Logical, Assignment, Ternary, Bitwise
++x(pre) increments before use;x++(post) uses then increments- Bitwise operators work on individual bits โ essential for embedded systems
- Integer division truncates:
5/2 = 2, use casting for float result - Operator precedence determines evaluation order; use parentheses when in doubt
- Type casting: implicit (automatic widening) and explicit
(type)