0% found this document useful (0 votes)
6 views46 pages

Ch3 1

The document provides an overview of enumerators, structures, and unions in C programming. It explains enumerators as user-defined data types for creating named constants, structures for grouping different data types, and complex structures for managing hierarchical data. Additionally, it covers various usages of enumerators, including basic, custom, and bit-flag enumerators, as well as how to define and use structures effectively.

Uploaded by

mitaligole02
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views46 pages

Ch3 1

The document provides an overview of enumerators, structures, and unions in C programming. It explains enumerators as user-defined data types for creating named constants, structures for grouping different data types, and complex structures for managing hierarchical data. Additionally, it covers various usages of enumerators, including basic, custom, and bit-flag enumerators, as well as how to define and use structures effectively.

Uploaded by

mitaligole02
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 46

Enumerators , Structures , Unions

Prof. Agola Abhi


Assistant Professor
Computer Science and Engineering(AIML)
Outline

 Enumerators CHAPTER-1
 Structures Preprocessor Directives
 Unions
What is Enumerators (Enums)?
• An enumerator is a user-defined data type that assigns names to a set of integral constants.
• It makes your code more readable and organized by replacing raw numbers with meaningful names.
• Enums are defined using the enum keyword and can be of different types based on their usage.

How can we use Enums? Example :

enum TrafficLight { Red, Yellow, Green };


Syntax :
enum EnumName { int main() {
CONSTANT1, CONSTANT2, enum TrafficLight signal = Red;
CONSTANT3 if (signal == Red) {
}; printf("STOP\n");
}
return 0;
}
When can we use Enums?

• When you have a fixed set of related constants:


• Examples:
• Days of the week (Monday, Tuesday, ...).
• Traffic lights (Red, Yellow, Green).
• Status codes (Success, Error, Pending).
Why do we use Enums?

1. Improves readability:Enums replace raw numbers with descriptive names, making the code easier to understand.

2. Reduces errors:Prevents the use of undefined or incorrect constants.

3. Enhances maintainability:If the values of constants change, you only update them in the enum declaration.

4. Better code organization:Groups related constants together under one name.


Example
enum DifficultyLevel { Easy, Medium, Hard };

void displayDifficulty(enum DifficultyLevel level) {


if (level == Easy) printf("You selected EASY mode.\n");
else if (level == Medium) printf("You selected MEDIUM mode.\n");
else if (level == Hard) printf("You selected HARD mode.\n");
}

int main() {
displayDifficulty(Medium);
return 0;
}
Types / Usages of Enumerators (enums)
1. Basic Enumerators : A simple list of named constants where each constant is automatically assigned an
integer value starting from 0 (by default).
2. Enumerators with Custom Values : Similar to basic enumerators, but you can manually assign specific
integer values to some or all constants.
3. Enumerators with Arithmetic or Mixed Values : Enumerators where values are assigned using
calculations or combinations of other constants.
4. Anonymous Enumerators : Enumerators without a name, used directly to define constants.
5. Typedef Enumerators : Enumerators defined with a typedef so you can use them without the enum
keyword every time.
6. Bit-Flag Enumerators : Enumerators where each constant represents a power of 2, allowing multiple
constants to be combined using bitwise operations.
Types / Usages of Enumerators (enums)
1. Basic Enumerators: #include <stdio.h>
enum DaysOfWeek {
These are simple enumerations where constants are MONDAY, // 0
assigned integer values automatically starting from 0 TUESDAY, // 1
(default) or from a user-specified value. WEDNESDAY, // 2
THURSDAY, // 3
Syntax : FRIDAY, // 4
enum EnumName { SATURDAY, // 5
SUNDAY // 6
CONSTANT1,
};
CONSTANT2,
CONSTANT3 int main() {
}; enum DaysOfWeek today = WEDNESDAY;
printf("Today is day number: %d\n", today); // Outputs: 2
return 0;
}
Types / Usages of Enumerators (enums)
2. Enumerators with Custom Values #include <stdio.h>
enum ErrorCodes {
You can assign specific integer values to the constants in the SUCCESS = 0,
enum. ERROR_FILE_NOT_FOUND = 404,
If a value isn't specified, it will continue from the previous ERROR_ACCESS_DENIED = 403,
constant's value. ERROR_TIMEOUT = 408
Syntax : };
enum EnumName {
int main() {
CONSTANT1 = 10, enum ErrorCodes error = ERROR_FILE_NOT_FOUND;
CONSTANT2 = 20, printf("Error Code: %d\n", error); // Outputs: 404
CONSTANT3 return 0;
}; }

Real-World Analogy:
HTTP Status Codes: 200 for success, 404 for file not found,
etc.
Types / Usages of Enumerators (enums)
3. Enumerators with Arithmetic or Mixed Values #include <stdio.h>
enum MemorySizes {
Enums allow performing arithmetic operations during BYTE = 1,
declaration, combining constants or offsets. KILOBYTE = BYTE * 1024,
MEGABYTE = KILOBYTE * 1024,
GIGABYTE = MEGABYTE * 1024
Syntax : };
enum EnumName {
int main() {
CONSTANT1 = 10, printf("1 GB = %d bytes\n", GIGABYTE); // Outputs:
CONSTANT2 = CONSTANT1 + 10, 1073741824
CONSTANT3 = CONSTANT2 * 2 return 0;
}; }

Real-World Analogy:
Memory Units: 1 KB = 1024 Bytes, 1 MB = 1024 KB, 1
GB = 1024 MB.
Types / Usages of Enumerators (enums)
4. Anonymous Enumerators #include <stdio.h>

Enums can be defined without a name when their constants int main() {
are to be used directly. enum {
LOW,
MEDIUM,
Syntax : HIGH
};
enum {
CONSTANT1 = 1, int priority = HIGH;
CONSTANT2, printf("Priority level: %d\n", priority); // Outputs: 2
CONSTANT3 return 0;
}; }
Types / Usages of Enumerators (enums)
5. Typedef Enumerators #include <stdio.h>

Enumerators defined with a typedef so you can use them typedef enum {
without the enum keyword every time. SPRING,
. SUMMER,
FALL,
Syntax : WINTER
} Season;
typedef enum {
CONSTANT1, int main() {
CONSTANT2, Season currentSeason = FALL;
CONSTANT3 printf("Current season: %d\n", currentSeason); //
} EnumAlias; Outputs: 2
return 0;
}
Types / Usages of Enumerators (enums)
6. Bit-Flag Enumerators #include <stdio.h>

Bit-Flag Enumerators are a way to use binary values to store enum Permissions {
multiple options in a single variable. This is useful when READ = 1, // 0001
you want to store multiple on/off (true/false) values WRITE = 2, // 0010
efficiently. EXECUTE = 4 // 0100
};
Syntax :
int main() {
enum EnumName { int permissions = READ | WRITE; // Combine using
FLAG1 = 1, // 1 << 0 bitwise OR
FLAG2 = 2, // 1 << 1 printf("Permissions: %d\n", permissions); // Outputs: 3
FLAG3 = 4 // 1 << 2 (0001 | 0010 = 0011)
}; return 0;
}
Structure
What is a Structure in C?
• A structure is a user-defined data type that allows you to group multiple variables of
different data types under one name.
• Structures are particularly useful when you need to represent a complex entity with
various attributes.
• For example, if you need to represent a "Person," you can group attributes like name
(string), age (integer), and height (float) together using a structure.
Declaring a Structure in C
Syntax :
struct StructureName {
dataType member1; Example :
dataType member2; struct Person {
// More members can be added as needed char name[50]; Here:
}; int age; name is a string (character array) to store the
float height; person's name.
}; age is an integer to store the person's age.
height is a float to store the person's height.
Accessing and Using Structures
#include <stdio.h> // Assign values to the members
printf("Enter name: ");
struct Person { scanf("%s", person1.name);
char name[50]; printf("Enter age: ");
int age; scanf("%d", &person1.age);
float height; printf("Enter height: ");
}; scanf("%f", &person1.height);

int main() { // Print the details


printf("\nPerson Details:\n");
// Create a structure variable
printf("Name: %s\n", person1.name);
struct Person person1; printf("Age: %d\n", person1.age);
printf("Height: %.2f meters\n", person1.height);
return 0;
}
Key Points

• Structures allow combining variables of different types into one entity.


• Use the struct keyword to define a structure.
• Access members using the dot (.) operator.
• Structures are essential when dealing with real-world objects or entities.
Complex Structures
• A complex structure in C is a structure that contains other structures or arrays as members.
• It allows you to create a hierarchy of related data, making it easier to represent and manage more complex
entities.

A complex structure in C refers to a structure that contains:


• Nested structures: A structure as a member of another structure.
• Arrays within structures: Arrays as members of a structure.
• Pointers in structures: Members that are pointers.
• Structures with self-referential pointers: A structure having a pointer to the same structure type (used in
linked lists, trees, etc.).
How to Define a Complex Structure?
• Include one structure inside another (nested structures).
• Use arrays within a structure.

Syntax for Nested Structures


struct Structure1 { Syntax for Structures with Arrays
dataType member1; struct Structure {
dataType member2; dataType arrayMember[arraySize];
// More members dataType member2;
}; };
struct Structure2 {
struct Structure1 nestedStructure; // Structure inside
another
dataType member3;
};
Example: Nested Structures
#include <stdio.h> int main() { printf("Enter zip code: ");
// Define the Address structure scanf("%d", &emp.address.zipCode);
struct Employee emp;
struct Address { // Input employee details // Print employee details
char street[100]; printf("Enter name: "); printf("\nEmployee Details:\n");
char city[50]; scanf("%s", emp.name); printf("Name: %s\n", emp.name);
int zipCode; printf("Enter age: "); printf("Age: %d\n", emp.age);
}; scanf("%d", &emp.age); printf("Address: %s, %s - %d\n",
// Define the Employee structure
printf("Enter street: "); emp.address.street, emp.address.city,
struct Employee {
scanf("%s", emp.address.street); emp.address.zipCode);
char name[50];
printf("Enter city: "); return 0;
int age;
scanf("%s", emp.address.city); }
struct Address address; // Nested structure
};
Array of Structures
• An array of structures means we have multiple instances of a structure stored in an array.
• Each element in the array is a separate structure.
• Think of it like having multiple boxes, and each box can store information of a single item. All the
boxes are of the same type. struct Student {
char name[50];
int age;
float marks;
Example: };
Imagine you are collecting information about students in a class: struct Student students[3]; // Array of 3 Students
• Each student has a name, age, and marks.
• You create a structure Student and an array of 3 students.
Example: Array of Structures
#include <stdio.h> // Input details for each student // Display details of each student
// Define the structure for (int i = 0; i < 3; i++) { printf("Student Details:\n");
struct Student { printf("Enter details for student %d:\n", for (int i = 0; i < 3; i++) {
char name[50]; i + 1); printf("Student %d: Name: %s, Age:
int age; printf("Name: "); %d, Marks: %.2f\n",
float marks; scanf("%s", students[i].name); i + 1, students[i].name,
}; printf("Age: "); students[i].age, students[i].marks);
int main() { scanf("%d", &students[i].age); }
// Declare an array of structures printf("Marks: ");
struct Student students[3]; // Array of 3 scanf("%f", &students[i].marks); return 0;
structures printf("\n"); }
}
Array within a Structure
An array within a structure means the structure itself has an array as one of its members.
Think of it like having one big box, and inside this box, there is an array to store multiple related items

struct Library {
char name[50];
Example: char books[3][50]; // Array to store 3 book names
Imagine you have a library: };
• Each library has a name and multiple books.
• You create a structure Library that contains an array of books.
Example: Array within a Structure
#include <stdio.h> int main() { // Display library details
// Define a structure for a Library struct Library library; printf("\nLibrary Name: %s\n",
struct Library { // Input library details library.name);
char name[50]; printf("Enter library name: "); printf("Books Available:\n");
char books[3][50]; // Array to store 3 scanf("%s", library.name); for (int i = 0; i < 3; i++) {
book names printf("Book %d: %s\n", i + 1,
}; printf("\nEnter names of 3 books:\n"); library.books[i]);
for (int i = 0; i < 3; i++) { }
printf("Book %d: ", i + 1); return 0;
scanf("%s", library.books[i]); }
}
Structure and Functions
• Structures can be used with functions in C for better modularity and reusability.
• Users can pass a structure to a function, return a structure from a function, or manipulate structure members
within a function.

Passing Structures to Functions


1. By Value: The function receives a copy of the structure.
2. By Reference (Pointer): The function can modify the original structure.

void functionName(struct StructureName structureVariable);


void functionName(struct StructureName *structureVariable);
Example: Passing Structures to Functions (By Value)
#include <stdio.h> int main() {
struct Student stu = {"Alice", 20};
struct Student { displayStudent(stu); // Pass structure to
char name[20]; function
int age; return 0;
}; }

void displayStudent(struct Student s) { // Output:-


Structure passed by value Name: Alice
printf("Name: %s\n", s.name); Age: 20
printf("Age: %d\n", s.age);
} Here, stu is passed by value, so changes inside
displayStudent() won’t affect the original stu.
Example: Passing Structures to Functions(By Reference)
#include <stdio.h> printf("Updated Age: %d\n", stu.age); //
struct Student { Original structure modified
char name[20]; return 0;
int age; }
};
void updateAge(struct Student *s) { // OutPut
Structure passed by reference (pointer) Updated Age: 25
s->age = 25; // The arrow operator (->) in
C is used to access members of a structure
through a pointer
}
int main() {
struct Student stu = {"Alice", 20};
updateAge(&stu); // Pass address of
structure
Anonymous Structures
• An anonymous structure is a structure declared without a name. It is primarily used for grouping related
variables under one scope without requiring the structure to be explicitly named.

Key Features:
• No explicit name for the structure. struct {
• Useful for simple and temporary groupings of data. dataType member1;
• Typically used in conjunction with typedef or as part of other structures. dataType member2;
// More members
} variableName;
Example
// Assign values
printf("Enter name: ");
Real-World Example:
#include <stdio.h> scanf("%s", person.name);
You want to quickly
printf("Enter age: ");
group and manage
int main() { scanf("%d", &person.age);
data for a temporary
struct { purpose, such as
char name[50]; // Display values
storing information
int age; printf("Name: %s\n", person.name);
about a one-time
} person; printf("Age: %d\n", person.age);
event (e.g., a single
visitor's details).
return 0;
}
Self-Referential Structures
• A self-referential structure is a structure in programming that includes a pointer (or reference) to another
instance of the same structure.
• Think of it like a train, where each train coach is connected to the next one. Similarly, in programming, one
structure can point to another of the same type, helping us create linked lists, trees, and graphs.These are
commonly used for creating dynamic and linked data structures like linked lists, trees, or graphs.

Key Features:
• Contains a pointer to its own type. struct StructureName {
• Allows the creation of dynamic data structures. dataType member;
• Commonly used in linked data structures. struct StructureName *pointerToSameStructure;
};
Example
#include <stdio.h> // Assign values and link nodes
#include <stdlib.h> node1->data = 10;
node1->next = node2;
node2->data = 20;
// Define a self-referential structure
node2->next = NULL;
struct Node { // Display the list
int data; struct Node *current = node1;
struct Node *next; // Pointer to the next node while (current != NULL) {
}; printf("Data: %d\n", current->data);
int main() { current = current->next;
// Create two nodes }
struct Node *node1 = (struct Node // Free memory
*)malloc(sizeof(struct Node)); free(node1);
free(node2);
struct Node *node2 = (struct Node
*)malloc(sizeof(struct Node)); return 0;
}
Structure Padding
• Structure padding is a mechanism where the compiler adds extra bytes (padding) between structure members to
align them according to the system's word size.
• This ensures better performance by aligning data in memory.

Key Features:
• Added bytes improve data access speed.
• Padding is compiler and architecture-dependent.
• Can lead to wasted memory.

Structure padding happens automatically, no specific syntax is needed


Example
#include <stdio.h> Explanation:
On a 32-bit system, int must align to 4 bytes.
struct Padded { char occupies 1 byte.
char a; // 1 byte The compiler adds padding bytes to ensure alignment:
1 byte for a + 3 bytes padding to align b.
int b; // 4 bytes 4 bytes for b.
char c; // 1 byte 1 byte for c + 3 bytes padding for alignmen
};

int main() {
printf("Size of struct Padded: %zu bytes\n", Real-World Example:
sizeof(struct Padded)); When working with hardware devices or protocols where data needs to
return 0; align with memory boundaries for efficiency.
}
Example
Avoiding Padding:
You can use the #pragma pack directive to avoid padding (not always recommended for performance reasons):

#pragma pack(1) // Disable padding


struct Compact {
char a;
int b;
char c;
};
#pragma pack() // Re-enable default alignment

int main() {
printf("Size of struct Compact: %zu bytes\n", sizeof(struct Compact));
return 0;
}
Pointers in Structures
• A pointer in a structure is a member of a structure that holds the memory address of a specific data type (e.g.,
an integer, a float, a structure, or even another structure).
• Pointers in structures are very useful when dynamically managing memory or linking multiple structures
together. Below, you'll find a detailed explanation, syntax, and example in simple terms.

struct StructName { Key Points


int *ptr; // Pointer to an integer • Pointer Member: A pointer inside a structure can store the address of
float *fptr; // Pointer to a float variables or arrays.
char *str; // Pointer to a • Dynamic Allocation: You can dynamically allocate memory to these
character array (string) pointer members during runtime using malloc() or calloc().
}; • Accessing Pointer Members:
• If you have a structure variable, use the dot operator (.) to access
its members.
• If you have a pointer to a structure, use the arrow operator (->) to
access its members.
Example
#include <stdio.h> // Allocate memory for the name and marks dynamically // Display student details
#include <stdlib.h> printf("\nStudent Details:\n");
s.name = (char *)malloc(50 * sizeof(char)); // Allocate printf("Name: %s\n", s.name);
// Define a structure with a pointer memory for a string
printf("Marks: %d\n", *s.marks);
struct Student {
char *name; s.marks = (int *)malloc(sizeof(int)); // Allocate memory for an
integer // Free allocated memory
int *marks; free(s.name);
}; // Input student details free(s.marks);
printf("Enter student name: ");
int main() { scanf("%s", s.name); // Store the name in dynamically return 0;
struct Student s; allocated memory
}
printf("Enter student marks: ");
scanf("%d", s.marks); // Store marks in dynamically
allocated memory
Unions
• A union is a user-defined data type in C that allows storing different data types in the same memory location.
• Unlike a structure, where each member gets its memory, all members of a union share the same memory.
• This means that a union can hold only one value at a time, even if it has multiple members.

Declaration of a Union : Example :


union Data {
union UnionName { int i;
dataType member1; float f;
dataType member2; char str[20];
... };
};
Unions (Conti...)

Initialization of a Union : You can initialize a union when declaring it. However, since all members share the
same memory, initializing one member overwrites any previously stored value.
union UnionName varName = {value}; union Data d1;
d1.i = 42; // Assigning to the integer member
d1.f = 3.14; // Overwrites the integer member
strcpy(d1.str, "Hello"); // Overwrites the float member
You can initialize a union directly during declaration:

union Data d2 = {42}; // Initialize integer


Bitfields in Unions

Bitfields in Unions : Bitfields are a way to specify that a member of a structure or union should occupy a specific
number of bits in memory, rather than the default size for its type.
This is often used when working with hardware, protocols, or memory optimization.

Syntax :
struct {
unsigned int bit1 : 1; // 1 bit
unsigned int bit2 : 2; // 2 bits
unsigned int bit3 : 3; // 3 bits
}; union Data d1;
d1.i = 42; // Assigning to the integer member
d1.f = 3.14; // Overwrites the integer member
strcpy(d1.str, "Hello"); // Overwrites the float member
Example
union Flags {
struct {
unsigned int option1 : 1;
unsigned int option2 : 1;
unsigned int option3 : 1;
} bits;
unsigned int allOptions;
};

int main() {
union Flags f;
f.bits.option1 = 1; // Enable option1
f.bits.option2 = 0; // Disable option2
f.bits.option3 = 1; // Enable option3

printf("All options as bits: %d\n", f.allOptions);


return 0;
}
Example of Bitfields
#include <stdio.h>
// Setting status
union DeviceStatus { device.statusBits.powerOn = 1; // Device is powered on
struct { device.statusBits.error = 0; // No error
unsigned int powerOn : 1; device.statusBits.batteryLow = 1; // Battery is low
unsigned int error : 1;
unsigned int batteryLow : 1; // Viewing status
} statusBits; printf("Power On: %u\n", device.statusBits.powerOn);
unsigned int allStatus; // To view all status as a single integer printf("Error: %u\n", device.statusBits.error);
}; printf("Battery Low: %u\n", device.statusBits.batteryLow);

int main() { // Combined status


union DeviceStatus device; printf("All Status Bits: %u\n", device.allStatus);

return 0;
}
What is typedef ?
• In simple terms, typedef is a keyword in C that allows you to create a new name (or alias) for an existing data
type.
• Think of it as giving a nickname to a data type to make your code easier to read and understand.

Why Use typedef?


• Simplifies complex data types: You can give a shorter, more understandable name to complex types like
pointers or structures.
• Improves code readability: Makes the code easier to understand for others (and yourself).
• Consistency: Helps maintain consistent naming for specific types.

Syntax : typedef existing_type new_name;


Example

Simple Type Alias Using typedef with Structures


#include <stdio.h> #include <stdio.h>
typedef struct {
typedef unsigned int uint; // Creating an alias for unsigned int int id;
char name[50];
int main() { } Student; // Now, 'Student' is an alias for the struct
uint age = 25; // Now, you can use 'uint' instead of 'unsigned int'
printf("Age: %u\n", age); int main() {
return 0; Student s1; // No need to write 'struct'
} s1.id = 1;
strcpy(s1.name, "Dhruv");
printf("ID: %d, Name: %s\n", s1.id, s1.name);
return 0;
}
Example
Typedef with Pointers Real-World Example : Program for a hospital system
#include <stdio.h> #include <stdio.h>
typedef struct {
typedef int* IntPtr; // Creating an alias for 'int*' int day;
int month;
int main() { int year;
IntPtr ptr1, ptr2; // Both are now pointers to integers } Date; // Alias for the date structure
return 0;
} int main() {
Date today = {2, 2, 2025}; // Declaring a Date variable
printf("Today's date: %02d/%02d/%d\n", today.day,
today.month, today.year);
return 0;
}
Key Points
• typedef does not create new data types; it only creates an alias for existing ones.

• It is mainly used for :


• Simplifying complex types.
• Improving code readability.
• Working with structures and pointers.

You might also like