UNIT-1
UNIT-1
INTRODUCTION TO C:
Features of C:
1. Simplicity: C has a simple set of keywords, making it easier to learn and use
compared to many other languages. Its syntax is straightforward, yet powerful.
2. Portability: C programs can be easily transferred from one machine to another with
minimal or no modification, making it a highly portable language.
6. Efficiency: C programs are generally very efficient in terms of execution speed and
memory usage. This efficiency is a result of its close-to-hardware operations and
minimal runtime overhead.
10. Recursion: C supports recursion, where functions can call themselves. This is
useful for solving problems that can be broken down into smaller, similar sub-
problems.
11. Pointers: C includes extensive support for pointers, which are variables that store
memory addresses. Pointers are powerful for dynamic memory allocation, array
manipulation, and handling function arguments.
12. Bitwise Operations: C supports bitwise operators that enable manipulation of data
at the bit level, which is useful in systems programming, network programming, and
other low-level applications.
13. Fast Compilation and Execution: C compilers are generally very fast, and the
compiled code runs efficiently on most hardware, making it suitable for performance-
critical applications.
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Explanation:
- `#include <stdio.h>`: Includes the standard input-output library, providing functions
like `printf()`.
- `intmain()`: Entry point of the program, where execution begins.
- `printf("Hello, World!\n");`: Prints "Hello, World!" to the console.
- `return 0;`: Indicates successful program completion.
#include <stdio.h>
int main() {
int num1 = 10, num2 = 5;
int sum, difference, product;
float quotient;
return 0;
}
Explanation:
- `int num1 = 10, num2 = 5;`: Declares and initializes two integers.
- `int sum, difference, product; float quotient;`: Declares variables for storing results.
- Arithmetic operations (`+`, `-`, `*`, `/`) are performed.
- `(float)num1 / num2;`: Type casting ensures floating-point division.
- `%.2f`: Format specifier for printing floating-point numbers with two decimal places.
#include <stdio.h>
int main() {
intnum = 10;
if (num> 0) {
printf("Number is positive\n");
} else if (num< 0) {
printf("Number is negative\n");
} else {
printf("Number is zero\n");
}
return 0;
}
Explanation:
- `if`, `else if`, `else`: Used for conditional execution based on the value of `num`.
- `num> 0`: Condition for positive number.
- `num< 0`: Condition for negative number.
- `printf()`: Outputs the appropriate message based on the condition.
DATATYPES IN C:
In C programming, data types specify the type of data that a variable can hold. Here
are the primary data types in C:
These data types can be combined or used in combination with modifiers like `signed`,
`unsigned`, `short`, and `long` to specify the range and storage size of variables.
It's essential to choose the appropriate data type based on the requirements of your
program to efficiently use memory and ensure data integrity.
1. Arithmetic Operators:
- Addition `+`
- Subtraction `-`
- Multiplication `*`
- Division `/`
- Modulus `%` (remainder after division)
2. Relational Operators:
- Equal to `==`
- Not equal to `!=`
- Greater than `>`
- Less than `<`
- Greater than or equal to `>=`
- Less than or equal to `<=`
These operators compare two operands and return a Boolean value (`true` or `false`)
based on the comparison result.
3. Logical Operators:
- Logical AND `&&`
- Logical OR `||`
- Logical NOT `!`
These operators perform logical operations on Boolean operands and return Boolean
results.
4. Assignment Operators:
- Assignment `=`
- Compound assignment operators like `+=`, `-=`, `*=`, `/=`, `%=` etc.
This operator evaluates a condition and returns one of two expressions based on
whether the condition is true or false.
8. Comma Operator:
- `,`
This operator allows multiple expressions to be evaluated in a single statement, with
the value of the last expression being the result.
These operators and expressions form the foundation of C programming and are used
extensively in writing logic and algorithms. Understanding them thoroughly is crucial
for effective programming.
1. Arithmetic Operators:
int a = 10, b = 5;
int sum = a + b; // Addition
int difference = a - b; // Subtraction
int product = a * b; // Multiplication
int quotient = a / b; // Division
int remainder = a % b; // Modulus
2. Relational Operators:
int x = 10, y = 5;
if (x > y) {
printf("x is greater than y\n");
}
if (x != y) {
printf("x is not equal to y\n");
}
3. Logical Operators:
int p = 1, q = 0;
if (p && q) {
printf("Both p and q are true\n");
}
if (p || q) {
printf("At least one of p or q is true\n");
}
4. Assignment Operators:
intnum = 10;
num += 5; // Equivalent to num = num + 5
num *= 2; // Equivalent to num = num * 2
int count = 0;
count++; // Increment by 1
count--; // Decrement by 1
6. Bitwise Operators:
int x = 5, y = 3;
intbitwise_and = x & y; // Bitwise AND
intbitwise_or = x | y; // Bitwise OR
intbitwise_xor = x ^ y; // Bitwise XOR
intbitwise_not = ~x; // Bitwise NOT
int a = 10, b = 5;
int max = (a > b) ? a : b; // Assigns the larger of a and b to max
8. Comma Operator:
int a = 1, b = 2, c = 3;
int sum = (a + b, b + c); // sum will be assigned the value of b + c
struct Point {
int x;
int y;
};
intsize_int = sizeof(int);
intsize_char = sizeof(char);
In C programming, the scope and lifetime of variables determine where and for how
long a variable can be accessed and used within a program. Let's delve into each
concept with examples:
1. Scope: Scope refers to the region of the program where a variable is accessible.
There are three main scopes in C:
Block Scope: Variables declared within a block of code (within curly braces
`{}`) have block scope. They are accessible only within that block.
#include <stdio.h>
int main() {
int x = 10; // x has block scope
{
int y = 20; // y also has block scope
printf("x = %d\n", x); // x is accessible
printf("y = %d\n", y); // y is accessible
}
// printf("y = %d\n", y); // Error: y is not accessible outside its block
return 0;
}
#include <stdio.h>
voidmyFunction() {
int a = 5; // a has function scope
printf("a = %d\n", a); // a is accessible
}
int main() {
// printf("a = %d\n", a); // Error: a is not accessible here
myFunction();
return 0;
}
File Scope (Global Scope): Variables declared outside of all functions have file
scope. They are accessible from their declaration point until the end of the file.
#include <stdio.h>
voidmyFunction() {
printf("globalVar = %d\n", globalVar); // globalVar is accessible
}
int main() {
printf("globalVar = %d\n", globalVar); // globalVar is accessible
myFunction();
return 0;
}
2. Lifetime: Lifetime refers to the duration for which a variable exists in memory.
There are primarily three lifetimes in C.
#include <stdio.h>
voidmyFunction() {
int a = 5; // a has automatic lifetime
printf("a = %d\n", a); // a is accessible
}
int main() {
// printf("a = %d\n", a); // Error: a is not accessible here
myFunction();
return 0;
}
ii. Static Lifetime: Variables declared with the `static` keyword inside a function
have static lifetime. They are created when the program starts and destroyed
when the program terminates.
#include <stdio.h>
voidmyFunction() {
staticint b = 10; // b has static lifetime
printf("b = %d\n", b); // b is accessible
b++;
}
int main() {
myFunction();
myFunction();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(sizeof(int)); // Dynamically allocated memory
*ptr = 100;
printf("*ptr = %d\n", *ptr); // *ptr is accessible
free(ptr); // Deallocate memory
// printf("*ptr = %d\n", *ptr); // Error: *ptr is not accessible after
deallocation
return 0;
}
Understanding the scope and lifetime of variables is crucial for writing efficient and
bug-free C programs. It helps in managing memory effectively and prevents issues
like memory leaks and undefined behavior.
CONSTANTS:
In C programming, constants are values that do not change during the execution of a
program. They are used to represent fixed values that remain constant throughout the
program's execution. Constants in C can be categorized into two main types:
1. Numeric Constants: Numeric constants represent fixed numerical values. They can
be integers, floating-point numbers, or characters. Numeric constants can be specified
in various formats:
Integer Constants: These are whole numbers without any fractional part.
intnum = 10;
2. Symbolic Constants: Symbolic constants are identifiers that represent fixed values.
They are defined using the `#define` preprocessor directive or the `const` keyword.
Symbolic constants provide a way to give meaningful names to values, making the
code more readable and maintainable.
#define PI 3.14
#define MAX_SIZE 100
POINTERS:
Pointers in C are variables that store memory addresses. They are powerful features of
the language, allowing you to work directly with memory locations and manipulate
data efficiently. Here's an overview of pointers with examples:
1. Declaring Pointers:
Pointers are declared by adding an asterisk (*) before the variable name.
2. Assigning Pointers:
Pointers can be assigned the address of a variable using the address-of operator (&).
intnum = 10;
int *ptr = # // Assigns the address of num to ptr
intnum = 10;
int *ptr = #
printf("Value of num: %d\n", *ptr); // Prints the value of num (10)
4. Pointer Arithmetic:
Pointers can be incremented or decremented to navigate through memory locations.
The size of the data type being pointed to determines the step size.
5. Null Pointers:
Pointers can be explicitly set to NULL, indicating that they do not point to any valid
memory location.
intnum = 10;
int *ptr = #
int ptrPtr = &ptr; // Pointer to a pointer
Pointers are extensively used in C for tasks like array manipulation, dynamic memory
allocation, and passing parameters to functions by reference. While powerful, they
require careful handling to avoid common pitfalls like dangling pointers and memory
leaks.
ARRAYS:
Arrays in C are collections of elements of the same data type stored in contiguous
memory locations. They provide a convenient way to store and manipulate a fixed-size
sequence of elements. Here's an overview of arrays in C with examples:
1. Declaring Arrays:
Arrays are declared by specifying the data type of the elements and the number of
elements enclosed in square brackets ([]).
int numbers[5]; // Declares an array of 5 integers
float prices[10]; // Declares an array of 10 floating-point numbers
char name[20]; // Declares an array of 20 characters
2. Initializing Arrays:
Arrays can be initialized at the time of declaration or later using assignment
statements.
5. Multidimensional Arrays:
Arrays can have more than one dimension, allowing you to represent tables, matrices,
or other multi-dimensional data structures.
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
6. Strings as Arrays:
In C, strings are represented as arrays of characters, terminated by a null character (`'\
0'`).
char greeting[] = "Hello, World!";
7. Array Size:
The size of an array can be determined using the `sizeof` operator.
int numbers[5];
int size = sizeof(numbers) / sizeof(numbers[0]); // Calculates the size of the
array
STRINGS:
1. Declaring Strings:
Strings can be declared as character arrays, with enough space to store the characters
plus one additional character for the null terminator.
char greeting[20]; // Declares a string of 19 characters plus the null terminator
2. Initializing Strings:
Strings can be initialized at the time of declaration or later using assignment
statements.
5. String Input:
Strings can be read from the standard input using functions like `scanf()` or `fgets()`.
char name[50];
printf("Enter your name: ");
scanf("%s", name); // Reads a string from the user
printf("Hello, %s!\n", name);
6. String Functions:
C provides several string manipulation functions in the `<string.h>` header, such as
`strlen()`, `strcpy()`, `strcat()`, `strcmp()`, etc., for tasks like string length calculation,
copying, concatenation, and comparison.
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello";
char str2[] = "World";
return 0;
}
7. String Comparison:
Strings can be compared using the `strcmp()` function, which returns 0 if the strings
are equal, a negative value if the first string is lexicographically less than the second,
and a positive value otherwise.
char str1[] = "apple";
char str2[] = "banana";
Understanding strings and string manipulation functions is crucial for working with
text data in C programming. It allows you to perform tasks like input/output,
processing, and manipulation of textual data effectively.
CONTROL FLOW:
Control flow in C refers to the order in which statements are executed in a program. C
provides several control flow structures that allow you to alter the sequence of
execution based on conditions, loops, and function calls. Here's an overview of control
flow in C with examples:
#include <stdio.h>
int main() {
intnum = 10;
if (num> 0) {
printf("Number is positive\n");
} else if (num< 0) {
printf("Number is negative\n");
} else {
printf("Number is zero\n");
}
return 0;
}
2. Switch Statement:
The switch statement allows you to select one of many blocks of code to execute.
#include <stdio.h>
int main() {
int choice = 2;
switch (choice) {
case 1:
printf("Choice is 1\n");
break;
case 2:
printf("Choice is 2\n");
break;
case 3:
printf("Choice is 3\n");
break;
default:
printf("Invalid choice\n");
}
return 0;
}
3. Loops:
Loops allow you to execute a block of code repeatedly.
- For Loop:
#include <stdio.h>
int main() {
for (int i = 0; i < 5; i++) {
printf("Iteration %d\n", i);
}
return 0;
}
- While Loop:
#include <stdio.h>
int main() {
int i = 0;
while (i < 5) {
printf("Iteration %d\n", i);
i++;
}
return 0;
}
- Do-While Loop:
#include <stdio.h>
int main() {
int i = 0;
do {
printf("Iteration %d\n", i);
i++;
} while (i < 5);
return 0;
}
#include <stdio.h>
int main() {
for (int i = 0; i < 10; i++) {
if (i == 5) {
break; // Exit the loop when i is 5
}
if (i % 2 == 0) {
continue; // Skip even numbers
}
printf("%d\n", i);
}
return 0;
}
These control flow structures in C allow you to write programs that can make
decisions, iterate over data, and handle various scenarios based on conditions.
Understanding and using them effectively is essential for writing efficient and robust
C programs.
In C programming, functions are blocks of code that perform a specific task. They
allow you to organize code into manageable and reusable units. Here's an overview of
function and program structure in C:
// Function declaration
int add(int a, int b);
int main() {
int result = add(10, 20); // Function call
printf("Result: %d\n", result);
return 0;
}
// Function definition
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(10, 20); // Function call with parameters
printf("Result: %d\n", result);
return 0;
}
3. Function Prototypes:
Function prototypes declare the signature of a function before its actual
implementation. They are usually placed at the beginning of the file or in a header file.
// Function prototype
int add(int a, int b);
int main() {
int result = add(10, 20);
printf("Result: %d\n", result);
return 0;
}
4. Function Scope:
Variables declared inside a function have function scope and are accessible only
within that function.
int main() {
// printf("%d\n", sum); // Error: sum is not accessible here
return 0;
}
5. Program Structure:
A C program typically consists of one or more functions. The `main()` function is the
entry point of the program, from where execution begins.
#include <stdio.h>
// Function declaration
int add(int a, int b);
int main() {
int result = add(10, 20);
printf("Result: %d\n", result);
return 0;
}
// Function definition
int add(int a, int b) {
return a + b;
}
6. Header Files:
Header files contain function prototypes, constant declarations, and other preprocessor
directives. They are included in C programs using the `#include` directive.
// Example C program
#include <stdio.h>
#include "math.h" // Include user-defined header file
int main() {
int result = add(10, 20);
printf("Result: %d\n", result);
return 0;
}
NAMESPACES:
intmath_subtract(int a, int b) {
return a - b;
}
2. Static Keyword: The `static` keyword can be used to limit the scope of functions
and variables to the file in which they are defined. This helps prevent name clashes
between files.
// math_operations.c
staticint add(int a, int b) {
return a + b;
}
// main.c
#include <stdio.h>
int main() {
printf("Result: %d\n", add(10, 20)); // Error: add is not accessible from main.c
return 0;
}
3. File Scope: Functions and variables declared outside of any function, at the top of a
file, have file scope. They are accessible only within that file by default.
// math_operations.c
staticint add(int a, int b) {
return a + b;
}
4. Module or Object Files: You can also organize related functions and data
structures into separate module or object files, which are then linked together during
compilation. This helps compartmentalize code and reduce dependencies.
ERROR HANDLING IN C:
1. Return Values: Functions can return error codes or special values to indicate
success or failure. Conventionally, a return value of 0 indicates success, while non-
zero values represent different error conditions.
2. Global Variables: Global variables can be used to store error codes or status flags
that functions can check and update accordingly.
#include <stdio.h>
intlastError = 0;
int main() {
int result;
if (divide(10, 0, &result) != 0) {
printf("Error: Division by zero\n");
printf("Last error code: %d\n", lastError);
}
return 0;
}
#include <stdio.h>
#define ERROR_DIVISION_BY_ZERO -1
int main() {
int result;
int error = divide(10, 0, &result);
if (error != 0) {
printf("Error: Division by zero\n");
printf("Error code: %d\n", error);
}
return 0;
}
#include <stdio.h>
#define ERROR_DIVISION_BY_ZERO -1
voidreportError(interrorCode) {
switch (errorCode) {
case ERROR_DIVISION_BY_ZERO:
printf("Error: Division by zero\n");
break;
default:
printf("Unknown error\n");
}
}
int main() {
int result;
int error = divide(10, 0, &result);
if (error != 0) {
reportError(error);
}
return 0;
}
Input and output (I/O) operations are essential for interacting with users and external
data sources in C programming. C provides several standard functions for performing
I/O operations. Here's an overview of input and output in C:
#include <stdio.h>
int main() {
intnum;
printf("Enter a number: ");
scanf("%d", &num);
printf("You entered: %d\n", num);
return 0;
}
#include <stdio.h>
int main() {
FILE *fp;
intnum;
return 0;
}
3. Character I/O:
- `getchar()`: Reads a single character from the standard input.
- `putchar()`: Writes a single character to the standard output.
#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
ch = getchar();
printf("You entered: ");
putchar(ch);
putchar('\n');
return 0;
}
output:
4. String I/O:
- `gets()`: Reads a line of text from the standard input (deprecated due to security
vulnerabilities).
- `fgets()`: Reads a line of text from a file or the standard input.
- `puts()`: Writes a string to the standard output followed by a newline character.
#include <stdio.h>
int main() {
char str[100];
printf("Enter a string: ");
fgets(str, sizeof(str), stdin);
printf("You entered: ");
puts(str);
return 0;
output:
Enter a string: pani malar
You entered: pani malar
}
5. Error Handling:
- Functions like `scanf()` and `fgets()` return a value indicating the number of items
successfully read. This can be used for error checking.
- `ferror()` and `feof()` can be used to check for file I/O errors and end-of-file
conditions.
Input and output operations are fundamental to most C programs. Understanding how
to use standard input and output functions, as well as file I/O functions, is essential for
writing practical and useful programs. Additionally, error handling is crucial to ensure
that I/O operations are performed safely and reliably.
1. string.h:
- strlen(): Calculates the length of a string.
#include <stdio.h>
#include <string.h>
int main() {
charstr[] = "Hello, World!";
int length = strlen(str);
printf("Length of the string: %d\n", length);
return 0;
}
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello, World!";
char dest[20];
strcpy(dest, src);
printf("Copied string: %s\n", dest);
return 0;
}
#include <stdio.h>
#include <math.h>
int main() {
double num = 25.0;
double squareRoot = sqrt(num);
printf("Square root of %lf: %lf\n", num, squareRoot);
return 0;
}
Output: Square root of 25.000000: 5.000000
#include <stdio.h>
#include <math.h>
int main() {
double base = 2.0;
double exponent = 3.0;
double result = pow(base, exponent);
printf("%lf raised to the power %lf is %lf\n", base, exponent, result);
return 0;
}
Output:
2.000000 raised to the power 3.000000 is 8.000000
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(sizeof(int));
*ptr = 10;
printf("Value stored at dynamically allocated memory: %d\n", *ptr);
free(ptr); // Free dynamically allocated memory
return 0;
}
These are just a few examples of library functions from `string.h`, `math.h`, and
`stdlib.h` in C. These libraries offer a wide range of functions for string manipulation,
mathematical operations, memory allocation, and more, making them invaluable for
developing C programs.
#include <stdio.h>
return 0;
}
Example usage:
$ ./program arg1 arg2 arg3
Number of command-line arguments: 4
Argument 0: ./program
Argument 1: arg1
Argument 2: arg2
Argument 3: arg3
How it works:
- `argc`: The number of command-line arguments passed to the program, including the
program name itself.
- `argv`: An array of pointers to strings (`char *`) representing the command-line
arguments. `argv[0]` holds the name of the program itself, and subsequent elements
contain the actual arguments.
- Each argument is separated by a space on the command line.
PREPROCESSOR DIRECTIVE:
Example:
int main()
{
#ifdef DEBUG
printf("Debug mode enabled\n");
#else
printf("Debug mode disabled\n");
#endif
}
Output:
Debug mode disabled.
This ensures that the contents of the header file are included only once, even if the
header file is included multiple times in the program.
Preprocessor directives are processed before the actual compilation of the source code
begins. They are powerful tools for controlling the compilation process, including file
inclusion, conditional compilation, and macro definition, thus allowing for flexible
and efficient code development in C.