C programming
C programming
Introduction to Programming:
C- Programming
Programming using C
C-Compilation Model Source Code
Preprocessor
C code (without
preprocessor directives) e.g., to create assembly code from source
code
Compiler $cc –S test.c -o test.s
assembly to object code
Assembly level code $cc –c test.s –o test.o
e.g., to create object codes from source
codes & link them together to create Assembler
executable code (either test1.c or test2.c
must contain main()) Object code Object codes/libraries
$cc –c test1.c -o test1.o
e.g., to create object code from source code &
$cc –c test2.c –o test2.o
Linker link with math library to create executable
$cc test1.o test2.o –o test
code
Executable Code $cc test.c -o test -lm
2
Start
SUM:= SUM + I
Print SUM
I:= I + 1
No Yes
IS I=N+1?
Stop
3
Problem Solving (cont’d…) Start
I:= N
No
Is N=0?
Is I divides
Yes
Yes
N and M?
No
Print I Print M
I:= I - 1
Stop
Naïve Approach
Stop Euclid Method
4
Start
Flowchart for finding real roots
of a quadratic equation
(ax2+bx+c=0)
Input a,b,c
3x2-5x+2=0, a=3,b=-5,c=2
No
Is T≥0?
Yes
X1:=(-b+√T)/2a
X2:= (-b-√T)/2a Print “Imaginary roots”
Stop 5
Programming using C
Structure of a typical C Program
Preprocessor Directives (#include, #define, #ifdef #pragma etc)
Type definitions (typedef <newtype> definition)
Function Prototypes (<type> myfunct (argument types))
◼ Declarations of function’s return type and arguments types
Declaration of Global variables (exist throughout the entire execution and are accessible
from anywhere)
Functions definitions
◼ All programs must contain a single main() function. All functions including main()
have the following format.
<type> Function_name (parameters) {
declaration of local variables; (exist during the execution of the function, and are
accessible within the function only)
C statements;
}
6
Programming using C (Cont’d…)
Structure of a typical C Program
#include <stdio.h>
#define TIMES 10 /*upper bound */
double myfunction (float ); /* Function prototype declaration*/
main()
{
double x;
double pi=3.14;
printf(“Multiplying by 10 \n”);
x = myfunction(pi); /* function call */
printf(“%d * %f = %f \n”, TIMES, pi,x);
}
double myfunction (float m) { /* function definition */
double count=0.0;
count = TIMES * m;
return count;
}
7
Programming using C
Elements of C Programming language
Alphabets (character sets)
Words/identifiers (entity, reserved words)
Constants (symbolic/macro, literals, \ddd, \xx, \n, const etc)
Variables: Local, global, extern, static, register, auto etc
Functions Prototype, declaration, calls
Data types (standard, user defined, sizeof etc)
Type conversion (implicit, explicit (type casting))
Expression
Operators and precedence
8
Data types in C
C provides a way to store and manipulate different types of data in a program.
Data types can be broadly categorized into three groups:
1) Basic data types: These are the fundamental data types in C and include:
• int, short int, long, long long - for integer values of different lengths (unsigned for
+ve)
• char - for single characters (one byte) (unsigned for +ve)
• float - for floating-point values with single precision (IEEE754): SEM notation
• double - for floating-point values with double precision
• void - for representing the absence of type (one byte)
2) Enumerated types: These are user-defined data types that allow you to create a set of
named integer constants using ’enum’ keyword.
Example:
enum day_of_week {monday, tuesday, wednesday, thursday, friday, saturday, sunday};
9
Data types in C (Cont’d…)
3) Derived data types: These are data types that are derived from the basic
data types and include:
• Arrays - for storing a fixed number of values of the same data type
• Pointers - for storing memory addresses of variables
• Structures - for grouping related data of different data types under a single name
• Unions - for storing different data types in the same memory location
C also provides the ability to define custom data types using typedef. This allows to
define a new name for an existing data type, which can make source code easier to
read and maintain.
e.g.,
typedef unsigned int counter;(declare variable as counter i;)
typedef enum day_of_week day;
Size of a data type (in terms of number of bytes) is given by sizeof() function
10
Identifiers in C
Identifier is a name used to represent a variable, function, or other programming
elements. Rules and conventions for identifiers in C:
1. Valid characters: Identifiers can consist of letters (both uppercase and
lowercase), digits (0-9), and underscores (_). The first character of an
identifier must be a letter or an underscore.
2. Length: Identifiers can be of any length (standard specific), but typically, they
are kept reasonably short and descriptive to improve code readability.
3. Case sensitivity: C is a case-sensitive language, so "myVar" and "myvar" are
considered different identifiers.
4. Reserved words: C has reserved words or keywords, which are predefined and
used as part of the language syntax. Identifiers cannot have the same names
as reserved words, such as "if", "else", "while", "int", “do”, “case” etc.
11
Identifiers in C (Cont’d…)
5. Naming conventions: It is common practice to follow certain naming
conventions. For example, variable names are usually in lowercase, with words
separated by underscores (e.g., my_variable), while function names are
typically in lowercase with words concatenated (e.g., myfunction).
6. Meaningful names: It is recommended to use meaningful and descriptive
names for identifiers to make the code more understandable and maintainable.
Some examples of invalid identifiers:
int 123age;
float my-salary;
char first Name;
double if;
int sample@func (float);
12
Constants in C
There are several types of constants in C:
1. Integer Constants: Constants that represent integer values. They can be written in decimal,
octal, or hexadecimal format. E.g., int x=12, y=012, z=0xA;
2. Floating-point Constants: Constants that represent real values in standard and scientific
notations. E.g., float pi=3.1415, f=2.02e7;
3. Character Constants: Constants that represent single characters. They are enclosed in single
quotes. E.g., char c=‘A’, s=‘$’;
4. String Constants: Constants that represent a sequence of characters, such as a string of text.
They are enclosed in double quotes. E.g., char msg[]=“Hello World!”;
5. Enumeration Constants: These are user-defined constants that represent a set of named
integer values. E.g.,
enum color {RED, GREEN, BLUE};
enum color new_color=GREEN;
6. Macro Constants: Constants that are defined using the #define preprocessor directive. E.g.,
#define PI 3.14159
13
#define MAX 100
Constants in C (cont’d…)
6. In C, the const keyword is used to declare variables whose values cannot be changed after
initialization.
It tells the compiler that the variable is read-only, helping prevent unintended modifications and
improving code safety and clarity.
Basic Usage:
Example 1:
const int x=10;/*OR const int x; here x is initialized to 0 by default */
x = 20; // Error: assignment of read-only variable
Example 2:
const char msg[] = "Hello!";
msg[0] = 'h'; // Error: Cannot modify string literal
Example 3:
void printArray(const int *arr, int size) {
for (int i = 0; i < size; ++i)
printf("%d ", arr[i]);
// arr[0] = 99; // Error: Cannot modify a const parameter
}
14
Variables in C
Variables are classified into different categories based on their scope and storage
duration.
1. Global Variables: variables declared outside of any function, have a global scope and have
static storage duration (they exist for the entire duration of the program, initialized automatically
with 0 (for int), 0.0 (for float/double), ‘\0’ (for char) etc.)
2. Local Variables: variables declared inside a function or a block of code, have a local scope and
have automatic storage duration (created when the function or block of code is entered, and
destroyed when it is exited, uninitialized, and hence they may store random values)
3. Function Parameters: variables that are passed to a function as arguments, have a local
scope and exist only within the function. They have automatic storage duration.
4. Static Variables: variables that are declared with the static keyword. They have a local scope
and exist for the entire duration of the program like global variables (across multiple invocations
of the functions). Note: making a global variable static means – it cannot be used by other files
5. Register Variables: variables that are declared with the register keyword, stored in the CPU
registers rather than in memory to make them faster to access. (preferable within a function for
scalar type int) 15
Programming using C
#include <stdio.h>
#include <math.h>
/*Program to print the real roots of a quadratic equation*/
main() {
int a,b,c;
double x1,x2,d;
printf(“Give values of a (not = 0) b and c \n”);
scanf(“%d %d %d”,&a,&b,&c);
d=b*b – 4*a*c;
if (d>=0)
{
x1=(-b+sqrt(d))/(2*a);
x2=(-b-sqrt(d))/(2*a);
printf (“Real roots are x1=%3.2f, x2=%3.2f\n”,x1,x2);
}
else
printf(“Roots are Imaginary\n”);
}
16
Programming using C (cont’d…)
#include <stdio.h>
#include <math.h>
/*Program to compute the cos(x) series upto nth term*/
main() {
int i,n;
float x;
double term, sum;
printf(“Give values of n and x to compute cos(x)\n”);
scanf(“%d %f”,&n,&x);
sum=1.0;
i=1;
term=1.0;
while(i<=n-1) {
i++; term= - term*x*x/((2*i-3)*(2*i-2));
sum=sum+term;
}
printf(“Cos(x)= %f\n”, sum);
printf(“Actual value of cos(x) is %f\n”, cos(x));
} 17
Programming using C (cont’d…)
#include <stdio.h>
#define N 100
/*Program to compute the maximum of a number of integers */
main() {
int i,n;
int num,max;
printf(“Give values n(<=100) \n”);
scanf(“%d”,&n);
printf(“numbers are \n”);
scanf(“%d”,&num);
max=num;
for(i=2;i<=n;i++) {
scanf(“%d”,&num);
if (max<num)
max=num;
}
printf(“Maximum is %d\n”, max);
} 18
Programming using C (cont’d…)
#include <stdio.h>
#define N 100
/*Program to compute the maximum of a number of integers and to store the numbers*/
main() {
int i,n;
int num[N],max;
printf(“Give values n(<=100) \n”);
scanf(“%d”,&n);
printf(“numbers are \n”);
scanf(“%d”,&num[0]);
max=num[0];
for(i=1;i<=n-1;i++)
{
scanf(“%d”,&num[i]);
if (max<num[i])
max=num[i]; }
printf(“The Numbers are : \n”);
for(i=0;i<=n-1;i++)
printf(“%d “,num[i]);
printf(“\n Maximum is %d\n”, max);
} 19
Expressions in C
+, -, *, /, % ---→ Basic arithmetic operators
x= 73/8; /* x=9, if x is declared as int x,*/
x= 73.0/8.0 /* x= 9.125, if x is declared as float x */
x= 73%8 /* x=1, the remainder of the division, operands
cannot be float or double types */
Multiplication operators (*, /, %) have higher priority than additive
operators (+, -)
Short-hand operators: C allows for a shorthand notation that introduces
side effect.
These are Prefix or Postfix operators ++ (increment) or - - (decrement)
20
Expressions in C (Cont’d…)
Prefix ++ or -- : ++a, --a (The variable a is modified before it is used in
the evaluation)
Postfix ++ or -- : a++, a--(The variable is first used to evaluate the
expression and then modified)
a=3; b=a++ + 3; /* b= 3 + 3 =6 and a =4 as side effect */
a=3; b=++a + 3; /* b= 4 + 3 =7 and a =4 as side effect */
All operators can be combined with = as follows
◼ a+=b; /* a= a+ b*/
◼ a/=b; /* a= a/b */
21
Expressions in C (Cont’d…)
Bit-Operators:
◼ & (AND) : c=a & b
◼ | (OR) : c= a | b
◼ ^ (ExOR) : c= a ^ b
◼ ~ (1’s Complement): c= ~ a
◼ << (Shift Left) : a= a << 3
◼ >> (Shift Right) : a= a >> 3
Comparison and Logical Operators:
◼ <, >, <=, >=, ==, != (Comparison operators , returns 1 (true) or 0 (false))
◼ && and || (Logical operators (Connector): AND and OR, returns 1 or 0)
◼ && and || are used for short circuiting logical expression. It means, to know the
value of a logical expression, you need not evaluate the whole expression.
◼ E.g. (a != b) && (c > d), (a < b) || (c > d) etc.
◼ Ternary Operator: (<cond>? <exp1>:<exp2>)
e.g, max=(a>b? a: b) (means max will be assigned a if a>b, else it will be assigned b)
22
Expressions in C (Cont’d…)
23
Expressions in C (Cont’d…)
24
Statements (Instructions) in C
◼ Assignment (a = b*c + d;)
Right hand side expression is evaluated and the value is assigned
to the variable in the left hand side.
The assigned value is the value of the expression (i.e.,
assignment operation)
◼ Input/output
For taking inputs from user and to return results to the user
through output device.
◼ Flow Control
if statements, for, while, do while, switch,
goto, exit, continue, break 25
Flow Control
If statement: In both cases, when <expr> is true, then statement1
1st form: is executed. If the <expr> is false, then, in the first
case statement2 is executed, and in the second case
if <expr>
the statement after the if block is executed.
statement1
Important: Any value other than 0 (may be +ve or
else –ve) is considered as True and 0 is considered as
staement2 False. As for example,
-1 → true,23→ true,1→ true,0→ false
2nd form: Example:
if <expr> if (x>y) max=x;
statement1 else max=y;
if (x>y) t=x; 26
Flow Control (cont’d…)
Switch statement: Depending on value of <expr>, statements are
switch (<expr>) executed. If <expr> has value val1, then stat1 is
{ executed, similarly for val2 and val3 stat2 and stat3
case val1:stat1; are executed respectively. If <expr> is none of values
break; of the cases, then stat4 is executed. values are to be
case val2:stat2; distinct, and ordering is NOT important. <expr> can
break; be int, char or enum types.
case val3:stat3;
break; Example:
27
Flow Control (cont’d…)
for statement: To implement a loop, it does the initialization
for (init; cond; incr) first, then checks the <cond>. If <cond> is
{ Statements
true, execute the body of the loop and at
}
end does the increment.
- All parts are optional
- Use break to interrupt the loop From next time onwards, it checks <cond>
and use continue to skip the rest and executes the body of the loop, does the
of the body of the loop and to re-
evaluate the cond. increment, and continue like that until the
<cond> becomes false.
Example:
for (x=0; x<100; x=x+1) {
if ((x % 5) == 0) printf(“%d is multiples of 5\n”,x) ;
}
[x=0;
for( ; x<100; ) {
if ((x % 5) == 0) printf(“ %d is multiples of 5\n”,x) ;
x=x+1; }] 28
Flow Control (cont’d…)
While statement:
while (cond) { While statement is used to continually execute a
Statements block of statements while a <cond> remains true.
} Do-while is like the while statement except that the
loop is always executed once and the <cond> is
do { checked at the end of each iteration. break and
Statements continue are used like their uses in for loop.
} while (cond);
Example:
x=0;
while (x<100) {
if ((x % 5) == 0) printf(“ %d is multiples of 5\n”, x) ;
x=x+1;
} 29
Flow Control (cont’d…)
Write c code for the flowchart for Code for both +ve and –ve integers,
printing the binary equivalent of a where –ve integers are stored in 2’s
Start +ve integer (in reverse order). complement representation:
Assume N>=0 #include <stdio.h>
(here use an array to print bits in int main() {
Input N correct order)
#include <stdio.h> unsigned int mask;
int main() { int num;
M:= N
int b[32], i=0; scanf(“%d”, &num);
int num, m;
mask= 1 << sizeof(int)*8 -1;
No scanf(“%d”, &num);
Is M>0? m=num; while (mask!=0) {
while (m>0) { if ((num & mask) == 1)
Yes b[i]=m%2; printf(“1”);
Stop m=m/2; else
R:=M%2
M:=M/2 i++;
} printf(“0”);
printf(“Binary form of mask= mask >>1 ;
Print R
%d\n”,num); }
for( i=i-1; i>=0; i--)
return 0;
printf(“%d ”,b[i]);
return 0; } } 30
Flow Control (cont’d…)
Exit statement: exit()
To terminate execution of the program passing an
integer error code.
Return values:
0 -> no error
1 -> not found
99 -> crash
31
Statements: Input/Output
Standard Input/Output:
◼ int getchar (void) : To read one character at a time
from standard input (keyboard)
◼ int putchar (int) : To write one character at a
time to standard output (Monitor)
◼ Needs #include <stdio.h>
◼ EOF (End of File) means no more characters in the input
stream (use <ctrl>+d to enter EOF character from keyboard)
32
Statements: Input/Output
#include <stdio.h>
/* Program to count no of lines in input */
/* Using while loops */
int main() {
int c, nline=0;
while ((c = getchar())!=EOF)
if (c==‘\n’)
nline++;
printf(“no of lines in text is %d\n”,nline);
return 0;
}
33
Statements: Input/Output
#include <stdio.h>
/* Using do while loops */
main() {
int c, nline=0;
do
{
c=getchar();
if (c=='\n')
nline++;
} while (c!=EOF);
printf("no of lines = %d\n", nline);
}
34
Statements: Input/Output
#include <stdio.h>
/* Program to count no of lines in input */
/* Using for loops */
main() {
int c, nline=0;
c=getchar();
for ( ; c !=EOF; )
{
if (c==‘\n’)
nline++;
c=getchar();
}
printf(“no of lines in text is %d\n”,nline);
}
35
Statements: Input/Output
Formatted Input:
◼ int scanf ( char *format, arg1, arg2 …….) : reads
characters from the standard input, interprets them according to
the specification in format, and stores the results through the
remaining arguments (list of pointers to variables). It returns no.
of items successfully read and assigned.
◼ int sscanf (char *string, char *format, arg1,
arg2,…..) reads characters from the given string string.
◼ Tips: Also used for converting string to other datatypes
◼ int fscanf (FILE *fp, char *format, arg1, arg2…)
reads characters from the given text file fp. 36
Statements: Formatted Input
Format string may contain
◼ Blanks or tabs which are ignored
◼ Ordinary characters (not %) which are expected to match the
next non-white space char of the input stream
◼ Conversion specifications, consisting of the character %, an
optional assignment suppression character *, an optional
number specifying a maximum field width, an optional h, l, L
indicating the width of the target and a conversion character.
◼ Conversion characters: d, i, o, u, x, c (1s), s, e,
f, g, %
37
Statements: Input/Output
Formatted Output:
◼ int printf ( char *format, arg1, arg2 …….) : prints its
arguments on the standard output, converts, formats them according to the
specification in format. Returns the no of characters printed.
◼ int sprintf (char *string, char *format, arg1, arg2,…..)
stores its formatted arguments in the given string.
Tips: Also used for converting other datatype to string
◼ Conversion characters
d,i,o,x,X,u
c,s
e,E,g,G
40
Mid-Term QP (Q.4: Draw Flowchart, Q.5: Write C Program)
4. Draw flow charts (Answer any 2). [3×2= 6]
i). Compute factorial of a positive number.
ii). Find the smallest among the three numbers.
iii). To find the eligibility for discount for a senior citizen using the following information.
Age Income Eligibility Check Result
Age >= 60 < 5,00,000 Age >= 60 and Income < 5,00,000 "Eligible for Discount"
Age < 60 ≥ 5,00,000 Age < 60 or Income ≥ 5,00,000 "Not Eligible for Discount"
41
Arrays in C
Declaration : (sizes of all dimensions are mandatory)
int A[4],B[10][20]; /*Note: int A[], int B[][5], int C[5][], int D[][] etc. are all INVALID */
Declaration with Initialization: (sizes of all dimensions, EXCEPT the 1st one are mandatory)
int A[4]={2,3,4,5}; /* or int A[]={2,3,4,5}, A is a vector of 4 elements */
int C[5]={1,2}; /*the remaining 3 elements are assigned 0 (0.0 for float, ‘\0’ for char)*/
int B[4][5]={ {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}, {1,2,3,4,5}};
Or int B[][5]={{1,2,3},{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4}};//B[4][]= … is INVALID
Or int B[][5]={1,2,3,4,5,6} /* implies 2 rows of 5 elements each*/
Reference to array elements:
A[i] -→ means (i+1)th element of an array A.
B[i][j] -→ means (i+1, j+1)th element of a 2-dimensional array B.
Note: Strings are array of characters terminated with the null character ‘\0’: (but array of characters
need not terminate with ‘\0’)
e.g. char str[6]={‘h’,’e’,’l’,’l’,’o’,’\0’};
char str[6]=“hello”;
In C, arrays are just a syntactic convenience to make programming easier. For compiler, Arrays are basically
the same as pointers (array name is a constant pointer to the beginning of the array)
42
Example of using Arrays in C
• In C programming, an array is a collection of variables of the same type stored in contiguous
memory locations. The size of the array must be known at Compile time.
• This type of data types allow to store multiple values under a single variable name, facilitating
efficient data management and manipulation.
• Following program is for finding max. and min. of a collection of n integers given as input
#include <stdio.h>
#define N 20
int main() {
int arr[N], i, max, min, n;
printf(“no. of elements?”);
scanf(“%d”, &n);
printf(“%d Elements are….”,n);
for(i=0; i<n; i++)
scanf(“%d”, &arr[i]);
max = min = arr[0];
for (i = 1; i < n; i++) {
if (arr[i] > max)
max = arr[i];
if (arr[i] < min)
min = arr[i]; }
printf("Maximum element: %d\n", max);
printf("Minimum element: %d\n", min);
return 0; } 43
Pointers in C
A variable has the following 4 attributes:
1) Name: identifies the variable
2) Address: specifies where in main memory the variable is located (& operator is used to find
address of a variable)
3) Type: specifies how to interpret the data stored in main memory and how long (in bytes) the
variable is
4) Value: Actual data stored in the memory for the variable
• Pointers are language constructs that allow programmers to directly manipulate the
address of variables.
• Improper handling of pointers can lead to bugs such as segmentation faults, memory
leaks, or accessing invalid memory locations
Pointers: (with * and & operators)
int* px; /* px is declared as a pointer to an integer */
int x; /* x is declared as an integer */
px = &x; /* px gets the address of x or px points to x */
x = *px; /* x gets the contents of the location pointed by px */
Pointers are used for creating dynamic memory (or array) using malloc() in <stdlib.h>
44
Pointers in C (cont’d…)
int num = 3;
int* num_ptr = NULL; // making num_ptr points to nowhere (means 0)
int* int
0 3
num_ptr num
NOTE:
• The size of any pointer type is the same on a given system, i.e., it does not depend on the size of
the data type it points to.
• pointer arithmetic does take the size of the pointed-to data into account.
45
Pointers in C (cont’d…)
num_ptr = #
int* int
num_ptr num
46
Pointers in C (cont’d…)
num = 5;
int* int
num_ptr num
47
Pointers in C (cont’d…)
*num_ptr = 7;
int* int
num_ptr num
48
Pointers in C (cont’d…)
int x = *num_ptr ;
int* int
int
7 7
num_ptr num
x
49
Pointers in C (cont’d…) int*
int* int
int
7 7
num_ptr num
x
50
Pointers in C (cont’d…) int*
*y_ptr = 6 ;
y_ptr
int* int
int
7 6
num_ptr num
x
51
Pointers in C (cont’d…) int*
y_ptr = &x ;
y_ptr
int* int
int
7 6
num_ptr num
x
52
Pointers in C (cont’d…) int*
int **p_ptr_ptr;
p_ptr_ptr = &num_ptr;
y_ptr
int* int
int
7 6
num_ptr num
x
p_ptr_ptr
int** 53
Pointers in C (cont’d…) int*
*(*p_ptr_ptr) = 5 ;
y_ptr
int* int
int
7 5
num_ptr num
x
p_ptr_ptr
int** 54
Pointers, arrays and strings
An array, in reality, is a pointer (a const pointer, which can be initialized, but can’t be
modified):
int a[10], y;
int* px;
px=a; /* px points to a[0] */
px++; /* px points to a[1] */
px= &a[4] /* px points to a[4] */
y= *(px+3) /* y gets value in a[7] */
Strings can be manipulated through pointers;
char* message, msg[12]=“Hello World”;
message=“This is a string”;
msg=“Tezpur University”; /* Error, here msg is an array, i.e., a const pointer can’t be changed*/
use <string.h> for string manipulation functions below:
• strlen(): Calculates the length of a string.
• strcpy(): Copies the contents of one string to another.
• strcat(): Concatenates two strings by appending the contents of one string to the end of another.
• strcmp():Compares two strings and returns an integer (e.g., -1, 0, 1) indicating their lexicographical order.
Use <ctype.h> for the following functions
• isalpha(),isdigit(),isalnum(),islower(),isupper(),toupper(), tolower()….. 55
Pointer arithmetic
The size of any pointer type is the same on a given system, i.e., it does not depend on
the size of the data type it points to.
Use the following to know the size of a pointer type
◼ printf(“void pointer size: %zu bytes\n",sizeof(void *));
◼ printf(“integer pointer size: %zu bytes\n",sizeof(int *));
Pointer arithmetic does take the size of the pointed-to data into account.
int *p, *q, arr[5]={1,2,3,4,5};
p=arr; /* OR p=&arr[0]; */
q=&arr[3];
printf(“pointer value p = %p, q = %p, and q-q = %d\n”, p, q, q-p);
p+3: means move the pointer p forward by 3 elements
q-2: means move the pointer q backward by 2 elements
p-q: means the number of elements between the two pointers p and q
p++, p-- : means post increment/decrement the pointer p by one element
++p, --p : means pre increment/decrement the pointer p by one element
56
Pointers and arrays
How to create a dynamic array, A, of size n using malloc()?
An Example:
#include <stdio.h>
#include <stdlib.h>
main() {
int n, *A, i, sum=0;
printf(“n =“);
scanf(“%d”,&n);
A= (int *) malloc(sizeof(int)*n);
printf(“Supply %d numbers:\n”,n);
for(i=0; i<n; i++)
scanf(“%d”, &A[i]); /* A+i is same as &A[i] */
for(i=0; i<n; i++)
sum= sum + *(A+i); /* *(A+i) is same as A[i] */
printf(“\n SUM =%d\n”,sum);
free(A);
}
57
Pointers and arrays (cont’d…)
How to create a 2-dimensional dynamic array, A, of size m×n using malloc()?
An Example:
#include <stdio.h>
#include <stdlib.h>
main() {
int m,n, i, j, sum=0;
int **A;
printf(“Supply m and n:“);
scanf(“%d %d”,&m, &n);
A=(int **) malloc(sizeof(int *)*m);/* A is pointing to m int ptrs*/
for(i=0; i<m; i++)
A[i]= (int *)malloc(sizeof(int)*n);/* A[i] is pointing to n ints */
for(i=0; i<m; i++)
for(j=0; j<n; j++)
sum= sum + A[i][j];
……………..
for(i=0; i<m; i++)
free(A[i]);
free(A); }
58
Standard String manipulation functions in <string.h>
#include <stdio.h>
#include <string.h>
int main() {
// Example 1: strlen() → Write your function for strlen(), string length operation
char str1[] = "Hello, World!";
int length = strlen(str1);
printf("Length of str1:%s is %d\n", str1, length);
// Example 2: strcpy() → Write your function for strcpy(), string copy operation
char str2[20];
strcpy(str2, str1);
printf("Copied string: %s\n", str2);
// Example 3: strcat() → Write your function for strcat(), string concatenation operation
char str3[30] = "Hello";
char str4[] = " World!";
strcat(str3, str4);
printf("Concatenated string: %s\n", str3);
// Example 4: strcmp() → Write your function for strcmp(), string comparison operation
char str5[] = "apple";
char str6[] = "banana";
int result = strcmp(str5, str6);
if (result < 0) {
printf("%s comes before %s in lexicographical order\n", str5, str6);
} else if (result > 0) {
printf("%s comes after %s in lexicographical order\n", str5, str6);
} else {
printf("%s and %s are equal\n", str5, str6);
}
return 0;
} 59
String manipulation functions in string.h (user defined)
size_t my_strlen(const char *s) {
size_t i=0;
while (s[i]!=‘\0’)
i++;
return i; /* size_t is a data type for unsigned int, defined as
typedef unsigned int size_t; */
}
char *my_strcpy(char *dest, const char *src) {
int i=0;
while(src[i]!=‘\0’) {
dest[i]=src[i];
i++;
}
dest[i]=‘\0’;
return dest;
}
char *my_strcat(char *dest, const char *src) {
int i=0, j=0;
while (dest[i]!=‘\0’)
i++;
while (src[j]!=‘\0’)
dest[i++]=src[j++];
dest[i]=‘\0’;
return dest;
} 60
String manipulation functions in string.h(user defined)(cont’d…)
int my_strcmp(const char *s1, const char *s2) {
int i=0;
while (s1[i] && (s1[i] == s2[i]))
i++;
return (unsigned char)(s1[i]) - (unsigned char)(s2[i]);
}
char *my_strrev(char *dest, const char *src) {
int len=0, i;
while(src[len]!=‘\0’) len++;
for (i = 0; src[i]!=‘\0’; i++) {
dest[i] = src[len - i - 1];
}
dest[i] = '\0';
return dest;
}
Standard input functions for reading strings from keyboard or input files (stdin means keyboard):
char buffer[30]; /* declare an array of character to store the string */
fgets(buffer, sizeof(buffer), stdin); /* Read an entire line including spaces, also stores \n if sufficient space is
available. Safest one, read one line */
gets(buffer); /* Read an entire line including spaces, but does not store \n. It does not perform bounds checking, Not
safe from security perspective */
scanf(“%s”, buffer); /* Reads until spaces, it does not perform bounds checking, Not safe from security perspective,
better use “%29s” */ 61
Character manipulation functions in <ctype.h> (user defined)
isalpha(), isdigit(), isalnum(), islower(), isupper(), toupper(), tolower()…. are standard
functions in ctype.h
/* returns 1 (true) or 0 (false) based on whether the given character c is an alphabet (A-Z
or a-z) or not */
int my_isalpha(int c) {
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z’));
}
/* returns 1 (true) or 0 (false) based on char c is a decimal digit (0-9) or not */
int my_isdigit(int c) {
return (c >= '0' && c <= '9’); }
/* returns 1 (true) or 0 (false) based on char c is alphanumeric (A-Z, a-z, 0-9) or not*/
int my_isalnum(int c) {
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= ‘z’) || (c >= '0' && c <= '9')); }
int my_islower(int c) {
return (c >= 'a' && c <= 'z’); /* check whether the given char is lower case or not */
}
int my_isupper(int c) {
return (c >= 'A' && c <= 'Z’); /* check whether the given char c is upper case or not */
}
int my_toupper(int c) { /* similarly int my_tolower(int c) will return c + ('a'-'A’), if
the given char is upper*/
if (c >= 'a' && c <= 'z')
return c - ('a' - 'A');
return c;
} 62
Using pointer to define pass/call by reference parameters
#include <stdio.h>
/* Program to exchange the values of two variables */
64
Different types of pointers (using int as the basic type)
• Pointer to int: int *ptr;
You can manipulate both ptr (pointer value) and *ptr (content of memory location pointed by ptr)
• Pointer to const int: const int *ptr;
You can manipulate ptr (pointer value) but cannot manipulate *ptr (pointed content)
• Const pointer to int: int *const ptr;
You can manipulate *ptr (pointed content) but cannot manipulate ptr (pointer value)
• Const pointer to const int: const int *const ptr;
You can neither manipulate *ptr nor ptr
• Array of pointers: int *ptrs[5];
• Pointer to a function: int (*func_ptr)(int, int);
• Pointer to an array: int (*ptr)[5];
• Function returning a pointer value: int *func(int)
Note: Two operators/functions which return addresses are --- & and
malloc()/calloc() [calloc() also initializes the allocated memory with 0 or null value].
65
Example 1: using an array of pointers to integers
#include <stdio.h>
Int main() {
int num1 = 10;
int num2 = 20;
int num3 = 30;
int *a[] = {&num1, &num2, &num3}; /* Array of pointers */
printf(“%d %d %d\n”, *a[0], *a[1], *a[2]);
return 0;}
70
Example 7: Consider the following c function defn.
/* From GATE 2024 (CS) */
#include <stdio.h>
int f(int x, int y) {
for (int i=0; i<y; i++) {
x=x+x+y;
}
return x;
}
Which of the following statements is/are TRUE about the above function?
A) If the inputs are x=20, y=10, then return value is > 220 (FALSE)
B) If the inputs are x=20, y=20, then return value is > 220 (TRUE)
C) If the inputs are x=10, y=10, then return value is < 210 (FALSE)
D) If the inputs are x=10, y=20, then return value is > 220 (TRUE)
71
Example 8: Consider the following c function defn.
/* From GATE 2023 (CS) */
The integer value printed by the ANSI-C program given below is 7=(x=2 + y=5)
#include<stdio.h>
int funcp(){
static int x = 1;
x++;
return x;
}
int main(){
int x,y;
x = funcp();
y = funcp()+x;
printf("%d\n", (x+y));
return 0;
}
72
Example 9: Consider the following c program
/* From GATE 2023 (CS) */ int f3()
int main() {
{ return(5);
f1(); f2(2); f3(); }
return(0); Which one of the following options represents the
} activation tree corresponding to the main function?
int f1() Ans: (A)
{
return(1);
}
int f2(int X)
{
f3();
if (X==1)
return f1();
else
return (X*f2(X-1));
} 73
Example 10: Consider the following c function defn.
/* From GATE 2024 (CS) */
#include <stdio.h>
int main(){
int a = 6;
int b = 0;
while(a < 10) {
a = a/12 + 1;
a += b;}
printf(”%d”, a);
return 0;}
Which of the following is CORRECT?
87
Using Structures
Pointer to a structure: take a structure to represent a complex number as follows.
e.g., struct complex {
float real, img;};
struct complex *p, *q, x,y={6.5, 9.35};
/*p and q are ptrs to structure and x and y are vars of type struct */
x.real=6.7; /* real part of x is 6.7 */
x.img=5.2; /* imaginary part of x is 5.2i */
p=&x; /* p points to the locations where x is stored */
p->real= p->real – 2.0; /* or (*p).real = (*p).real – 2.0 */
p->img = 0.0; /* or (*p).img = 0.0 */
/* Dynamic memory allocation is done through malloc() */
q= (struct complex *) malloc (sizeof(struct complex));
q->real=4.0; q->img=3.2;
/* malloc() and free() are library functions for allocation and
deallocation and available in header file <stdlib.h> */
88
Using Structures (cont’d…)
Pointer field in a structure: take a structure to represent a link list of complex numbers as
follows.
e.g., struct complex {
float real, img;
struct complex *link;
};
struct complex *p, *q, x,y;
/* p and q are pointers to structure and x and y are variables of
type structure */
x.real=6.7; /* real part of x is 6.7 */
x.img=5.2; /* imaginary part of x is 5.2i */
p=&x; /* p points to the locations where x is stored */
p->real= p->real – 2.0; /* or (*p).real = (*p).real – 2.0 */
p->img = 0.0; /* or (*p).img = 0.0 */
/* Dynamic memory allocation is done through malloc() */
p->link= (struct complex *) malloc (sizeof(struct complex));
(p->link)->real=4.0; (p->link)->img=3.2;
(p->link)->link = NULL
89
Linked List of numbers
Use a structure to represent a link list of 10 integer numbers as follows.
#include <stdio.h>
#include <stdlib.h>
struct node { int info;
struct node *link;};
int main() {
struct node *head=NULL, *p, *q, *t;
int i, x;
for (i=0; i<=9;i++){
scanf(“%d”, &x);
q=(int *) malloc(sizeof(int));
q->info=x;
q->link=NULL;
if (head==NULL) head=q;
else { t=head;
while (t->link!=NULL) t=t->link;
t->link=q; }
p=head;
while (p!=NULL){
printf(“%d “, p->info);
p=p->link; }
free(q);
return 0; } 90
Sorting a number of integers in ascending order
Here a dynamic array of size n (variable) is used. Dynamic Memory allocation & deallocation
#include <stdio.h>
#include <stdlib.h>
main() {
int *A, n, i, x, pass;
printf(“ Give the no of integers to sort:”);
scanf(“%d”,&n);
A=(int *)malloc(sizeof(int)*n);
printf(“Numbers are ..\n”);
for(i=0;i<=n-1;i++)
{
scanf(“%d “, &x); *(A+i)=x; /* or A[i]=x; */
}
for(pass=1;pass<=n-1;pass++)
{
for(i=0;i<=n-(pass+1);i++)
if (A[i]>A[i+1])
exch(&A[i],&A[i+1]); /* exch() function is defined and used as earlier */
}
printf(“Printing the Sorted list ..\n”);
for(i=0;i<=n-1;i++)
printf(“%d\n”,A[i]);
free(A); /* Making the memory free for other use */
}
91
Function Pointers in C
92
Function Pointers in C
Just as a variable can be declared to be a pointer to a data type (e.g., an int, a float, a
char etc.) a variable can also declared to be a pointer to a function
For example, the following declares a variable v whose type is a pointer to a function that
takes an int as a parameter and returns an int as a result:
int (*v)(int);
That is, v is not itself a function, but rather is a variable that can point to a function.
Since v does not yet actually point to anything, it needs to be assigned a value (i.e. the
address of a function).
Suppose you have already defined the following function f, as follows.
int f(int x) { return x+1; }
To make v point to the function f, you simply need to assign v as follows:
v = f; /* optionally, v=&f ; */
93
Function Pointers in C (Cont’d…)
To call the function that v points to (in this case f), you could write, for example,
(*v)(6); /* Optionally, you can call v(6) */
That is, it would look like an ordinary function call, except that you would need to
dereference v using * and wrap parentheses around the *v.
Putting it all together, here is a simple program:
#include <stdio.h>
int (*v)(int); /* function pointer to a function which returns an int
and takes an int argument */
int f(int x) { return x+1;}
main() {
v = f; /* Optionally, you can use v = &f */
printf("%d\n", (*v)(3)); /* Optionally, you can call v(3) */
}
94
Example of using Function Pointers in C
#include<stdio.h>
int add(int, int); /*function to perform addition of two integers */
int sub(int, int); /*function to perform subtraction of two integers */
void operate(int (*op)(int, int),int, int); /* using function pointer as argument*/
int main()
{ int a=10, b=5;
operate(add,a,b); /* Only Function Name without parameter is used as a
value to be passed for a function pointer */
operate(sub,a,b);
return 0;}
void operate(int(*op)(int, int), int x, int y) {
int c;
c=(*op)(x,y);
printf("Value of the function is %d\n",c);
}
int add(int x, int y) { return (x+y); }
int sub(int x, int y) { return (x-y); }
95
Using File Input/Output in C (use stdlib.h)
• In order to read information from a file, or write information to a file
• File is stored in secondary memory like disk
The basic steps for using a File in C are always the same:
• Create a variable of type "FILE*"
• Open the file using the "fopen" function and assign the "file" to the variable
• Check to make sure the file was successfully opened by checking to see if the
variable == NULL. If it does, an error has occurred.
• Use the fprintf(fp,….) or fscanf(fp,….) functions to write/read values from
the file Usually these function calls are placed in a loop.
• Use fputs or fgets functions to write/read one line at a time
• Finally use fclose() to close the file (otherwise file contents will be lost)
96
Using File Input/Output in C (use stdlib.h)
FILE *fp1=fopen(“samplew.txt”, “w”);
FILE *fp2=fopen(“sampler.txt”, “r”);
Fp1, fp2 → file pointers to samplew.txt & sampler.txt respectively
97
Program using Input/Output files in C
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp1, *fp2;
int x;
if((fp1=fopen(“input.txt”, “r”))==NULL)
{ printf(“Input File does not exist\n”);
return (0);
}
FILE *fp2=fopen(“output.txt”, “w”);
while (fscanf(fp1, “%d”, &x)!=EOF)
fprintf(fp2, “%d”, x*x);
fclose(fp1);
fclose(fp2);
return(1);
}
98
Using command line arguments in C
The main function should be defined as follows:
int main(int argc, char *argv[]) {
….
return 1;
}
argc → no. of command line arguments including the executable file name .
argv[0], argv[1], ……. argv[argc - 1] → strings representing the arguments
As for example, if we use the following to run a program –
$./a.out 7 98 45 3 2 5 7 22
Here, argc is 9
argv[0] is “./a.out”
argv[1] is “7”, argv[1] is “98” ....
And so on……
99
Example using input/output files
#include<stdio.h>
#include<stdlib.h>
#define N 5
struct node {
unsigned int rollno;
char name[30];
int m1, m2, m3;}; /* Students’ Record storing RoLL No, Name, and Marks in three subjects m1, m2 & m3 */
int main() {
FILE *fp1, *fp2;
struct node student[N];
int i;
fp1=fopen("student.txt", "w"); /* Text file created */
fp2=fopen("student.bin", "wb"); /* binary file created */
printf(“Enter student %d records – one by one\n”, N);
printf(“RollNo Name M1 M2 M3\n”);
for(i=0;i<N;i++) {
scanf(“%d %s %d %d %d”,&student[i].rollno,student[i].name, &student[i].m1, &student[i].m2,
&student[i].m3);
fprintf(fp1,”%d %s %d %d %d\n”,student[i].rollno,student[i].name, student[i].m1, student[i].m2,
student[i].m3);
fwrite(&student[i], sizeof(struct node), 1, fp2); }
fclose(fp1);
fclose(fp2);
return 0; }
100
#include<stdio.h>
Example using input/output files
#include<stdlib.h> fscanf(fp1,"%d %s %d %d %d", &std[i].rollno,
#include<string.h> std[i].name, &std[i].m1, &std[i].m2, &std[i].m3);
#define N 5 printf("%d %s %d %d %d
struct node { %f\n",std[i].rollno,std[i].name, std[i].m1,
unsigned int rollno; std[i].m2, std[i].m3,
char name[30]; (std[i].m1+std[i].m2+std[i].m3)/3.0 );
int m1, m2, m3; }
}; fread(&student, sizeof(struct node), N, fp2);
struct res { printf("Result is \n");
unsigned int rollno; for(i=0;i<N;i++)
char name[30]; {
float percage; }; result[i].rollno=student[i].rollno;
int main(){ strcpy (result[i].name, student[i].name);
FILE *fp1, *fp2, *fp3, *fp4; result[i].percage=(student[i].m1+student[i].m2+stu
struct node student[N], std[N]; dent[i].m3)/3.0;
struct res result[N]; printf("%d %s %f\n", result[i].rollno,
int i; result[i].name, result[i].percage);
fp1=fopen("student.txt", "r"); }
fp2=fopen("student.bin", "rb"); fwrite(&result, sizeof(struct res), N, fp4);
fp3=fopen("result.bin", "wb"); fclose(fp1);
fclose(fp2);
printf("RollNo Name M1 M2 M3 return 0;
Avg\n"); }
for(i=0;i<N;i++) {
101
Example using input/output files with argc & argv
#include<stdio.h> fread(&student, sizeof(struct node), N, fp1);
#include<stdlib.h> printf("Result is \n");
#include<string.h> for(i=0;i<N;i++)
#define N 5 {
struct node { result[i].rollno=student[i].rollno;
unsigned int rollno; strcpy (result[i].name, student[i].name);
char name[30]; result[i].percage=(student[i].m1+student[i].m2+
int m1, m2, m3;}; student[i].m3)/3.0;
struct res { printf("%d %s %f\n", result[i].rollno,
unsigned int rollno; result[i].name, result[i].percage);
char name[30]; }
float percage;}; fwrite(&result, sizeof(struct res), N, fp2);
int main(int argc, char *argv[]){ fclose(fp1);
FILE *fp1, *fp2; fclose(fp2);
struct node student[N]; return 0;
struct res result[N]; }
int i;
if (argc<3)
{ printf(“wrong: input/output filenames
missing\”);
exit(0);
}
fp1=fopen(argv[1], "rb");
fp2=fopen(argv[2], “wb");
102
Function with variable number of arguments
#include <stdio.h> int main()
#include <stdarg.h> {
double sum(int num_args, ...){ // Call the sum function with different
double total = 0.0; numbers of arguments
int i; printf("Sum: %.2f\n", sum(3, 2.5, 3.7,
// Declare a variable to hold the 1.3));
arguments printf("Sum: %.2f\n", sum(4, 1.0, 2.0, 3.0,
va_list args; 4.0));
// Initialize the argument list return 0;
va_start(args, num_args); }
// Loop through the arguments and
calculate the sum
for (i = 0; i < num_args; i++) {
// Get the next argument from the list
double arg = va_arg(args,
double);
// Add the argument to the total
total += arg;
}
// Clean up the argument list
va_end(args);
return total;
}
103