C Programming
-
C is a versatile, high-level programming language that finds its application in a wide array of software and application development, system programming, game development, web programming, and more. It was in 1972 when Dennis M. Ritchie, working at the Bell Telephone Laboratories, birthed this programming gem. Originally intended for programming the UNIX operating system, C has grown to become one of the most widely used and influential programming languages out there.
1. Genesis of C: C had its beginnings in the early 1970s at Bell Telephone Laboratories. Dennis Ritchie was the brain behind this creation.
2. B Language Predecessor: Before C, there was a programming language called B, which Ken Thompson developed. B was influenced by BCPL and was primarily used for the Multics operating system.
3. Birth of C: Ritchie and his team wanted to enhance the capabilities and efficiency of B. Their efforts resulted in the birth of C, originally referred to as "NB" (New B). The work on C started in 1972 and continued into 1973.
4. C for Unix: One of the primary goals of C was to provide a more efficient and versatile language for developing the Unix operating system. At the time, Unix was primarily written in assembly language, making it less portable across different computer architectures. C changed that.
5. Portability: C's design for system programming allowed Unix to be easily ported to various hardware platforms. This portability became one of the key factors in Unix's widespread adoption.
6. The C Book: In 1973, Dennis Ritchie and Brian Kernighan published "The C Programming Language," often referred to as "K&R C." This book became the definitive reference for the language and played a significant role in popularizing C among programmers and institutions.
1. Fundamental Understanding: C is often considered the "mother" of all programming languages. Learning C gives you a strong foundation in programming concepts, which can be applied to other languages.
2. Efficiency: C is known for its efficiency. It allows you to write fast and optimized code, making it suitable for system programming and applications where speed and resource usage are critical.
3. Portability: C code is highly portable across different platforms and operating systems. Programs written in C can run on various hardware and software environments with minimal modification.
4. Versatility: C is a versatile language used in a wide range of applications, from embedded systems and game development to operating systems and high-performance computing.
5. Low-Level Programming: Learning C allows you to work at a lower level of abstraction, enabling you to understand how the computer's memory and processor work. This knowledge is invaluable for system programming and debugging.
6. Problem-Solving Skills: C challenges you to manage memory, pointers, and other low-level details. This hones your problem-solving skills and teaches you to write efficient code.
7. Career Opportunities: Proficiency in C programming is highly sought after by employers, especially in industries like embedded systems, robotics, and game development.
8. Open Source and Legacy Code: Many open-source projects and legacy systems are written in C. Learning C allows you to contribute to open-source software and maintain or modernize older codebases.
9. C++ and Embedded Systems: C is a precursor to C++, and learning C makes it easier to transition to C++ for object-oriented programming. Additionally, C is commonly used in embedded systems, a growing field.
10. Security Knowledge: C requires careful memory management. Learning C can help you understand and mitigate security vulnerabilities like buffer overflows and memory leaks.
1. Choose an Operating System: You can develop C programs on various operating systems, including Windows, Linux, and macOS. Your choice depends on your preferences and the platform you intend to target.
2. Select a Text Editor or Integrated Development Environment (IDE): You have several options for writing C code. You can choose a simple text editor or a specialized C programming IDE. Some popular choices include: - Text Editors: - Notepad (Windows) - Visual Studio Code - Sublime Text - Atom - C-Specific IDEs: - Code::Blocks - Dev-C++ - CLion - Eclipse C/C++ IDE - Linux Development Tools: - On Linux, you can use text editors like Vim or Emacs along with GCC (GNU Compiler Collection) for compiling.
3. Install a C Compiler: You need a C compiler to compile and execute your C programs. The most commonly used C compiler is GCC (GNU Compiler Collection). Here's how to install GCC on different platforms: - Linux: Most Linux distributions come with GCC pre-installed. If not, you can use your package manager to install it. For example, on Ubuntu, run `sudo apt-get install build-essential`. - Windows: You can use MinGW (Minimalist GNU for Windows) to install GCC on Windows. Download the MinGW installer and follow the installation instructions. - macOS: On macOS, you can use the Xcode Command Line Tools, which include GCC. Open a terminal and run `xcode-select --install` to install these tools.
4. Write and Compile Your First C Program: Now that you have a text editor, C compiler, and development environment set up, you can write your first C program. Here's a simple "Hello, World!" example: ```c #include
int main() { printf("Hello, World!\n"); return 0; } ``` Save this code in a file with a `.c` extension, such as `hello.c`. 5. Compile and Run Your Program: - On the command line, navigate to the directory where you saved your C file. - Compile the program using the C compiler. For GCC, you can use the following command: `gcc -o hello hello.c` (This compiles `hello.c` and produces an executable named `hello`.) - Run the program by entering `./hello` (on Linux/macOS) or `hello.exe` (on Windows).
6. Debugging Tools (Optional): For debugging your C programs, consider using a debugger like GDB (GNU Debugger) or the built-in debugging tools provided by your chosen IDE. That's a basic overview of setting up a C programming development environment. As you gain more experience, you can explore additional tools and libraries to enhance your development process.
Chapter 2: Getting Started with C
#include< stdio.h > int main(){ printf("Hello, World!"); return 0; }
This program prints "Hello, World!" on the console.
#include< stdio.h> :- This line includes the stdio.h file, which contains the printf() function.
int main() { :- This line defines the main() function, which is the entry point for all C programs.
printf("Hello, World!"); :- This line prints the string "Hello, World!" to the console.
return 0; :- This line returns the value 0 to the operating system, indicating that the program terminated successfully.
}There are 6 sections in a C.
// Documentation section // Link section // Definition section // Global declaration section // Main() function // Subprograms
In C, there are different types of variables (defined with different keywords), for example:
int - stores integers (whole numbers), without decimals, such as 123 or -123.
float - stores floating point numbers, with decimals, such as 19.99 or -19.99.
char - stores single characters, such as 'a' or 'B'.
scanf():
The scanf() method, in C, reads the value from the console as per the type specified. Syntax:
"scanf(“%X”, &variableOfXType);" = where %X is the format specifier in C. It is a way to tell the compiler what type of data is in a variable and & is the address operator in C
printf():
The printf() method, in C, prints the value passed as the parameter to it, on the console screen. Syntax:
"printf(“%X”, variableOfXType);" = where %X is the format specifier in C. It is a way to tell the compiler what type of data is in a variable and & is the address operator in C
Integer:
Input: scanf("%d", &intVariable);
Output: printf("%d", intVariable);
Float:
Input: scanf("%f", &floatVariable);
Output: printf("%f", folatVariable);
Character:
Input: scanf("%c", &charVariable);
Output: printf("%c", charVariable);
Comments are used in C programming to provide information about the code, or to add notes for yourself or other developers. Comments are ignored by the compiler, so they do not affect the execution of the program.
There are two types of comments in C: single-line and multi-line.
Single-line comments start with two forward slashes (//) and continue to the end of the line.
Multi-line comments start with a forward slash and an asterisk (/) and end with an asterisk and a forward slash (/).
/* This is a multi-line comment.
You can use comments to make your code more readable and understandable.It can span multiple lines. */
Formatting:
Formatting is also important in C programming.
Formatting your code can make it easier to read and understand. For example, you can use spaces and tabs to indent your code, and you can use line breaks to separate different sections of code.
Question :
Write a C program to swap 2 numbers without using third variable
Solution :
void main() { int a,b; printf("Enter two numbers \n"); scanf("%d%d",&a,&b); printf("Value of a before swapping is : %d\n",a); printf("Value of b before swapping is : %d\n",b); a=a+b; b=a-b; a=a-b; printf("\nValue of a after swapping is : %d\n",a); printf("Value of b after swapping is : %d\n",b); }
Chapter 3: Control Structures
Conditional statements in C are programming constructs that allow a program to execute different blocks of code based on whether a certain condition is true or false. The most common types of conditional statements in C are the if, else if, and else statements.
The syntax for the if statement is:
if (condition) { // block of code to execute if condition is true }
The else if statement is used to execute a block of code if a certain condition is true, and another block of code if the condition is false. The syntax for the else if statement is:
if (condition1) { // block of code to execute if condition1 is true } else if (condition2) { // block of code to execute if condition2 is true } else { // block of code to execute if condition1 and condition2 are false }
Switch Statement
The switch statement in C is a selection statement that allows you to transfer control to different statements within the switch body depending on the value of the switch expression.
switch (expression) { case value1: // code to be executed; break; } case value2: // code to be executed; break; default: // code to be executed if all cases are not matched;
For Loop
The for loop is a repetition control structure that allows you to efficiently write a loop that needs to execute a specific number of times.
The syntax of a for loop in C programming language is:
for (initialization; condition; increment) { // statement(s); }
Here is the flow of control in a 'for' loop:
The initialization statement is executed once, before the loop begins.
The condition statement is evaluated. If it is true, the loop body is executed. If it is false, the loop terminates.
The increment statement is executed after the loop body is executed, before the condition statement is evaluated again.
The loop goes back to step 2 and repeats the process until the condition statement becomes false.
Here is an example of a for loop that prints the numbers from 1 to 10:
for (int i = 0; i < 10; i++) { printf("%d\n", i); }
This loop will print the numbers from 1 to 10, one per line.
While Loop
The while loop in C is a programming construct that allows us to execute a block of code repeatedly, as long as a specified condition remains true. The syntax for a while loop in C is:
while (condition) { // code block }
The condition is a Boolean expression that is evaluated before each iteration of the loop. If the expression evaluates to true, the code block is executed. If the expression evaluates to false, the loop terminates.
Here is an example of a while loop in C that prints the numbers from 1 to 10:
int i = 1; while (i <= 10) { printf("%d\n", i); i++; }
In this example, the variable i is initialized to 1. The loop then iterates as long as i is less than or equal to 10. On each iteration, the value of i is printed to the console, and then i is incremented by 1. The loop terminates when i is greater than 10.
Do - While Loop
The do-while loop is a programming construct that allows us to execute a block of code repeatedly, until a specified condition is met. The syntax for a do-while loop in C is as follows:
do { // statements } while (condition);
The do keyword is followed by a block of statements, which is executed repeatedly. The while keyword is followed by a condition, which is evaluated after each iteration of the loop. If the condition is true, the loop is executed again; otherwise, the loop terminates.
Here is an example of a do-while loop in C that prints the numbers from 1 to 10:
int i = 1; do { printf("%d\n", i); i++; } while (i <= 10);
This loop will print the numbers from 1 to 10, inclusive
The do-while loop is a useful construct for situations where you need to execute a block of code repeatedly, but you don't know how many times the loop should iterate. For example, you could use a do-while loop to read input from a user until they enter a valid value.
The break and continue statements in C are used to control the flow of a loop. The break statement causes the loop to terminate immediately, while the continue statement causes the loop to skip the current iteration and continue with the next iteration.
Break Statement
Here is an example of how to use the break statement:
int i; for (i = 0; i < 10; i++) { if (i == 5) { break; } printf("%d\n", i); }
This code will print the numbers from 0 to 4, and then the break statement will cause the loop to terminate.
Continue Statement
Here is an example of how to use the continue statement:
int i; for (i = 0; i < 10; i++) { if (i == 5) { continue; } printf("%d\n", i); }
This code will print the numbers from 0 to 9, skipping the number 5.
The break and continue statements can be used together to create more complex control flows. For example, the following code will print the numbers from 0 to 9, but it will skip the numbers 5 and 7:
int i; for (i = 0; i < 10; i++) { if (i == 5 || i == 7) { continue; } printf("%d\n", i); }
The break and continue statements are powerful tools that can be used to control the flow of a program. However, they should be used with care, as they can easily lead to unexpected results.
The ternary operator in C is a conditional operator that can be used to replace an if-else statement.
The syntax for the ternary operator is- ? :
where ? is the conditional expression, :` is the separator, and expression1 and expression2 are the expressions to be evaluated if the condition is true or false, respectively.
Example:
For example, the following code uses the ternary operator to print "hello world" if the value of x is greater than 10, and "goodbye world" otherwise:
int x = 15; printf("%s", x > 10 ? "hello world" : "goodbye world");
For example, the following code uses the ternary operator to assign the value of x to y if x is greater than 10, and the value of 0 otherwise:
int x = 15; int y; y = x > 10 ? x : 0;
Question 1 :
Write a C program to check a number is odd or even
Solution :
int main() { int num; printf("Enter a number : "); scanf("%d",&num); if(num%2==0) printf("Number is even \n"); else printf("Number is odd \n"); return 0; }
Question 2 :
Write a C program to find sum of series : 1+2+3....N
Solution :
void main() { int i,N,sum=0; printf("Enter the value of N\n"); scanf("%d",&N); for(i=1;i<=N;i++) { sum=sum+i; } printf("Sum from 1 to %d is: %d\n",N,sum); }
Question 3 :
Write a C program to find factorial of a number
Solution :
void main() { int n,i,f=1; printf("Enter a number\n"); scanf("%d",&n); for(i=1;i<=n;i++) { f=f*i; } if(n < 0) printf("Factorial does not exist for negative number\n"); else printf("Factorial is %d\n",f); }
Question 4 :
Write a C program to find sum of digits of a number
Solution :
void main() { int n,d,sum=0,copy; printf("Enter a number\n"); scanf("%d",&n); copy=n; while(copy!=0) { d=copy%10; sum=sum+d; copy/=10; } printf("Sum of digits is : %d\n",sum); }
Chapter 4: Functions
What is Functions?
A function is a group of statements that together perform a task. Every C program has at least one function, which is main(), and all the most trivial programs can define additional functions.
A function declaration tells the compiler about a function's name, return type, and parameters. A function definition provides the actual body of the function.
Defining a Function:
The general form of a function definition in C programming language is as follows −
return_type function_name( parameter list ) { //body of the function }
A function definition in C programming consists of a function header and a function body. Here are all the parts of a function −
• Return Type - A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, thereturn_type is the keyword void. • Function Name - This is the actual name of the function. The function name and the parameter list together constitute the function signature. Parameters - A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters. • Function Body - The function body contains a collection of statements that define what the function does.
Example:
Given below is the source code for a function called max(). This function takes two parameters num1 and num2 and returns the maximum value between the two −
/* function returning the max between two numbers */ int max(int num1, int num2) { /* local variable declaration */ int result; if (num1 > num2) result = num1; else result = num2; return result; }
Calling a Function:
While creating a C function, you give a definition of what the function has to do. To use a function, you will have to call that function to perform the defined task.
When a program calls a function, the program control is transferred to the called function. A called function performs a defined task and when its return statement is executed or when its function-ending closing brace is reached, it returns the program control back to the main program.
To call a function, you simply need to pass the required parameters along with the function name, and if the function returns a value, then you can store the returned value. For example −
/* function declaration */ int max(int num1, int num2); int main() { /* local variable definition */ int a = 100; int b = 200; int ret; /* calling a function to get max value */ ret = max(a, b); printf("Max value is : %d\n", ret ); return 0; } /* function returning the max between two numbers */ int max(int num1, int num2) { /* local variable declaration */ int result; if (num1> num2) result = num1; else result = num2; return result; }
Output: Max value is : 200
Parameters in C functions
Pass by Value. Pass by Value, means that a copy of the data is made and stored by way of the name of the parameter. Any changes to the parameter have NO affect on data in the calling function.
Pass by Reference. A reference parameter "refers" to the original data in the calling function
Return Values in C functions
The return statement may or may not return a value depending upon the return type of the function. For example, int returns an integer value, void returns nothing, etc.
The scope of a variable in C is the region of code where the variable can be accessed. The lifetime of a variable in C is the time period during which the variable exists in memory.
There are two main types of scopes in C: global and local. Global variables are declared outside of any function, and they can be accessed from anywhere in the program. Local variables are declared inside of a function, and they can only be accessed from within that function.
The lifetime of a variable is determined by its scope. Global variables have a lifetime that lasts for the entire program, while local variables have a lifetime that lasts only for the duration of the function in which they are declared.
There are also two main types of lifetimes in C: static and automatic. Static variables are declared with the static keyword, and they exist in memory for the entire lifetime of the program. Automatic variables are declared without the static keyword, and they exist in memory only for the duration of the function in which they are declared.
Here is an example of the scope and lifetime of variables in C:
#include < stdio.h> int main() { int local_variable = 1; // Local variable static int global_variable = 2; // Global variable printf("The local variable is %d\n", local_variable); printf("The global variable is %d\n", global_variable); return 0; }
In this example, the local_variable is declared inside of the main() function, so it has a local scope. The global_variable is declared outside of any function, so it has a global scope.
The local_variable will exist in memory only for the duration of the main() function. The global_variable will exist in memory for the entire lifetime of the program.
What is Function Prototype in C?
A function prototype in C is a function declaration specifying the function’s return type, name, and the number and types of its parameters. It acts as a contract between the function definition and its callers, providing information about the expected inputs and outputs of the function.
The C function prototype is a statement that tells the compiler about the function's name, its return type, numbers and data types of its parameters.
By using this information, the compiler cross-checks function parameters and their data type with function definition and function call.
What is Recursion?
Recursion is a programming technique in which a function calls itself directly or indirectly. The process of recursion consists of multiple recursive calls. The function that calls itself is called a recursive function.
What Recursion looks like:
A ladder like structure.
Recursion can be used to solve many problems, such as:
1. Finding the factorial of a number
2. Generating the Fibonacci sequence
3. Finding the longest common substring of two strings
4. Sorting a list of numbers
For example, the following function calculates the factorial of a number:
int factorial(int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } }
Question 1 :
Write a C program to implement fibonacci series
Solution :
void main() { int num; printf("Enter range\n"); scanf("%d",&num); printf("Fibonacci series upto %d is :\n",num); fibo(num); printf("\n"); } void fibo(int a) { int f=0,f1=1,f2=0,i; printf("%d %d ",f,f1); for(i=2;i < a ;i++) { f2 = f+f1; printf(" %d ",f2); f=f1; f1=f2; } }
Question 2 :
Write a C program to find GCD & LCD using recursion
Solution :
void main() { int num1,num2,gc,lc; printf("Enter two numbers\n"); scanf("%d%d",&num1,&num2); gc=gcd(num1,num2); lc=lcm(num1,num2); printf("GCD of %d and %d is : %d",num1,num2,gc); printf("\nLCM of %d and %d is : %d\n",num1,num2,lc); } int lcm(int c, int d) { static int temp = 1; if(temp%c==0 && temp%d==0) { return temp; } else { temp++; lcm(c,d); return temp; } } int gcd(int a,int b) { if (b == 0) return a; else return gcd(b, a % b); }
Question 3 :
Write a C program to find factorial of a number using recursion
Solution :
void main() { int num,fa; printf("Enter a number\n"); scanf("%d",&num); fa=fact(num); printf("Factorial of %d is : %d\n",num,fa); } int fact(int n) { if(n==1) return 1; else return n*fact(n-1); }
Question 4 :
Write a C program to find : 1/1! + 1/2! +1/3!....+1/N!
Solution :
double sum_of_series(int n) { double sum = 0; double fact = 1; for (int i = 1; i <= n; i++) { fact *= i; sum += 1 / fact; } return sum; } int main() { int n; printf("Enter the value of n: \n"); scanf("%d", &n); printf("Sum of the series is %lf\n", sum_of_series(n)); return 0; }
Chapter 5: Arrays and Pointers
What is Array?
An array in C is a collection of data items of the same data type that are stored in contiguous memory locations. The data items in an array are accessed using an index, which is an integer value that specifies the position of the item in the array.
To declare an array in C, you use the following syntax:
data_type array_name [size];
where data_type is the type of the data items in the array, array_name is the name of the array, and size is the number of elements in the array.
For example, the following code declares an array of 10 integers:
int numbers [10];
To access an element in an array, you use the following syntax:
array_name [index]
where array_name is the name of the array, and index is the index of the element you want to access.
For example, the following code prints the value of the first element in the numbers array:
printf("%d\n", numbers [0]);
You can also use the for loop to iterate over the elements of an array. For example, the following code prints the values of all elements in the numbers array:
for (int i = 0; i < 10; i++) { printf("%d\n", numbers [i]); }
Arrays are a powerful tool for storing and manipulating data in C. They can be used to solve a variety of problems, such as sorting, searching, and filtering data.
What is Pointer?
A pointer in C is a variable that stores the memory address of another variable. Pointers are used to access the memory of the said variable and then manipulate their addresses in a program.
What is Memory Address?
The memory address is the location of where the variable is stored on the computer. A pointer basically stores the memory address of a variable as its value. To print pointer values, we use the %p format specifier.
In C, there are three types of pointers:
- Integer pointers: - These pointers store the memory address of an integer variable.
- Character pointers: - These pointers store the memory address of a character variable.
- Void pointers: - These pointers can store the memory address of any type of variable.
Pointers are important in C, because they allow us to manipulate the data in the computer's memory. This can reduce the code and improve the performance.
Here is an example of how to use a pointer in C:
int main() { int x = 10; int* p = &x; printf("%p\n", p); // Prints the address of x *p = 20; // Changes the value of x to 20 printf("%d\n", x); // Prints the value of x, which is now 20 return 0; }
In this example, the p pointer is used to store the memory address of the x variable. The *p operator is used to dereference the pointer, which means that it is used to access the data that is stored at the memory address that the pointer points to. In this case, the *p operator is used to change the value of the x variable to 20.
Pointer arithmetic is a C programming concept that allows you to perform arithmetic operations on pointers, such as addition, subtraction, increment, and decrement. The size of the data type the pointer points to determines the size of the step taken during the arithmetic operation.
For example, if you have a pointer to an int, then adding 1 to the pointer will move it to the next int in memory. Similarly, if you have a pointer to a char, then adding 1 to the pointer will move it to the next char in memory.
Pointer arithmetic can be used to iterate over arrays and structures. For example, the following code would iterate over the array arr of 5 integers:
int arr[] = {1, 2, 3, 4, 5}; int *ptr = arr; for (int i = 0; i < 5; i++) { printf("%d\n", *ptr); ptr++; }
The output of the code would be:
1 2 3 4 5
Pointer arithmetic can also be used to compare pointers. For example, the following code would compare the pointers ptr1 and ptr2 to see if they point to the same memory location:
int *ptr1 = &arr[0]; int *ptr2 = &arr[1]; if (ptr1 == ptr2) { printf("The pointers are equal.\n"); } else { printf("The pointers are not equal.\n"); }
The output of the code would be:
"The pointers are not equal."
Pointers & Arrays
You can also use pointers to access arrays.
Consider the following array of integers:
Example
int myNumbers[4] = {25, 50, 75, 100};
You learned from the arrays chapter that you can loop through the array elements with a for loop:
Example
int myNumbers[4] = {25, 50, 75, 100};
int i;
for (i = 0; i < 4; i++)
{
printf("%d\n", myNumbers[i]);
}
25 50 75 100
Instead of printing the value of each array element, let's print the memory address of each array element:
Example
int myNumbers [4] = {25, 50, 75, 100}; int i; for (i = 0; i < 4; i++) { printf("%p\n", &myNumbers[i]); }
Output:
0x7ffe70f9d8f0 0x7ffe70f9d8f4 0x7ffe70f9d8f8 0x7ffe70f9d8fc
So from the "memory address example" above, you can see that the compiler reserves 4 bytes of memory for each array element, which means that the entire array takes up 16 bytes (4 * 4) of memory storage:
Example
int myNumbers [4] = {25, 50, 75, 100}; // Get the size of the myNumbers array printf("%lu", sizeof(myNumbers));
Output:
16
How Are Pointers Related to Arrays
Well, in C, the name of an array, is actually a pointer to the first element of the array.
Let's try to understand this better, and use our "memory address example" above again.
The memory address of the first element is the same as the name of the array:
Example int myNumbers [4] = {25, 50, 75, 100}; // Get the memory address of the myNumbers array printf("%p\n", myNumbers); // Get the memory address of the first array element printf("%p\n", &myNumbers[0]); Result: 0x7ffe70f9d8f0 0x7ffe70f9d8f0
This way of working with arrays might seem a bit excessive. Especially with simple arrays like in the examples above. However, for large arrays, it can be much more efficient to access and manipulate arrays with pointers.
It is also considered faster and easier to access two-dimensional arrays with pointers.
And since strings are actually arrays, you can also use pointers to access strings.
For now, it's great that you know how this works. But like we specified in the previous chapter; pointers must be handled with care, since it is possible to overwrite other data stored in memory.
What is Dynamic Memory Allocation?
Dynamic memory allocation in C is a process in which memory is allocated or deallocated during the run-time of a program. There are four functions malloc(), calloc(), realloc() and free() present in
header file that are used for Dynamic Memory Allocation in our system. Here is an example of how to use malloc() to dynamically allocate memory in C:
#include < stdio.h> #include < stdlib.h> int main() { int *ptr, n; printf("Enter number of elements: "); scanf("%d", &n); ptr = (int *)malloc(n * sizeof(int)); //memory allocated using malloc. if (ptr == NULL) { printf("Memory could not be allocated."); return 1; } for (int i = 0; i < n; i++) { printf("Enter element %d: ", i + 1); scanf("%d", &ptr[i]); } for (int i = 0; i < n; i++) { printf("Element %d: %d\n", i + 1, ptr[i]); } free(ptr); //memory deallocated using free() return 0; }
Output:
Enter number of elements: 5 Enter element 1: 1 Enter element 2: 2 Enter element 3: 3 Enter element 4: 4 Enter element 5: 5 Element 1: 1 Element 2: 2 Element 3: 3 Element 4: 4 Element 5: 5
The malloc() function takes two arguments: the number of bytes to allocate and a pointer to a variable that will be used to store the address of the allocated memory. The function returns a pointer to the allocated memory, or NULL if the allocation fails.
In the example above, the malloc() function is used to allocate memory for an array of 5 integers. The address of the allocated memory is stored in the pointer ptr. The elements of the array are then initialized using a for loop. Finally, the free() function is used to deallocate the memory that was allocated by malloc().
Dynamic memory allocation is a powerful tool that can be used to improve the flexibility and efficiency of C programs. However, it is important to use dynamic memory allocation carefully to avoid memory leaks and other errors.
Question 1 :
Write a C program to input n elements in array and find frequency of each
Solution :
void main() { int n,x,y,c; printf("Enter array size\n"); scanf("%d",&n); int a[n]; for(x=0; x < n;x++) { printf("Enter array elements: "); scanf("%d",&a[x]); } for(x=0;x< n-1;x++) { c=1; for(y=x+1;y < n;y++) { if(a[x]==a[y]) { a[y]=-1; c++; } } if(a[x]!=-1) printf("Frequency of %d is: %d\n",a[x],c); } if(a[n-1]!=-1) printf("Frequency of %d is: %d\n",a[n-1],c); }
Question 2 :
Write a C program to input n elements in array and delete duplicates
Solution :
void main() { int n,x,y,p=0; printf("Enter array size\n"); scanf("%d",&n); int a[n],b[n]; for(x=0;x< n;x++) { printf("Enter array elements: "); scanf("%d",&a[x]); } for(x=0;x< n-1;x++) { for(y=x+1;y< n;y++) { if(a[x]==a[y]) { a[y]=-1; } } if(a[x]!=-1) b[p++]=a[x]; } if(a[n-1]!=-1) b[p++]=a[n-1]; printf("Array without duplicates is : \n"); for(x=0;x< p;x++) { printf("%d ",b[x]); } printf("\n"); }
Question 3 :
Write a C program to merge 2 arrays using dynamic memory allocation
Solution :
int main() { int n1, n2, i; int *arr1, *arr2, *arr3; printf("Enter size of first array: "); scanf("%d", &n1); arr1 = (int*) malloc(n1 * sizeof(int)); printf("Enter elements of first array: "); for(i=0; i< n1; i++) scanf("%d", arr1+i); printf("\nEnter size of second array: "); scanf("%d", &n2); arr2 = (int*) malloc(n2 * sizeof(int)); printf("Enter elements of second array: "); for(i=0; i< n2; i++) scanf("%d", arr2+i); arr3 = (int*) malloc((n1+n2) * sizeof(int)); for(i=0; i< n1; i++) *(arr3+i) = *(arr1+i); for(i=0; i< n2; i++) *(arr3+n1+i) = *(arr2+i); printf("\nMerged array is :"); for(i=0; i< n1+n2; i++) printf("%d ", *(arr3+i)); printf("\n"); return 0; }
Chapter 6: Structures and Unions
What is Structures in C?
A struct in the C programming language (and many derivatives) is a composite data type (or record) declaration that defines a physically grouped list of variables under one name in a block of memory, allowing the different variables to be accessed via a single pointer or by the struct declared name which returns the same address. The struct data type can contain other data types so is used for mixed-data-type records such as a hard-drive directory entry (file length, name, extension, physical address, etc.), or other mixed-type records (name, address, telephone, balance, etc.).
Here is an example of how to define and use structures in C:
// Define a structure struct employee { int id; char name[20]; float salary; }; // Create a structure variable struct employee employee1; // Initialize the structure variable employee1.id = 1234; strcpy(employee1.name, "John Doe"); employee1.salary = 100000.00; // Print the structure variable printf("Employee ID: %d\n", employee1.id); printf("Employee Name: %s\n", employee1.name); printf("Employee Salary: %.2f\n", employee1.salary);
In this example, we define a structure named employee with three members: id, name, and salary. We then create a structure variable named employee1 and initialize its members. Finally, we print the values of the structure variable.
Here are some other things to keep in mind about structures in C:
You can use the struct keyword to define a structure.
You can use the sizeof() operator to determine the size of a structure.
You can use the strcpy() function to copy a string to a structure member.
You can use the printf() function to print the values of a structure member.
You can pass a structure to a function as an argument.
You can return a structure from a function.
What is Unions in C?
A union in C is a user-defined data type that allows different types of data to be stored in the same memory location. It provides a way to define a variable that may have different data types, but at any given time, only one member of the union can hold a value.
The syntax for defining a union in C is:
"union unionName { //member definitions };"
For example, the following code defines a union with two members: an integer and a float:
"union intFloatUnion
{
int intMember;
float floatMember;
};"
To use a union, you can declare a variable of the union type and then assign a value to one of the members. For example, the following code declares a variable of type unionIntFloatUnion and then assigns the value 10 to the intMember member:
"unionIntFloatUnion myUnion;
myUnion.intMember = 10;"You can then access the value of the intMember member by using the . operator:
"printf("%d\n", myUnion.intMember);"
This will print the value 10 to the console.
It is important to note that only one member of a union can contain a value at a time. For example, the following code will not compile:
unionIntFloatUnion myUnion;
myUnion.intMember = 10;
myUnion.floatMember = 3.14;This is because the floatMember member is already occupied by the value 10. To assign a value to the floatMember member, you must first clear the value of the intMember member:
myUnion.intMember = 0;
myUnion.floatMember = 3.14;This will print the value 3.14 to the console.
Unions can be used to optimize memory usage. For example, if you need to store an integer and a float, you can use a union to store both values in the same memory location. This can be useful if you are short on memory or if you want to avoid having to allocate multiple memory locations for different data types.
What is Bit Feidls in C?
A bit field in C is a data structure that allows you to allocate memory to structures and unions in bits in order to use computer memory in an efficient manner.
Since structures and unions are user-defined data types in C, the user has an idea of how much memory they will occupy. Accordingly, by the implementation of bit fields, memory management becomes easy and efficient.
The following example taken from GeeksforGeeks shows how bit fields can be used to conserve memory -
#include < stdio.h> // A simple representation of date struct date { unsigned int d; unsigned int m; unsigned int y; }; int main(void) { printf("Size of date is %d bytes", sizeof(struct date)); struct date dt = {31, 12, 2014}; printf("Date is %d/%d/%d", dt.d, dt.m, dt.y); }
The above representation of 'date' takes 12 bytes on a compiler where an unsigned int takes 4 bytes. Since we know that the value of d is always from 1 to 31, value of m is from 1 … 12, and value of y is from 1900 to 2099, we can use bit fields to reduce the memory usage.
The following code shows how to use bit fields to represent the 'date' structure:
#include
// A simple representation of date using bit fields struct date { unsigned int d : 5; unsigned int m : 5; unsigned int y : 16; }; int main(void) { printf("Size of date is %d bytes", sizeof(struct date)); struct date dt = {31, 12, 2014}; printf("Date is %d/%d/%d", dt.d, dt.m, dt.y); } The above code will print the following:
Size of date is 4 bytes
Date is 31/12/2014As you can see, the size of the 'date' structure has been reduced from 12 bytes to 4 bytes. This is because we are only using 5 bits to store the value of d, 5 bits to store the value of m, and 16 bits to store the value of y.
Bit fields can be used to represent any data structure that has a limited number of possible values. For example, you could use bit fields to represent a 'color' structure, where the possible values are red, green, blue, and black.
What is Structures & Pointers?
In C, a structure is a user-defined data type that allows you to group together variables of different data types under a single name. A structure pointer is a pointer that points to the address of a structure variable.
To declare a structure, you use the struct keyword, followed by the name of the structure, and then a list of members. For example:
struct student { char name[20]; int age; float grade; };
To create a structure variable, you use the struct keyword, followed by the name of the structure, and then a list of values for the members. For example:
struct student student1 = { "John Doe", 20, 3.5 };
To access a member of a structure, you use the -> operator. For example:
"printf("The student's name is %s.\n", student1.name);"
To declare a structure pointer, you use the struct keyword, followed by the name of the structure, and then a pointer to the structure. For example:
"struct student *studentptr;"
To assign a structure pointer to a structure variable, you use the =` operator. For example:
"studentptr = &student1;"
To access a member of a structure through a pointer, you use the -> operator. For example:
"printf("The student's name is %s.\n", studentptr->name);"
Structure pointers can be used to create complex data structures, such as linked lists, trees, and graphs.
What is Nested Structures?
A nested structure in C is a structure that contains one or more members that are themselves structures. This can be used to create complex data structures that can be used to represent real-world objects and relationships.
To define a nested structure, you can simply define one structure inside another structure. For example:
struct employee { int employee_id; char *name; float salary; }; struct organization { char *organization_name; int organization_number; struct employee employee; };
In this example, the organization structure contains a member of type employee. This means that an organization structure can contain an employee structure.
To access members of a nested structure, you use the dot operator (.). For example:
struct organization organization; struct employee employee; organization.employee.employee_id = 1234; organization.employee.name = "John Smith"; organization.employee.salary = 100000.00;
In this example, we are setting the employee_id, name, and salary members of the employee structure that is a member of the organization structure.
Nested structures can be used to create complex data structures that can be used to represent real-world objects and relationships. For example, you could use a nested structure to represent a company, with the organization structure representing the company and the employee structure representing an employee.
Here is an example of how you could use a nested structure to represent a company:
struct company { char *company_name; int company_number; struct employee *employees; }; struct employee { int employee_id; char *name; float salary; };
In this example, the company structure contains a member of type employee *, which is a pointer to an array of employee structures. This means that a company structure can contain an array of employee structures.
To access the members of an array of nested structures, you can use the [] operator. For example:
struct company company; struct employee employee; company.employees[0].employee_id = 1234; company.employees[0].name = "John Smith"; company.employees[0].salary = 100000.00; company.employees[1]. employee_id = 5678; company.employees[1].name = "Jane Doe"; company.employees[1]. salary = 150000.00;
In this example, we are setting the employee_id, name, and salary members of the first and second employee structures that are members of the company structure.
Nested structures can be used to create complex data structures that can be used to represent real-world objects and relationships. This is a powerful tool that can be used to create more realistic and sophisticated programs.