Advance C Module 8
Advance C Module 8
1. const:
Usage: Typically used to declare variables that represent fixed values or parameters whose values should not
be modified.
2. volatile:
Definition: volatile is a keyword used in C to declare variables that can be modified unexpectedly.
It informs the compiler that the value of the variable may change at any time without any action being taken
by the code the compiler finds nearby.
Usage: Typically used for variables that represent memory-mapped hardware registers, variables shared by
multiple threads, or variables accessed within interrupt service routines.
Program:
#include <stdio.h>
int main() {
int attempts = 0;
return 0;
}
3. goto Statement in C
The goto statement in C allows you to transfer control to another part of your program. It is typically used to implement
jumps to error-handling routines or to simplify complex logic. However, its use is controversial due to its potential to
create spaghetti code and make programs harder to read and maintain. Here are some points to consider:
Advantages:
• Simplicity: It can simplify certain types of control flow, especially in error handling where multiple nested
conditions would otherwise be required.
• Efficiency: In some cases, using goto can lead to more efficient code compared to nested conditions.
• Readability: Overuse of goto can make the code difficult to understand and follow (often referred to as "spaghetti
code").
• Maintenance: Programs with goto statements are generally harder to modify and debug.
• Scope of Use: Modern programming practices advocate structured programming and discourage the use of goto
except in specific, controlled scenarios.
Program 1: Program 2:
In C programming, setjmp() and longjmp() are used for non-local jumps, which means they can transfer
control from one point in your program to another that is not necessarily within the current function's call chain. This is in
contrast to the usual control flow which proceeds sequentially through function calls and returns.
1. setjmp() Function:
o setjmp() is used to save the current execution state (including the program counter, stack pointer, and
other relevant registers) into a jmp_buf data structure, which is typically an array type.
o The function prototype of setjmp() is:
oIt returns 0 on initial invocation and a non-zero value (typically 1) when returning from a longjmp()
call.
2. longjmp() Function:
o longjmp() is used to restore the execution state saved by setjmp() and transfer control back to the
point where setjmp() was called.
o The function prototype of longjmp() is:
o env is the jmp_buf structure containing the saved state, and val is the value passed to setjmp() when
it returns.
Program:
#include <stdio.h>
#include <setjmp.h>
jmp_buf env;
void func2() {
printf("Inside func2\n");
longjmp(env, 1); // Return to the point of setjmp() with a value of 1
}
void func1() {
printf("Inside func1\n");
func2();
printf("Back in func1 after longjmp\n");
}
int main() {
int val;
val = setjmp(env);
printf("Value retured by setjump is %d\n", val);
if (val == 0) {
printf("Initial setjmp call\n");
func1(); // Calls func2 and then returns here after longjmp
} else {
printf("Returned from longjmp with value: %d\n", val);
}
return 0;
}
5. Arrays
➔ Static Array Indices - Static array indices refer to arrays whose size is determined at compile-time and remains fixed
throughout the program's execution.
Example:
#include <stdio.h>
int main() {
int arr[5]; // Static array with size 5
// Accessing elements
arr[0] = 10;
arr[1] = 20;
// Printing elements
printf("arr[0] = %d\n", arr[0]);
printf("arr[1] = %d\n", arr[1]);
return 0;
}
➔ Designated Initializers - Designated initializers allow initializing specific elements of an array or members of a
structure by specifying their indices or names explicitly.
Example:
#include <stdio.h>
int main() {
// Designated initializers
int arr[5] = { [0] = 10, [2] = 20 };
// Printing elements
printf("arr[0] = %d\n", arr[0]); // Output: 10
printf("arr[1] = %d\n", arr[1]); // Output: 0 (uninitialized)
printf("arr[2] = %d\n", arr[2]); // Output: 20
return 0;
}
➔ Compound Literals - Compound literals provide a way to create unnamed objects of specified types.
Example:
#include <stdio.h>
int main() {
int *p = (int[]){1, 2, 3}; // Compound literal of type int[]
// Accessing elements
printf("p[0] = %d\n", p[0]); // Output: 1
printf("p[1] = %d\n", p[1]); // Output: 2
printf("p[2] = %d\n", p[2]); // Output: 3
return 0;
}
➔ Variable-Length Arrays (VLA) - Variable-Length Arrays allow the size of an array to be determined at runtime.
Example:
#include <stdio.h>
int main() {
int size;
printf("Enter size of array: ");
scanf("%d", &size);
printf("Array elements:\n");
print_array(size, arr);
return 0;
}
Flexible Array Members allow defining a structure with a variable-length array at the end.
Example:
#include <stdio.h>
#include <stdlib.h>
struct FlexArray {
int count;
int data[]; // Flexible array member
};
int main() {
int size = 5;
struct FlexArray *array = malloc(sizeof(struct FlexArray) + size * sizeof(int));
array->count = size;
free(array);
return 0;
}
➔ The restrict Keyword
The restrict keyword is used to indicate that a pointer is the only reference to a particular memory location during its
lifetime, allowing for optimizations by the compiler.
Example:
#include <stdio.h>
int main() {
int a[] = {1, 2, 3};
int b[] = {4, 5, 6};
int result[3];
add_arrays(3, a, b, result);
return 0;
}
6. ++/-- Operations
The increment (++) and decrement (--) operators can lead to unexpected behaviour when they are used multiple times
within a single expression due to sequence point rules
Program:
#include <stdio.h>
int main() {
int x = 1;
int y = ++x + ++x;
printf("y = %d\n", y);
return 0;
}
#include <stdio.h>
int main() {
int x = 1;
int y = ++x + x++;
printf("y = %d\n", y);
return 0;
}
7. The asm Keyword in C
In C programming, the asm keyword allows you to embed assembly language code within your C source code.
This can be useful for several reasons, such as:
• Performance optimization: Writing critical sections of code in assembly language can sometimes result in faster
and more efficient code than what the compiler generates from C.
• Hardware-specific operations: Direct access to hardware features or instructions that are not directly supported
by C can be achieved using assembly language.
#include <stdio.h>
int main() {
int a = 10, b = 20, result;
return 0;
}