Unit 3 Combined Notes
Unit 3 Combined Notes
Unit #: 3
Unit Name: : Text Processing and User-Defined Types
Topic: String in C
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C Arrays,
Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C contructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
String in C
A string in C is an array of characters and terminated with a special character ‘\0’ or
NULL. ASCII value of NULL character is 0. Each character occupies 1 byte of memory. There is
NO datatype available to represent a string in C.
char ch = 'x' ; // character constant in single quote. always of 1 byte
char ch[] = "x" ; // String constant. always in double quotes. Terminated with '\0'. Always
1 byte more when specified between “ and ” in initialization.
Note: When the compiler encounters a sequence of characters enclosed in the double quotes, it
appends a null character ‘\0’ at the end by default
Initialization:
If the size is not specified, the compiler counts the number of elements in the array and allocates
those many bytes to an array.
If the size is specified, it allocates those many bytes and unused memory locations are
initialized with default value '\0'. This is partial initialization.
If the string is hard coded, it is programmer’s responsibility to end the string with '\0'character.
char a[] = { 'C', ' ', 'P', 'r', 'o', 'g', 'r', 'a', 'm', 'm, 'i', 'n', 'g', '\0' };
char b[] = "C Programming" ;
C standard gives shorthand notation to write initializer’s list. b is a shorthand available only for
storing strings in C.
char a7[ ] = {'a', 't', 'm', 'a', '\0', 't', 'r', 'i', 's', 'h', 'a', '\0' };
printf("sizeof a7 is %d",sizeof(a7)); // 12 a7 will be printed only till first '\0'
Consider char str1[] = {'a', 't', 'm', 'a', 't', 'r', 'i', 's', 'h', 'a', '\0' };
One way of printing all the characters is using putchar in a loop.
int i;
for (i = 0; i<sizeof(str1); i++)
printf("%c",str1[i]); //each element of string is a character. So %c.
Also taking each character from the user using getchar() as we did in Unit_1 Last problem solution,
looks like a tedious task. So, use %s format specifier and No loops required. scanf with %s will
introduce '\0' character at the end of the string. printf with %s requires the address and will
display the characters until '\0' character is encountered.
Consider,
char str1[10] = "C class" ;
printf("%s", str1); // C class
Let us deal with how to take the input from the user for a string variable.
Coding Example_1:
char str3[100] ;
printf("Enter the string");
scanf(("%s", str3); // User entered Hello Strings and pressed enter key
printf("%s\n",str3); // Hello . Reason: scanf terminates when white space in the user input
Coding Example_2:
char str4[100] ;
char str5[100] ;
printf("Enter the string");
scanf(("%s %s", str4, str5); // User entered Hello Strings and pressed enter key
printf("%s %s",str4, str5); // Hello Strings
7 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
If you want to store the entire input from the user until user presses new line in one character
array variable, use [^\n] with %s. Till \n encountered, everything has to be stored in one variable.
Coding Example_3:
char str6[100] ;
printf("Enter the string");
scanf(("%[^\n]s", str6); // User entered Hello Strings and pressed enter key
printf("%s", str6); // Hello Strings
If you want few restricted characters only to be allowed in user input, how do you handle it?
Coding Example_4:
char str6[100] ;
printf("enter your name\n");
scanf("%[abcd]s",str6); // [ ] chracter class, starting with either a or b or c or d.
//When it encounters other characters, scanf terminates
printf("u entered %s\n",str6);
Output:
Coding Example_6:
char *p1 = "pesu";
//p1 is stored at stack. “pes” is stored at code segment of memory. It is read only.
printf("size is %d\n", sizeof(p1)); // size of pointer
// This statement assigns to p variable a pointer to the character array
printf("p1 is %s", p1) ; //pesu p1 is an address. %s prints until \0 is encountered
p++; // Pointer may be modified to point elsewhere.
printf("p1 is %s", p1) ; //esu
p1[1] = 'S' ; // No compile time Error
printf("p1 is %s", p1) ; //Behaviour is undefined if you try to modify the string contents
Coding Example_7:
char p2[] = "pesu"; // Stored in the Stack segment of memory
printf("size is %d\n", sizeof(p2)); // 5 = number of elements in array+1 for ‘\0’
printf("p2 is %s", p2) ; //pesu
p2[1] = ‘E’; //Individual characters within the array may be modified.
printf("p2 is %s", p2) ; //pEsu
p2++; // Compile time Error
// Array always refers to the same storage. So array is a Constant pointer
• strchr(a,ch) – Expects string and a character to be found in string. Returns the address of
the matched character in a given string if found. Else, NULL is returned.
Few more to think about: strncmp, strcmpi, strncat, strrev, strlwr, strupr, strrchr, strstr, strrstr, strset,
strnset
Coding Example_12:
char mystr[ ] = "pes";
printf("Length is %d\n", my_strlen(mystr));
++i;
}
return i;
}
Version 2: Run the loop till *s becomes ‘\0’ character. Increment the pointer and the counter
when *str is not NULL.
int my_strlen(char *str)
{
int i =0;
while(*str){ // str[i] != '\0' // *(str+i) != '\0' ---> all these are same
i++; str++;
}
return i;
}
Version 4: Using recursion and no change in the pointer in the function call
int my_strlen(char *str)
{ if (!(*str))
return 0;
else return 1+my_strlen(str+1);
}}
Coding Example_13:
char mystr1[] = "pes university";
char mystr2[100];
printf("%s\n",mystr1);
my_strcpy(mystr2, mystr2);
printf("%s\n",mystr2);
Version 3:
void my_strcpy(char *b, char *a)
{ while((*b = *a) != '\0')
{ b++; a++; }
}
Version 4:
void my_strcpy(char *b, char *a)
{
while(*b++ = *a++); // same as for(;*b++ = *a++;);
}
Coding Example_14:
char str1[100]; char str2[100];
printf("enter the first string\n");
scanf("%s",str1);
printf("enter the second string\n");
scanf("%s",str2);
int res = my_strcmp(str1,str2);
printf("result is %d\n",res);
if(!res)
printf("%s and %s are equal\n",str1,str2);
else if(res > 0)
printf("%s is higher than %s\n",str1,str2);
else
printf("%s is lower than %s\n",str1,str2);
{ int i;
for(i = 0; b[i]!= '\0' && a[i] != '\0' && b[i]==a[i]; i++);
return a[i]-b[i];
}
Coding Example_15:
char str1[100];
printf("enter the string\n");
scanf("%s",str1);
char ch = getchar();
char *p = my_strchr(str, ch);
printf("present in this address %d",p);
if(p)
printf("present in %d position\n", p - a);
else
printf("character not present\n");
Version 1:
char* mystrchr(char *a, char c)
{ char *p = NULL;
char *s = a;
while(*s != '\0' && p==NULL)
{ if(*s == c)
p = s;
s++;
}
return p;
}
Version 2:
char *mystrchr(char *a,char c)
{ while(*a && *a != c)
{ a++; }
if (!(*a)){ return NULL; } // Can replace if else with return !(*a)? NULL: a;
else { return a; }
}
Coding Example_16:
char str1[100]; char str2[100];
printf("enter first string\n");
scanf("%s",str1);
printf("enter second string\n");
scanf("%s",str2);
strcat(str1,str2);
printf("str1 is %s and str2 is %s\n",str1,str2);
Different versions of my_strcat() implementation are as below for the logic: my_strcat appends
the entire second string to the first
18 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
Version 1:
void my_strcat(char *a,char *b)
{ int i = 0;
while(a[i]!= '\0')
{ i++; } // while can be replaced with strlen()
int j;
for(j = 0;b[j] != '\0';j++,i++)
a[i] = b[j];
a[i] = '\0';
}
Version 2:
void my_strcat(char *a,char *b)
{ while(*a){ a++; }; // increment a till NULL.
while(*b)
{ *a = *b; a++; b++; }
// Once NULL, copy each character from b to a and increment a and b both till b
becomes ‘\0’
*a = '\0'; // assign ‘\0’ character to a’s end
}
Try to mimic the implementations of other functions like strncmp, strcmpi and strncat!!
Happy mimicking!!
Unit #: 3
Unit Name: : Text Processing and User-Defined Types
Topic: Dynamic Memory Management
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Points to think:
• In case of an array, memory is allocated before the execution time. Is there over
utilization or under utilization of memory?
• Can we take the size of the array at runtime and request to allocate memory for the
array at runtime? – This is Variable length Array(VLA).
It is not a good idea to use this as there is no functionality in VLA to
check the non availability of the space. If the size of large, results in code crash
without any intimation.
• Can we avoid this by allocating memory whenever and how much ever we require
using some of the functions?
known as Static Memory Allocation, and when the memory is allocated during run-time, it is
stored in the Dynamic Memory and it is known as Dynamic Memory Allocation.
There are different segments in the memory layout of a C Program as shown below. Let us know each
of these segments to some extent.
Text segment
It contains machine code of the compiled program. Usually, it is sharable so that only a
single copy needs to be in memory for frequently executed programs, such as text editors, the C
compiler, the shells, and so on. The text segment of an executable object file is usually read-only
segment that prevents a program from being accidentally modified.
Heap Segment
It is the segment where dynamic memory allocation usually takes place. When some more
memory need to be allocated using malloc and calloc function, heap grows upward. The Heap area is
shared by all shared libraries and dynamically loaded modules in a process.
Stack Segment
Is used to store all local variables and is used for passing arguments to the functions
along with the return address of the instruction which is to be executed after the function call is
completed.Local variables have a scope to the block where they are defined in, they are created when
control enters into the block. All recursive function calls are added to stack.
Note: The stack and heap are traditionally located at opposite ends of the process's virtual
address space
1. malloc():
Allocates requested size of bytes and returns a void pointer pointing to the first byte of the allocated
space. Prototype: void *malloc(size_t size);
The malloc() function allocates size bytes and returns a pointer to the allocated memory. The
memory is not initialized. This returns a void pointer to the allocated memory that is suitably aligned
for any kind of variable. On error, these functions return NULL. NULL may also be returned by a
successful call to malloc() with a size of zero.
2. calloc():
Allocates space for elements, initialize them to zero and then return a void pointer to the memory.
prototype: void *calloc(size_t nmemb, size_t size);
The calloc() function allocates memory for an array of nmemb elements of size bytes each and returns
a pointer to the allocated memory. The calloc() function return a pointer to the allocated memory that
is suitably aligned for any kind of variable. On error, this function returns NULL. NULL may also be
returned by a successful call to calloc() with nmemb or size equal to zero.
3. realloc():
Modifies the size of previously allocated space using above functions. copies the old values into the
new memory locations. Prototype: void *realloc(void *ptr, size_t size);
This function changes the size of the memory block pointed to by ptr to size bytes. The content of the
memory block is preserved up to the lesser of the new and old sizes, even if the block is moved to a
new location. If the new size is larger than the old size, the added memory will not be initialized.
Note:
If ptr is NULL, then the call is equivalent to malloc(size), for all values of size.
If size is equal to zero, and ptr is not NULL, then the call is equivalent to free(ptr).
Unless ptr is NULL, it must have been returned by an earlier call to malloc(), calloc() or
realloc(). If the area pointed to was moved, a free(ptr) is done. The realloc() function returns a
pointer to the newly allocated memory, which is suitably aligned for any kind of variable and
may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a
pointer suitable to be passed to free() is returned. If realloc() fails the original block is left
untouched, and it is not freed or moved
4. free():
Releases the allocated memory and returns it back to heap. Must be applied with
malloc(), calloc() or realloc()
Coding Exampe_2:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *x; int n, i;
printf(“Enter the number of elements\n”);
scanf(“%d”,&n);
x = (int*)malloc(n * sizeof(int)); //memory will be allocated for 5 integer numbers
if (x == NULL) //to check if memory is allocated or not by malloc
printf("Memory not allocated.\n");
else
{
printf("Memory successfully allocated using malloc.\n");
printf("Enter the integer values:\n ");
else
{
printf("Memory successfully allocated using calloc.\n");
printf("Enter the integer values:\n ");
for (i = 0; i < n; i++) // To read inputs from user
{
scanf("%d",&x[i]);
}
printf("Output: ");// Printing
for (i = 0; i < n; i++)
printf("%d\t", *(x+i));
}
return 0;
}
Output:
Enter the number of elements 5
Memory successfully allocated using calloc. Enter the integer values:
10
40
50
20
20
Output: 10 40 50 20 20
Output 2:
initial address is 0x555c214b42a0 enter three elements
10
20
30
entered elements are 10 20 30
enter the new size
2
new address is 0x555c214b42a0
10 20
Output 3:
initial address is 0x5632e1fc52a0
enter three elements 10
20
30
entered elements are 10 20 30
enter the new size
15
new address is 0x5632e1fc5ae0
10 20 30 0 0 0 0 0 0 0 0 0 0 0 0
When new size is greater than 3, here are the pictorial representations
Output:
x = 0x561aedb012a0 x is pointing to = 10
Malloc Memory successfully freed.
How does free function knows how much memory must be returned/released?
On allocation of Memory using memory management functions, it stores somewhere in
memory the # of bytes allocated. This is known as book keeping information. We cannot access this
info. But implementation has access to it. The function free finds this size given the pointer returned
by allocation functions and de-allocates the required amount of memory.
By observing both the diagrams above, we can get to know that block allocated using functions will
be deallocated and hence the pointer becomes dangling.
Points to think:
• Can free function take one more argument along with the pointer? -- No.
• Can you use free on the same pointer twice?
Happy Coding!!
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC
Jan-May, 2022
Dept. of CSE
PES University
Common Programming Errors that might occur during Dynamic Memory Management are
discussed one by one in this lecture notes
Dangling Pointer
A pointer which points to a location that doesn’t exist is known as dangling pointer. It can
happen anywhere in the memory segment. Solution is to assign the pointer to NULL. Situations that
results in dangling pointer are as below.
• Freeing the memory results in dangling pointer
• Using new pointer variable to store return address in realloc results in dangling pointer
Note: Dereferencing the dangling pointer results in undefined behavior
printf("%p\n",p2);
*p2 = 200;
printf("%p\n", p2);
free(p2); return 0;
Coding Example_2:
#include<stdio.h>
#include<stdlib.h>
int main()
{
printf("Enter the number of integers you want to store\n");
int n; int i;
scanf("%d", &n); // user entered 4
int *p3 = (int*)malloc(n*sizeof(int));// initially all values undefinedvalues
printf("Enter %d elements\n", n);
for(i = 0;i<n; i++)
scanf("%d",&p3[i]); // (p3+i)// user entered 1 2 3 4
printf("Entered elements are\n");
for(i = 0;i<n; i++)
printf("%d\n",p3[i]); // *(p3+i)
free(p3);
return 0;
} // returns the memory allocated using malloc
Coding Example_3:
int *p4 = (int*)malloc(sizeof(int));
*p4 = 400;
printf(" %d\n", *p4);
int *p5 = p4;
free(p5); // value of the pointer has the book keeping info available
Case 2: Using new pointer variable to store return address in realloc results in dangling
pointer
Coding Example_4:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int *p1 = (int *) calloc(5, sizeof(int));
printf("before %p\n", p1);
printf("enter the elements\n");
for(int i = 0; i < 5; i++)
scanf("%d", &p1[i]);//given input 1,2,3,4,5
for(int i = 0; i < 5; i++)
printf("%d ", p1[i]);
int *p2 = (int*) realloc(p1, 1000*sizeof(int)); // p1 becomes dangling if new locations allotted
printf("after increasing size %p\n", p2); // same address as p1 if same location can be extended
//else Different address
printf("content at address pointed by p2 = %d\n", *p2);
printf("after realloc %p\n", p1);
printf("contents at address pointed by p1 = %d\n", *p1);
return 0;
}
//undefined behaviour- p1 becomes dangling pointer
NULL Pointer
It is always a good practice to assign the pointer to NULL once after the usage of free on the
pointer to avoid dangling pointers. This results in NULL Pointer. Dereferencing the NULL
pointer results in guaranteed crash
Coding Example_5:
int *p1 = (int*)malloc(sizeof(int));
*p1 = 100;
printf(" %d\n", *p1); // 100 int
*p2 = p1;
printf(" %d\n", *p2); // 100
free(p1); // p1 and p2 both becomes dangling pointer. p1 =
NULL; // safe programming
p2 = NULL;
printf(" %d\n", *p1);// Guaranteed crash
printf(" %d\n", *p2);
Coding Example_6:
#include<stdio.h>
#include<stdlib.h>
int main()
{
• Might corrupt the state of the memory manager that can cause existing blocks of
memory to get corrupted or future allocations to fail.
Coding Example_7:
int* p = (int*)malloc(sizeof(int));
*p = 10;
printf(“p = %d”, *p);
free(p);
free(p);
The above code might lead to undefined behavior. So, it is a good practice to make the pointer
NULL after the usage of free. By chance, if the pointer is freed again, it doesn’t do anything with NULL.
free(p);
p = NULL; //Function free does nothing with a NULL pointer.
free(p);
Happy Freeing!!
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Programs on Strings
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
List of Problems
1. Program to find the count of given character in a given string.
2. WAP to input a string and print the Square of all the Numbers in a String. Take care of
special cases. Input: wha4ts12ap1p and Output: 16 1 4 1
3. Write a function to find the position of First occurrence of the input character in a given
string.
4. Write a function which takes two string arguments and find the Cartesian product of
passed strings.
Input: str1: abc str2: ab and Output: aa, ab, ba, bb, ca, cb
5. WAP to find the sum of all substrings of a string representing a number.
Input : num = "1234”
Output : 1670 Sum = 1+2 + 3 + 4 + 12 + 23 + 34 + 123 + 234 + 1234 = 1670
6. Write a function to reverse a string using recursion and test the function
7. Write a program to delete the characters from string1 which are present in string2.
input: string1: whatsapp string2: wat output: hspp
A few Solutions
1. Program to find the count of given character in a given string.
Solution:
int main()
{
char str1[100]; printf("enter the string\n");
scanf("%[^\n]s",str1); // To receive multiple words and store multiple words under one name
fflush(stdin);
char ch = getchar();
int count = find_frequency(str1, ch);
printf("%c is present in %s, %d times\n",ch, str1,count);
return 0;
}
int find_frequency(char *s, char ch)
{
int count = 0;
for(; *s ; s++) // exit the loop when *s is ‘\0’
{
if (*s == ch) count++;
}
return count;
}
2. WAP to input a string and print the Square of all the Numbers in a String. Take care of
special cases. Input: wha4ts12ap1p and Output: 16 1 4 1
Solution:
#include<stdio.h>
int sqr(int r);
void extract_num_square(char *c);
int main()
{
char ch[400];
scanf("%s",ch); //wha4ts12ap1p
extract_num_square(ch);
return 0;
}
int sqr(int r)
{ return r*r; }
3. Write a function to find the position of First occurrence of the input character in a given
string.
Solution:
#include<stdio.h>
int find_first(char* ,char);
int main()
{
char text[100];
printf("enter the text\n");
scanf("%[^\n]s",text); // Till \n, receive input and store in one char array variable
fflush(stdin);
printf("enter the character which u want to find\n");
char ch = getchar();
int res = find_first(text,ch);
if(res == -1)
Version 2:
int find_first(char *a, char c)
{
int i = 0;
while((a[i]) && a[i] != ch )
{
i++;
}
return a[i]? i: -1;
}
5 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
Version 3:
int find_first(char *a,char ch)
{
int i = 0;
while(*a && *a != ch )
{
a++;i++;
}
return (*a) ? i : -1;
}
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Problem Solving – Text Processing(String Matching)
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C contructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
#include<stdio.h>
#include<string.h>
int pattern_match(char text[],int n,char pat[],int m);
int main()
{
char text[100];
char pat[100];
printf("enter the string\n");
scanf("%[^\n]s",text);
fflush(stdin);
printf("enter the pattern\n");
scanf("%[^\n]s",pat);
int n = strlen(text);
int m = strlen(pat);
int pos = pattern_match(text,n,pat,m);
if(pos == -1)
printf("pattern not found\n");
else
printf("pattern is found at %d\n",pos);
return 0;
}
//version 1: Having multiple return statement in the same function is not a good
programmer's habit.
int pattern_match(char text[],int n,char pat[],int m)
{
int i; int j;
for(i = 0;i<=n-m;i++)
{
for(j = 0; j<m && text[i+j] ==pat[j];j++);
if(j==m)
return i;
}
return -1;
}
Version 2: Modified the usage of return twice.
int pattern_match(char text[],int n,char pat[],int m)
{
int i; int j;
int res = -1; // added inthis version
for(i = 0;res == -1 && i<=n-m;i++)
{
for(j = 0; j<m && text[i+j] ==pat[j];j++);
if(j==m)
res = i; // modified in this version of code
}
return res; //modified.
}
If res is initialized to -1 and res == -1 in the outer for loop, what happens? Are these two
statements required? If yes, Why? Think!
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Structures in C
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
Structure is a user-defined data type in C language which allows us to combine data of
different types together. It helps to construct a complex data type which is more meaningful. It is
often convenient to have a single name with which to refer to a collection of related items of
different types. Structures provide a way of storing many different values in variables of
potentially different types under the same name. Structures are generally useful whenever a lot of
data needs to be grouped together. For instance, they can be used to hold records from a database or
to store information about contacts in an address book.
Why Structures?
Need of Structure is discussed through below mentioned programs. Let us try to interactively
store the Roll_number, Total_marks and Name of 20 students.
char names[20][15];
int marks[20]; int roll_num[20];
for(int i=0;i<20;i++)
{
printf("Enter Roll_number, marks and name\n"); scanf("%d",&roll_num[i]);
scanf("%d",&marks[i]);
scanf("%[^\n]s",names[i]);
}
Display the entries and check whether this code works. By using separate arrays for each of the
details of students, nowhere we saying all these three are related. It means, no where we specifying
that it is the same set of 20 students whose details are taken. To make sure that we have the relation
between the data items, we need Structures.
Introduction to Structures
A structure creates a data type that can be used to group items of possibly different types into
a single type. Grouping of attributes into a single entity is known as Structure. Creating a new type
decides the binary layout of the type. Order of fields and the total size of a variable of that type is
decided when the new type is created.
Characteristics/properties:
• A user defined data type/non-primary/secondary
• Contains one or more components – Generally known as data members. These are
named ones.
• Collection of homogeneous or heterogeneous data members
• Size of a structure depends on implementation. Memory allocation would be at least
equal to the sum of the sizes of all the data members in a structure. Offset is decided at
compile time.
• The members of a structure do not occupy space in memory until they are associated
with structure variable.
• Compatible structures may be assigned to each other.
Any member of a structure can be accessed using the structure variable as:
structure_variable_name.member_name
Suppose, s1 is the structure variable name and we want to access roll_no member of s1. Then, it
can be accessed as: s1.roll_no
Any member of a structure can be accessed using the pointer to a structure as:
pointer_variable->member_name
Suppose, s2 is the pointer to structure variable and we want to access roll_no member of s2. Then,
it can be accessed as: s2->roll_no
Given the above user defined type, look at below client codes
Version 1:
struct student s1; // Declaration
printf("%s\n",s1.name);
printf("%d\n",s1.roll_no);
printf("%d\n",s1.marks);
// some undefined value gets printed.
Version 2:
struct student s2 = {44, "abc", 100}; // Initialization
printf("%d %d %s", s2.marks, s2.roll_no, s2.name); // 100 44 abc
Version 3:
struct student s3 = {44, "abc"}; // Partial Initialization
// Explicitly few members are initialized. others are initialized to default value
printf("%d %d %s", s3.marks, s3.roll_no, s3.name); // 0 44 abc
What is the minimum number of bytes allocated for the structure variable in each of these cases?
– Sum of the sizes of all the data members. Size of data members is implementation specific.
What is the maximum number of bytes allocated for the structure variable in each of these
cases? Implementation Specific.
Coding Example_2: Below programs are run on Windows7 machine and 32 bit GCC
compiler
struct test
{ int i; char j; };
struct test1
{ char j; int i; };
struct test2
{ char k; char j; int i; };
struct test3
{ int i; char k; int j; };
int main()
{
printf("size of the structure is %lu\n",sizeof(struct test)); //8bytes 4+4
struct test t;
printf("size of the structure is %lu\n",sizeof(t)); // 8bytes 4+4
printf("size of the structure is %lu\n",sizeof(struct test1)); //8bytes 4+4
printf("size of the structure is %lu\n",sizeof(struct test2)); //8bytes 4+4
printf("size of the structure is %lu\n",sizeof(struct test3)); //12bytes 4+4+4
return 0;
}
Comparison of Structures
Coding Example_3:
struct testing
{
int a; float b; char c;
};
int main()
{
struct testing s1 = {44, 4.4, 'A'};
struct testing s2 = {44, 4.4, ‘A’};
//printf(“%d”, s1== s2); // Compiletime Error.
// == operator cannot be applied on structures for comparing
// Think about s1- s2
// Write a function to check for equality of every member of the structure
printf(“%d”,is_equal(s1,s2)); // 1 // all fields are equal
struct testing s3 = {33, 3.3, ‘A’};
printf(“%d”,is_equal(s1,s3)); // 0 //first condition itself fails
return 0;
}
int is_equal(struct testing s1, struct testing s2)
{ return (s1.a == s2.a && s1.b == s2.b && s1.c == s2.c); }
Coding Example_4:
struct testing
{ int a;
float b;
char c;
};
int main()
{ struct testing s1 = {44,4.4, 'A'};
struct testing s2 = s1;
s1.a = 55;
printf("%d\n",s1.a);
printf("%d\n",s2.a);
return 0;
}
Parameter passing is always by value in C. So, copy of the argument is passed to the
parameter p1. Whatever is modified, it is made to parameter p1.
void read(struct player p1)
{
scanf("%d ", &p1.id); // user enters 20
scanf("%[^\n]s", p1.name);
}
void disp(struct player p1)
{
printf("%d\n",p1.id); // undefined values get printed
printf("%s",p1.name);
}
int main()
{ struct player p;
printf("Enter id and name\n");
read(&p); disp(p); // passing &p to read()
/ / Think, can we also pass &p to disp(). Is there any harm?
return 0;
}
Version 3:
Assume the player structure contains many data members. In this case, can we just use
structure variable to disp function? If we do so, this is considered as a bad practice. As
every member of argument is copied to every member of parameter, it requires more
space and more time to copy.
Also, when we are very sure that we do not want to make any changes to the argument,
parameter can be a pointer to constant structure
{ strcpy(p.name,"Sourav"); return p; }
Usage of typedef
• typedef is a keyword which is used to give a type, a new name. By convention, uppercase
letters are used for these definitions to remind the programmer that the type name is
really a symbolic abbreviation, but we can use lowercase as well
• Used to assign alternative names to existing data types. It is used to provide an interface for
the client. Once a new name is created using typedef, the client may use this without
knowing the underlying type.
• typedef is limited to giving symbolic names to types only where as #define can be used to
13 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
define values.
I want to store the age of a person. Best way to define a variable is int age = 80; Alternatively,
you can also say, typedef int age; //another name for int is age.
Then age a = 80;
Can we say age age = 80? // Think about this.
If we know how to declare a variable, then prefixing the declaration with typedef makes that a
new name.
int b[10]; // b is an array variable to store 10 integers
typedef int c[10]; // c is a name for an array of 10 integers
typedef is mostly used with user defined data types when names of the data types become slightly
longer and complicated to use in programs.
Coding Example_7:
Version 1:
struct player
{ int id;
char name[20];
};
typedef struct player player_t; // player_t is a new name to struct player.
int main()
{
player_t p1; // p1 is a variable
Version 2: You can include typedef when defining a new type itself.
typedef struct player
{
14 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
int id;
char name[20];
}player_t; // player_t is a new name to struct player.
int main()
{
player_t p1; // p1 is a variable
}
Nested Structures
Structure written inside another structure is called as nesting of two structures. It can be
done in two ways.
Coding Exampe_8:
1. Separate structures: Here, we create two structures, but the dependent structure should be
used inside the main structure as a member. Consider the following example.
struct dob
{
int date;
int month;
int year;
};
struct student // template declaration which describes how student entity looks like
{
int roll_no; // these three are members of the structure
char name[20];
int marks;
struct dob d1; //using structure variable of dob inside student
};
It can be understood from example that dob (date of birth) is the structure with members as
date, month and year. Dob is then used as a member in Student structure.
struct student // template declaration which describes how student entity looks like
{
int roll_no; // these three are members of the structure
char name[20];
int marks;
struct dob //declaring structure dob inside student
{
int date;
int month;
int year;
}d1;
};
Accessing Nested Structure Members: We can access the member of the nested structure by using
Outer_Structure.Nested_Structure.member as given below:
int main()
{
struct student s1 = {24, "John", 78, {20, 03, 2000}}; //Declaration and Initialization
printf("\n Roll no. = %d, Name= %s, Marks = %d, dob = %d.%d.%d ", s1.roll_no,
s1.name,s1.marks, s1.d1.date,s1.d1.month, s1.d1.year);
return 0;
Unit #: 3
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using
C Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures CO4:
Understand and apply sorting techniques using advanced C contructs
CO5: Understand and evaluate portable programming techniques using preprocessor
directives and conditional compilation of C Programs
Team – PSWC
Jan-May, 2022
Dept. of CSE
PES University
Array of Structures
In the previous example program, we have learnt about the creation of structure types,
declaration of structure variables and how individual elements of a structure variable are referenced.
Let us now consider the below code snippet,
struct student
{
int roll_no;
char name[20];
int marks;
};
The above code defines a new data type called struct student for a single student.
We create a structure variable s1 as:
struct student s1;
If the user wishes to store details of two students then two variables should be created as
struct student s1, s2;
To store the details of 100 students, we would be required to use 100 different structure variables from
s1 to s100, which is definitely not very convenient. A better approach would be to use an Array of
structures.
struct student
{
int roll_no;
char name[100];
int marks;
}s[100]; //Declaration of structure variable as s[100]
char name[100];
int marks;
};
struct student s[100]; // not preferred
In an array of structures, all elements of the array are stored in adjacent memory locations.
Few points to know about the array inside structure as a data member
• Flexible Array Member(FAM) is a feature introduced in the C99 standard of the C programming
language. For the structures in C programming language from C99 standard onwards, we can
declare an array without a dimension and whose size is flexible in nature
• Such an array inside the structure should preferably be declared as the last member of structure and
its size is variable meaning can be changed be at runtime
• The structure must contain at least one more named member in addition to the FAM.
Initialization of Structures:
Compile-time Initialization: Here, user has to enter the details within the program .
.Case 1: struct student S1[] = { {1, "John", 60}, {2,"Jack", 40}, {3, "Jill", 77} };
// size is decided by the compiler based on how many students details are stored
Case 2: struct student S2[3] = { {1, "John", 60}, {2,"Jack", 40}, {3, "Jill", 77} };
// size is specified and initialized values are exactly matching with the size specified.
Case 3: struct student S3[3] = {1, "John", 60, 2,"Jack", 40, 3, "Jill", 77};
//initialization can also be done this way
Case 4 : struct student S4[5] = { {1, "John", 60} };
//partial initialization. Default values are stored in remaining memory locations
Runtime Initialization: Runtime is the period of time when a program is running and user is allowed to
enter the input values to the variables of the structures.
Output:
int main()
{
struct student s[100];
int i;
for( i=0;i<3;i++)
{
printf("Enter the roll_num,Name and marks\n");
scanf("%d%s%d",&s[i].roll_no,s[i].name,&s[i].marks);
//for Name variable no need to put &
}
printf("Details entered are\n");
for(i=0;i<3;i++)
{
printf("Roll_Num:%d\t",s[i].roll_no);
printf("Name:%s\t",s[i].name);
printf("Marks:%d\n",s[i].marks);
}
return 0;
}
6 Dept. of Computer Science and Engineering
2022
Problem Solving With C – UE23CS151B
Pointer is used to access the array of structure variables efficiently. Suppose we have to store
record of 5 students, then using array of structure it can be easily done as:
struct student
{ int roll_no;
char name[22];
int marks;
}ST[5];
The sizeof operator when applied on structure student will take at least 30 bytes in memory. (Please note
this is implementation specific). Suppose, base address of the array ST is 1000, then pictorial
representation of the same in memory will be:
ST
1000
Now, if the pointer ptr initialized to ST as: struct student *ptr = ST;
It means that pointer ptr is of type student structure and is holding the address pointed by the array of
structure ST (which is 1000).
Now, suppose if we perform ptr++, the ptr gets updated and now it will start pointing to next array
record starting from 1030 (ptr++ → ptr+1 → 1000 + 30 = 1030), which is the record of next
student.
Example:
struct student ST[] = {{1, "John", 60}, {2, "Jack", 40}, {3, "Jill", 77}, {4, “Sam”, 78 }, {5,
“Dean”, 80}};
//prints 1 Jack 77
How we can use this ptr to print the details of all students??
int i;
for(i = 0; i < (sizeof(ST)/sizeof(ST[0])) ; i++)
{ printf("roll_num, name and marks\n");
printf("%d\t",(ptr+i)->roll_no); // ptr[i].roll_no
printf(“%s\t”, (ptr+i)->name);
printf("%d\n",(ptr+i)->marks);
}
Coding Example_4:
Let us write the C code by creating a type called Book. The Book entity contains these data members:
id, title, author, price, year of publication. Write separate functions to read details of n books and
display it. Also include functions to do the following.
Fetch all the details of books published in the year entered by the user.
Fetch all the details of books whose author name is entered by the user. Display appropriate
message if no data found.
Separate the interface and implementation.
Let us begin with the header file. Header file contains the below code: book.h
typedef struct Book {
int id;
char title[100];
char author[100];
int price;
int year;
}book_t;
void read_details(book_t *b,int n); void
display_details(book_t *b, int n);
int fetch_books_year(book_t *b,int n, int year, book_t*);
int fetch_books_author(book_t *b,int n, char *author, book_t*);
{ int i;
}
return count;
}
int count = 0;
if (!(strcmp(b[i].author, author)))
{
count++; b_author[count-1] = b[i];
}
}
return count;
}
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Problem Solving - Structures
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
• Create a Structure called hotel with following members c_name, No_days, phone number as
nested structure with its members as mob and alternate number. Write a function to read
details from the user. Also calculate the bill (per day charges is 2000 and 8.5%tax on total
bill) and Display appropriate message.
• Write a program to create a structure called weather_Report with data members rainfall,
temperature and city name. Create a function to read and display the details of 3 cities. Also
write a function to display the city name with maximum temperature.
• Create a user defined data type for date. Write a function which will increment the date by 1
#include<stdio.h>
struct Hotel
{
char c_name[10];
int no_days;
struct phone
{
int mob;
int alt_num;
} p;
};
struct Hotel read_details(struct Hotel h1);
int main()
{
struct Hotel h,h1;
h1=read_details(h);
calculate_Bill(&h1);
return 0;
}
float amount=h1->no_days*room_charges;
float total=amount+ (amount*(8.5/100));
printf("\n\nThe amount is %f",total);
printf("\n\nVisit again,Thank you");
}
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Problem Solving – Array of structures
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Solution:
Client code provided here and I do not want to change the client at any cost. Adding the source
files and header files as per this client only.
// employee_client.c
#include<stdio.h>
#include "employee.h"
int main()
{
employee_t e[1000];
printf("Enter the number of employees for which the details has to be entered\n");
int n, id;
scanf("%d", &n);
printf("enter name, id and basic salary of %d employees\n",n);
scan_details(e,n);
printf("enter the id of the employee whose total salary you want to know\n");
scanf("%d",&id);
int tot_salary = calculate_total_salary(e,n,id);
if (!tot_salary)
printf("employee with entered id doesnt exist\n");
else
printf("total salary of employee with id %d is %d\n",id,tot_salary);
Coding Exampe_2: Create a structure to store details of Car like company name, model and year. Add
functions to read and display the details of n cars. Also include functions to display only the model and
company name of the car in the specific year or previous to it. Display appropriate message.
Solution:
#include<stdio.h>
struct car
{
char company[20];
char model[30];
int year;
};
display(arr_car,n);
display_year(arr_car,n);
return 0;
}
for(int i=0;i<n;i++)
{
printf("make:%s\t",arr_car[i].company);
printf("model:%s\t",arr_car[i].model);
printf("year:%d\t",arr_car[i].year);
printf("\n");
}
}
int yy;
printf("Enter the year to display car details\n");
scanf("%d",&yy);
for(int i=0;i<n;i++)
{
if(arr_car[i].year==yy)
{
printf("Model:%s",arr_car[i].model);
printf("Company:%s",arr_car[i].company);
}
}
}
Coding Example_3: Create a structure to store information about property like property ID, owner
name, age, property tax and Annual income. Read the details of n properties. If the annual income is less
than 5 lakhs, he/she is eligible to avail discount of 20% on property tax amount. Display the tax amount
to be paid after discount using a separate function.
Solution:
#include <stdio.h>
struct info
{
int ID;
char name[30];
int age;
int tax;
int income;
};
void read(struct info *s,int n);
void calculate_tax(struct info *s,int n);
int main()
{
int n;
struct info s[100];
printf("Enter the number of entries ");
scanf("%d",&n);
read(s,n);
calculate_tax(s,n);
return 0;
}
{
s[j].tax=0.8*s[j].tax;
}
printf("%s should pay tax of %d\n",s[j].name,s[j].tax);
}
}
Happy Coding..!!
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Array of Pointers to structures
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine.
CObj2: Map algorithmic solutions to relevant features of C programming language constructs.
CObj3: Gain knowledge about C constructs and its associated eco-system.
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviours.
CObj5: Get insights about testing and debugging C Programs.
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs.
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions.
CO3: Understand prioritized scheduling and implement the same using C structures.
CO4: Understand and apply sorting techniques using advanced C constructs.
CO5: Understand and evaluate portable programming techniques using pre-processor directives
and conditional compilation of C Programs.
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
There are times when an array of pointers to structures is useful. For example, suppose the
structure had 100 elements, that one of the elements was a person's surname and one wanted to
sort the structure in alphabetical order of surnames. The sorting technique involves a lot of
swapping and moving structure around. This is slower than moving pointers around because
pointers occupy less space. So to speed up the sorting process and efficiency factor, array of
pointers is used for the structure rather than the whole structure or record being accessed.
Array of Pointers
An array of pointers is an indexed set of variables in which the variables are pointers.
Array and pointers are closely related to each other. The name of an array is considered as a
pointer, i.e., the name of an array contains the address of an element.
Coding Example_1:
int i;
int a[10] = {12,34,66,4,16,18,19,15};
int *p[10]; // p is created with the intention of storing an array of addresses
p[0] = &a[0];
p[1] = &a[1];
p[2] = &a[2];
for(i = 0 ; i<4;i++)
{
printf("%p %p\n",p[i],&a[i]); // same address for all 3 pairs except the last
iteration as we have not assigned.
}
Coding Example_2: Program to print the elements of the array using array of pointers
#include<stdio.h>
int main()
{ int a[5] = {12,33,45,66,17}; // a is an array
printf("Using original array\n");
for(int i = 0;i<5;i++)
{ printf("%d ",a[i]); }
printf("\n");
int *p[5]; // p is an array of pointers.
for(int i = 0;i<5;i++)
{ p[i] = &a[i]; // address of a[i] stored in p[i] }
printf("Using array of pointers\n");
for(int i = 0;i<5;i++)
{
printf("%d ",*p[i]);
// content at p[i] is displayed. All elements are displayed
Pointers to Structures
A pointer is a variable which points to the address of another variable of any data type like
int, char, float etc. Similarly, a pointer to structure is a variable that can point to the address of a
structure variable .Declaring a pointer to structure is same as pointer to variable:
Syntax: struct tagname *ptr;
Unit #: 3
Unit Name: Text Processing and User-Defined Types
Topic: Sorting
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine.
CObj2: Map algorithmic solutions to relevant features of C programming language constructs.
CObj3: Gain knowledge about C constructs and its associated eco-system.
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors.
CObj5: Get insights about testing and debugging C Programs.
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs.
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions.
CO3: Understand prioritized scheduling and implement the same using C structures.
CO4: Understand and apply sorting techniques using advanced C constructs.
CO5: Understand and evaluate portable programming techniques using pre-processor directives
and conditional compilation of C Programs.
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
There are so many things in our real life that we need to search for, like a particular record
in the database, roll numbers in the merit list, a particular telephone number in a telephone
directory, a particular page in a book etc. The concept of sorting came into existence, making it
easier for everyone to arrange data in order to make the searching process easy and efficient.
Arranging the data in ascending or descending order is known as sorting.
Why Sorting?
Think about searching for something in a sorted drawer and unsorted drawer. If the large
data set is sorted based on any of the fields, then it becomes easy to search for a particular data in
that set. Sometimes in real world applications, it is necessary to arrange the data in a sorted order
to make the searching process easy and efficient.
Example: Candidates selection process for an Interview- Arranging candidates for the interview
involves sorting process (sorting based on qualification, Experience, skills or age etc.
Sorting Algorithms
Sorting algorithm specifies the way to arrange data in a particular order. Most common
orders are in numerical or lexicographical order. Depending on the data set, Sorting algorithms
exhibit different time and space complexity.
Following are samples of sorting algorithms.
• An array is traversed from left and adjacent elements are compared and the higher one is
placed at right side.
• In this way, the largest element is moved to the rightmost end at first.
• This process is continued to find the second largest number and this number is placed in the
second place from rightmost end and so on until the data is sorted.
Coding Example_1: Sorting array of integers using Bubble sort (dealt in unit 2)
#include <stdio.h>
}
// Driver program to test above functions
int main(void)
{
int arr[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
printf("Sorted array: ");
printArray(arr, n);
return 0;
}
Coding Example _2 :Using array of structures, sort the structures in the array based on the
data member – roll_no
#include<stdio.h>
typedef struct Student
{
int marks;
char name[100];
int roll_no;
float cgpa;
} STUDENT;
int main()
{
STUDENT s[1000];
int n;
printf("Enter the number of students :");
scanf("%d", &n);
input_data(s,n);
printf("Entered details before sorting: \n");
display_data(s,n);
sort(s,n);
printf("After sorting, the sorted list printed using the array of structures:\n\n");
display_data(s,n);
}
}
}
Coding Example_3: Using array of pointers to structures, sort the structures in the array
based on the data member – roll_no , without affecting the array of structures
#include<stdio.h>
typedef struct Student
{
int marks;
char name[100];
int roll_no;
float cgpa;
} STUDENT;
return 0;
}
void init_structures_pointers(struct Student **sp,struct Student *s,int n)
{
int i;
for( i = 0 ; i < n; i++)
{
sp[i] = &s[i]; //(s+i)
}
}
}
}
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC
Jan-May, 2022
Dept. of CSE
PES University
struct A *p=&a1;
printf("a1 values:%d and %d\n", p->a,*(p->b)); // 300 400
return 0;
}
struct B
{
int a;
struct A a1;
}; // structure variable a1 as a data member in B
int main()
{
printf("sizeof A %d\n",sizeof(struct A));
printf("sizeof B %d\n",sizeof(struct B)); // more than A
return 0;
}
Q3. Can we have a structure variable inside the same structure? – No.
Coding Example_3:
struct A {
int a;
struct A a1;
};
//Compile time Error: field a1 has incomplete type
// size of struct A we cannot find as the field a1 which itself is a structure of the same kind.
The solution to the previous version is to have a pointer of the same type inside the structure. The size
of a pointer to any type is fixed. Hence, the size of the structure can be computed by the compiler at
compile time.
Coding Example_ 4:
#include<stdio.h>
struct Sample
{
int a;
struct Sample *p;
};
int main()
{
printf("%d\n",sizeof(struct Sample) ); // implementation specific
struct Sample s;
s.a = 100;
s.p = &s;
printf("%d %d %d\n", s.a, s.p->a, s.p->p->a); // all 100
return 0;
}
Now let us get back to the Linked list and its implementation in detail.
Characteristics
1. A data structure that consists of zero or more nodes. Every node is composed of minimum two
fields: a data/component field and a pointer field. The pointer field of every node point to the next node
in the sequence.
2. We can access the nodes one after the other. There is no way to access the node directly as
random access is not possible in a linked list. Lists have sequential access.
3. Insertion and deletion in a list at a given position requires no shifting of elements.
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC
Jan-May, 2022
Dept. of CSE
PES University
int main()
{
NODE *head=NULL;
int choice;
int ele;
do
{
printf("1.InsertFront 2.Display 3.DeleteFront\n");
scanf("%d",&choice);
switch(choice)
{
case 1:printf("Enter an integer\n");
scanf("%d",&ele);
return newNode;
}
newNode->next=head;
head=newNode;
return head;
}
void display(NODE *head)
{
if(head==NULL)
printf("Empty List\n");
else
{
NODE *p=head;
while(p!=NULL)
{
printf("%d ",p->info);
p=p->next;
}
}
}
return head;
}
Unit : 3
Topic: Unions in C
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C Arrays,
Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C contructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
Both structure and union are the custom data types that store different types of data together as a single
entity. The members of structure and union can be entities of any type, such as other structures,
unions, or arrays. Both structures or unions can be passed by value to a function and also return to the
value by functions, the argument will need to have the same type as the function parameter.
Note: To access members, we use the ‘.’ operator or ‘->’ in a given context.
C unions are used to save memory. To better understand a union, think of it as a chunk of
memory that is used to store variables of different types. When we want to assign a new value to a
field, the existing data is replaced with new data. C unions allow data members which are mutually
exclusive to share the same memory. This is quite important when memory is valuable, such as in
embedded systems. Unions are mostly used in embedded programming where direct access to memory
is needed.
Defining a union:
You can define a union with many members, but only one member can contain a value at
any given time. The memory occupied by a union will be large enough to hold the largest
member of the union. So, the size of a union is at least the size of the biggest component. At a
given point in time, only one can exist. All the fields overlap and they have the same offset: 0.
Example:
union car
{
char name[10];
float price;
};
Now, a variable of car type can store a floating-point number or a string, i.e., the same memory
location is used to store multiple types of data. In the above example, the data type will occupy at
least 10 bytes of memory space. Because this is the maximum space that can be occupied by a
character array (Plus padding bytes, if necessary).
Coding Example_1: Displays the total memory size occupied by the union
#include <stdio.h>
union car
{
char name[10]; //assuming, 1 byte for char
float price; // assuming, 4 bytes for float
};
int main( )
{
union car c;
printf( "Memory size occupied by data in bytes : %d\n", sizeof(union car));
return 0;
}
Output: Memory size occupied by data in bytes : 12
Note: Output may vary depending on the number of bytes of padding
Coding Example_2:
#include<stdio.h>
#include<string.h>
union car
{
char name[10];
float price;
};
int main()
{
union car c;
strcpy(c.name, "Benz");
c.price=4000000.00;
printf( "car name: %s\n", c.name);
printf( "car price: %f\n", c.price);
return 0;
}
Output: When the above code is compiled and executed, the value of name gets corrupted because the
final value assigned to the variable price has occupied the memory location, and this is the reason that
the value of price member is printed well.
#include<stdio.h>
union X
{ int i;
int j;
double k;
}; // ; compulsory
struct Y
{ int i;
int j;
double k;
};
int main()
{
printf("sizeof X is %lu\n",sizeof(union X));
union X x1;
x1.i = 23;
x1.j = 23;
x1.i = 49;
printf("%d %d\n",x1.i, x1.j);
printf("sizeof Y is %lu\n",sizeof(struct Y));
return 0;
}
Output:
sizeof X is 8
49 49
sizeof Y is 16
Coding Example_6: All the fields overlap and they have the same offset: 0 in union
#include<stdio.h>
#include<stddef.h> // offsetof function is declared in stddef.h
union A
{
int x;
int y;
int z;
};
struct B
{
int x;
int y;
int z;
};
int main()
{
// assumption int occupies four bytes
printf("%lu\n",offsetof(union A,y)); // 0
printf("%lu\n",offsetof(struct B,y)); // 4
printf("%lu\n",offsetof(struct B,z)); // 8
}
Union:
1. The keyword union is used to define a union.
2. When a variable is associated with a union, memory is allocated by considering the size of the
largest data member. So, the size of a union is at least equal to the size of its largest member.
3. Memory allocated for union is shared by individual members of union
4. For unions, the address is same for all the members of a union. This indicates that every
member begins at the same offset.
5. Altering the value of any of the member will alter other member values.
6. In Unions, only one member can be accessed at a time.
1. Both are user-defined data types used to store data of same or different types as a single unit.
2. Their members can be objects of any type, including other structures, unions, or arrays. A
member can also consist of a bit of a field.
3. Both structures and unions support only assignment = and sizeof operators. The two structures
or unions in the assignment must have the same members and member types.
4. A structure or a union can be passed by value to functions and returned by value by functions.
The argument must be of the same type as the function parameter. A structure or union is
passed by value just like a scalar variable as a corresponding parameter.
5. ". "operator is used for accessing members.
We know that the fields of a union will share memory, so in the main program we ask the user which
data he/she would like to store, and depending on the user's choice, the appropriate field will be used.
By this way, we can use the memory efficiently.
t2.k=45.6;
printf("k is %f\n",t2.k);
struct test t;
t.u.j=78;
printf("j is %d\n",t.u.j);
t.u.k=45.6;
printf("k is %f\n",t.u.k);
return 0;
}
Output:
24
k is 45.599998
j is 78
k is 45.599998
{
int i;
union
{
char a[20];
float k;
};
};
int main()
{
printf("%lu",sizeof(union test)); // 20
union test t;
t.i=78; // One member at a time from union
printf("\ni is %d\n",t.i);
strcpy(t.a,"sindhu");
printf("a is %s\n",t.a);
t.k=45.5;
printf("k is %f",t.k);
return 0;
}
Output:
20
i is 78
a is sindhu
k is 45.500000
{
char name[30];
int rollno;
float percentage;
};
union details
{
struct student s1;
};
int main()
{
union details set;
printf("Enter details:");
printf("\nEnter name : ");
scanf("%s", set.s1.name);
printf("\nEnter roll no : ");
scanf("%d", &set.s1.rollno);
printf("\nEnter percentage :");
scanf("%f", &set.s1.percentage);
printf("\nThe student details are : \n");
printf("\nName : %s", set.s1.name);
printf("\nRollno : %d", set.s1.rollno);
printf("\nPercentage : %f", set.s1.percentage);
return 0;
}
Output:
Enter details:
Enter name : sindhu
Enter roll no : 123
Enter percentage :67
Unit #: 3
Topic: Bitfields
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and it's respective behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C Arrays,
Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C contructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
In programming terminology, a bit field is a data structure that allows the programmer to
allocate memory to structures and unions in bits in order to utilize computer memory in an efficient
manner. Bit fields are of great significance in C programming, because of the following reasons:
In C, we can specify the size (in bits) of the structure and union members. The idea is to use
memory efficiently when we know that the value of a field or group of fields will never exceed a limit
or is within a small range. The variables defined with a predefined width are called bit fields. A bit
field can hold more than a single bit.
Declaration:
struct
{
type [member_name] : width ;
};
type - An integer type that determines how a bit-field's value is interpreted. The type may be int,
signed int, or unsigned int.
width -The number of bits in the bit-field. The width must be less than or equal to the bit width of the
specified type.
Coding Example_1:
#include<stdio.h>
struct Status
{
unsigned int bin1:1; // 1 bit is allocated for bin1. only two digits can be stored 0 &1.
Coding Example_2: Demonstration of the maximum value that can be stored in bitfields.
Results in warning. If you need a variable to store a value from 0 to 7, then you can define a bit
field with a width of 3 bits as below. The age variable is going to use only 3 bits to store the
value. If you try to use more than 3 bits, then it will not allow you to do so.
struct {
unsigned int age : 3;
} Age;
#include <stdio.h>
#include <string.h>
struct
{
unsigned int age : 3;
} Age;
int main( )
{
Age.age = 4;
printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
return 0;
}
When the above code is compiled it will compile with a warning as shown
Coding Exampe_2.c: In function 'main':
17:14: warning: unsigned conversion from 'int' to 'unsigned char:3' changes value from '8' to '0' [-
Woverflow]
Age.age = 8;
^
Output:
Sizeof( Age ) : 4
Age.age : 4
Age.age : 7
Age.age : 0
Coding Example_3: Demonstration of assigning signed value to an Unsigned variable for which
bit fields are specified.
#include<stdio.h>
struct Status
{
unsigned int bin1:4; // 4 bits is allocated for bin1. 0 to 15, any number can be used.
unsigned int bin2:2; // 2 bits allocated for bin2. 0 to 3, any number can be used
};
int main()
{
printf("Size of structure is %lu\n",sizeof(struct Status)); // again 4 bytes
struct Status s1;
Coding Example_4: Structure having two members with signed and unsigned variable for which
bit fields are specified.
#include<stdio.h>
struct Status
{
int bin1:4; // one bit is used for representing the sign. Another 3 bits for data
unsigned int bin2:2; // 2 bits allocated for bin2. 0 to 3, any number can be used
};
int main()
{
printf("Size of structure is %lu\n",sizeof(struct Status)); // again 4 bytes
struct Status s1;
s1.bin1=-7; s1.bin2=2;
printf("%d %d",s1.bin1,s1.bin2); // -7 2
return 0;
}
Coding Example_5: Array of bit fields not allowed. Below code results in Error.
#include<stdio.h>
struct Status
{
unsigned char bin1[10]:40; // invalid type
};
int main()
{
printf("Size of structure is %lu\n",sizeof(struct Status));
return 0;
}
Coding Example_6: We cannot have pointers to bit field members as they may not start at a byte
boundary. This code results in error.
#include<stdio.h> struct
Status
{
int bin1:4; // 1 bit is used for representing the sign. Another 3 bits for data
int *p:2;
};
int main()
{
printf("Size of structure is %lu\n",sizeof(struct Status));
return 0;
}
Coding Example_7: Storage class can’t be used for bit field. This code results in error.
#include<stdio.h>
struct Status
{
static int bin1:32;// Any storage class not allowed for bit field
int p:2;
};
int main()
{
printf("Size of structure is %lu\n",sizeof(struct Status));
return 0;
}
Coding Example_ 9: Bit fields with a length of 0 must be unnamed. Unnamed bit fields cannot
be referenced or initialized. A zero-width bit field can cause the next field to be aligned on the
next container boundary where the container is the same size as the underlying type of the bit
field. Below code demonstrates the force alignment on next boundary.
#include<stdio.h>
struct Status
{
int bin1:4; // one bit is used for representing the sign. Another 3 bits for data
//int i:0;// you cannot allocate 0 bits for any member inside the structure. Error
int :0;// A special unnamed bit field of size 0 is used to force alignment on
// next boundary. observe no member variable. only size is 0 bits
unsigned int bin2:2; // 2 bits allocated for bin2. 0 to 3, any number can be used
};
int main()
{
// observe the size of the structure. Now 8 bytes
Unit #: 3
Unit Name: Text Processing and User defined Types
Topic: Priority Queue
Course objectives:
The objective(s) of this course is to make students
CObj1: Acquire knowledge on how to solve relevant and logical problems using computing
machine
CObj2: Map algorithmic solutions to relevant features of C programming language constructs
CObj3: Gain knowledge about C constructs and it's associated eco-system
CObj4: Appreciate and gain knowledge about the issues with C Standards and its respective
behaviors
CObj5: Get insights about testing and debugging C Programs
Course outcomes:
At the end of the course, the student will be able to
CO1: Understand and apply algorithmic solutions to counting problems using appropriate C
Constructs
CO2: Understand, analyse and apply text processing and string manipulation methods using C
Arrays, Pointers and functions
CO3: Understand prioritized scheduling and implement the same using C structures
CO4: Understand and apply sorting techniques using advanced C constructs
CO5: Understand and evaluate portable programming techniques using preprocessor directives and
conditional compilation of C Programs
Team – PSWC,
Jan - May, 2022
Dept. of CSE,
PES University
Introduction
Queue: A line or a sequence of people or vehicles waiting for their turn to be attended or to
proceed. In computer Science, a list of data items, commands, etc., stored so as to be retrievable
in a definite order. A Linear data structure which has 2 ends - Rear end and a Front end. Data
elements are inserted into the queue from the rear (back) end and deleted from the front end. Hence a
queue is also known as First In First Out (FIFO) data structure.
• peek() − Gets the element at the front of the queue without removing it.
• isfull() − Checks if the queue is full.
• isempty() − Checks if the queue is empty.
Types of Queue:
• Ordinary queue - insertion takes place at rear and deletion takes place at front.
• Priority queue - special type of queue in which each element is associated with a priority and
is served according to its priority. If elements with the same priority occur, they are served
according to their order in the queue
• Circular queue - Last element points to first element of queue making circular link.
• Double ended queue - insertion and removal of elements can be performed from either from
the front or rear.
Priority Queue
A data structure which is like a regular queue but where additionally each element has a
"priority" associated with it. This priority decides about the deque operation. The enqueue operation
stores the item and the priority information.
Happy Queueing!!