0% found this document useful (0 votes)
11 views

Advance C Module 8

Uploaded by

jet.fire.ch.021
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views

Advance C Module 8

Uploaded by

jet.fire.ch.021
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 7

Module 8

1. const:

Definition: const is a keyword used in C to declare constants.

It defines variables whose values cannot be changed after initialization.

Usage: Typically used to declare variables that represent fixed values or parameters whose values should not
be modified.

Example: const int MAX_SIZE = 100;

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.

This variable value can be modified by things sensor reading in Embedded C.

Usage: Typically used for variables that represent memory-mapped hardware registers, variables shared by
multiple threads, or variables accessed within interrupt service routines.

Example: volatile int *sensorAddress = (int *)0x40000000;

Program:

#include <stdio.h>

// Example of const variable


const int MAX_ATTEMPTS = 8;

// Example of volatile variable


volatile int sensorValue;

int main() {
int attempts = 0;

// Using const variable


while (attempts < MAX_ATTEMPTS) {
attempts++;
printf("Attempt %d\n", attempts);
}

// Using volatile variable


while (1) {
// Check the sensor value
if (sensorValue > 100) {
printf("Sensor value exceeds threshold!\n");
break;
}
}

return 0;
}
3. goto Statement in C

Why and Why Not to Use goto

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.

Disadvantages and Limitations:

• 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:

#include <stdio.h> #include <stdio.h>

int main() { void process_input(int input) {


int i = 0; if (input < 0) {
printf("Error: Input cannot be
loop_start: negative.\n");
printf("Current value of i: %d\n", goto end_processing;
i); // Jump to end_processing label
i++; }
// Process valid input
if (i < 5) printf("Processing input: %d\n",
goto loop_start; input);
// Jump back to loop_start if i < 5
end_processing:
printf("Loop ended.\n"); printf("End of process.\n");
}
return 0;
} int main() {
process_input(10);
process_input(-5);
return 0;
}
4. setjmp() and longjmo()

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:

int setjmp(jmp_buf env);

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:

void longjmp(jmp_buf env, int val);

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>

void print_array(int n, int arr[n]) {


for (int i = 0; i < n; ++i) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}

int main() {
int size;
printf("Enter size of array: ");
scanf("%d", &size);

int arr[size]; // Variable-Length Array

// Initializing and printing array


for (int i = 0; i < size; ++i) {
arr[i] = i * 10;
}

printf("Array elements:\n");
print_array(size, arr);

return 0;
}

➔ Flexible Array Members

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;

// Initializing and printing elements


for (int i = 0; i < size; ++i) {
array->data[i] = i * 2;
printf("array->data[%d] = %d\n", i, array->data[i]);
}

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>

void add_arrays(int n, int *restrict a, int *restrict b, int *restrict result) {


for (int i = 0; i < n; ++i) {
result[i] = a[i] + b[i];
}
}

int main() {
int a[] = {1, 2, 3};
int b[] = {4, 5, 6};
int result[3];

add_arrays(3, a, b, result);

// Printing result array


for (int i = 0; i < 3; ++i) {
printf("result[%d] = %d\n", i, result[i]);
}

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.

Example: Using asm for Inline Assembly

#include <stdio.h>

int main() {
int a = 10, b = 20, result;

// Example of inline assembly to add two numbers


asm("addl %%ebx, %%eax;" : "=a" (result) : "a" (a), "b" (b));

printf("Result: %d\n", result);

return 0;
}

You might also like