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

Lecture 3 - C Structure

asd

Uploaded by

toprakcihalil0
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Lecture 3 - C Structure

asd

Uploaded by

toprakcihalil0
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

SE 2005

DATA
STRUCTURES
C Structure
WHAT IS STRUCTURE?
• Structures are derived data types (derived from primitive data types such as int
and float) that we use in order to define a collection of similar or different data
types under one same name.
– similar to a record
– may contain variables of many different data types—in contrast to arrays,
which contain only elements of the same data type
EXAMPLE
Suppose you want to keep track of your books in a library.

A new
data type

The size of allocated memory is at least the sum of sizes of


all data members
STRUCTURE DECLARATION To declare a structure, you must use
the struct statement which defines a
new data type, with more than one
• Syntax of struct: struct structureName member.
{
Structure declaration do not dataType member1; is called structure tag which is is
reserve any space in dataType member2; optional
memory; rather, each definition ...
creates a new data type that’s }; Each variable name declared within a
structure is called a member of the
used to declare variables and
structure
conveys to the C compiler
how the structure would be Each structure definition must end
laid out in the memory. with a semicolon (;)

• Example
Good Programming
Practice
Always provide a structure tag name
when creating a structure type.

The structure tag name is required for


declaring new variables of the
structure type later in the program.
DECLARING STRUCTURE VARIABLES
• Like any other data type, memory is allocated for the structure when we declare a
variable of the structure (struct Book book1).
– We can't use structure definition in any way unless we declare structure variables.

• There are 2 ways to create a variable :


– Inside a function which is local declaration
• only that function can use the structure
– Outside the function which is global declaration
• any function can use it

• There is no difference in the way memory is allocated or how the data members are
accessed through the variables in both cases.
DECLARING STRUCTURE VARIABLES
If number of variables
If number of variables
are not fixed, use this
are fixed, use this one.
one. It provides you
1. Inside a function: It saves your code to
the flexibility to
struct book declare a variable in
declare the structure
{ main() function.
variable many times.
char book_name[30];
char author[30];
int book_id; 2. Outside the function:
float price; struct book
}; {
char book_name[30];
int main() char author[30];
{ int book_id;
struct book b; // Here b is a variable of structure book float price;
} } b; // Here b is a variable of structure book.
MEMORY ALLOCATION
• When we declare variables of
the structure, separate memory
is allocated for each variable

• Members of a structure are


stored in the memory in the
order in which they are defined.
(1-r_no, 2-name, 3- course, 4-
fees )
SOME RULES
struct book
• The name of structure and the {
name of a structure member char book_name[30];
char author[30];
should not be the same, but the
int book_id;
member names of two different float price;
structures can be same. };

int main()
• Moreover, structure name and its {
variable name should also be // Here b is a variable of structure book
different. struct book b;
}
HOW TO ACCESS DATA MEMBERS IN
STRUCTURES IN C
• There are basically two ways in order to access the data members in a
structure
– With the help of the structure member operator/ dot symbol (.)
• When the variable is normal type then go for struct to member
operator.

– With the help of structure pointer operator (arrow operator) (->)


• When the variable is pointer type then go for pointer to member
operator.
INITIALIZING STRUCTURES

If there are fewer initializers in the list than


members in the structure, the remaining
members are automatically initialized to 0
(or NULL if the member is a pointer).
struct Student To initialize a structure in order,
{ follow the variable name in the
float height; definition with an equals sign
int weight; and a brace-enclosed, comma-
int age; separated list of initializers
};

//Way 1 Hint: Structure variables defined


struct Student s1 = { 180.75 , 73, 23 }; This feature has
been added outside a function definition (i.e.,
in C99 standard. externally) are initialized to 0 or
//Way 2 NULL if they’re not explicitly
struct Student s1 = {. height = 180.75, . weight = 73, . age = 23};
initialized in the external
definition
//Way 3
struct Student s1;

s1.height = 182.5 ;
s1.weight = 65;
s1.age = 20;
EXAMPLE
• Structure members cannot be initialized with declaration

struct Point
{
int x = 0; // COMPILER ERROR: cannot initialize members here
int y = 0; // COMPILER ERROR: cannot initialize members here
};

WHY?

When a datatype is declared, no memory is allocated for it.


Memory is allocated only when variables are created
#include <stdio.h> #include <stdio.h>
struct person
struct person {
{ int age;
int age; float weight; the address
float weight; }; of person1 is stored in
}; the personPtr
int main() pointer
int main() {
{ struct person *personPtr, person1;
struct person person1; personPtr = &person1;

printf("Enter age: "); printf("Enter age: ");


scanf("%d", &person1.age); scanf("%d", &personPtr->age);

printf("Enter weight: "); printf("Enter weight: ");


scanf("%f", &person1.weight); scanf("%f", &personPtr->weight);

printf("Displaying:\n"); printf("Displaying:\n");
printf("Age: %d\n", person1.age); printf("Age: %d\n", personPtr->age);
printf("weight: %f", person1.weight); printf("weight: %f", personPtr->weight);

return 0; return 0; equivalent to


} } (*personPtr).weight
#include <stdio.h> #include <stdio.h>

struct StudentData{ struct StudentData{


char stu_name[20]; char *stu_name;
int stu_id; int stu_id;
int stu_age; int stu_age;
}; strcpy( student.stu_name, "Steve"); };
int main() int main()
{ {
/* student is the variable of structure StudentData*/ /* student is the variable of structure StudentData*/
struct StudentData student ={. stu_name = "Steve"}; struct StudentData student;

/*Assigning the values of each struct member here*/ /*Assigning the values of each struct member here*/
student.stu_id = 1234; student.stu_name = "Steve";
student.stu_age = 30; student.stu_id = 1234;
student.stu_age = 30;
/* Displaying the values of struct members */
printf("Student Name is: %s", student.stu_name); /* Displaying the values of struct members */
printf("\nStudent Id is: %d", student.stu_id); printf("Student Name is: %s", student.stu_name);
printf("\nStudent Age is: %d", student.stu_age); printf("\nStudent Id is: %d", student.stu_id);
return 0; printf("\nStudent Age is: %d", student.stu_age);
} return 0;
}
TYPEDEF IN C
• typedef keyword
– is used to create an alias (alternate) name for data types.
– reduces the length of the code and complexity of data types.
– helps in understanding the program.

• typedef statement does not occupy any memory; it simply defines a new type.
– typedef int INTEGER  then INTEGER is the new name of data type int
– INTEGER num=5;

Syntax typedef <existing_name> <alias_name>


TYPEDEF IN C
By convention, uppercase letters are used for type definitions

struct Distance{ struct Distance{ typedef struct Distance{


int feet; int feet; int feet;

= =
float inch; float inch; float inch;
}; }; } DISTANCE;

int main() { typedef struct Distance DISTANCE; int main() {


struct Distance d1, d2; DISTANCE d1, d2;
} int main() { }
DISTANCE d1, d2;
}
ANOTHER EXAMPLE
Define once,
use throughout
the program

#define MAX_NAME_SIZE 40

typedef struct {
char name[MAX_NAME_SIZE]; Defines a new data type
int rollno; called StudentRecord.
int midterm; Does not declare a
int final; variable.
char letterGrade;
} StudentRecord;

StudentRecord is a type;
StudentRecord s1; s1 is variables
OPERATING WITH STRUCTURE
VARIABLE However, we can perform arithmetic
operations with individual members of one
structure

we cannot
/* Invalid Operations */ • perform I/O, arithmetic
struct student
stu1 + stu2 and relational
{
stu1 - stu2 operators,
char name[20];
stu1 == stu2 • directly scanf or printf
double roll;
stu1 != stu2 etc. structs
char gender;
int marks[5]; we can
/* Valid Operation */ • copy one structure
}stu1,stu2;
stu1 = stu2 variable to another
• have a struct as a function
return type
Compare struct
variables member wise
(NOT
THE WHOLE
STRUCTURE)
NESTED STRUCTURES
• A structure that contains another
structure as its member is called a
nested structure

• The structure can be nested in the following ways.


– By separate structure: we create two structures, but the dependent structure should
be used inside the main structure as a member
– By Embedded structure: This method enables us to declare the structure inside the
structure. Hence, it requires less line of codes but it can not be used in multiple data
structures
// separate structure // Embedded structure

struct Date struct Employee


{ {
int day; int id;
int month; char name[20];
int year;
}; struct Date
{
struct Employee int day;
{ int month;
int id; int year;
char name[20]; } dayTime;
struct Date dayTime;
}emp1; }emp1;

ID NAME
day month year
#include<stdio.h>
struct address {
char city[20];
int pin;
char phone[14];
};
struct employee {
char name[20];
struct address add;
};
void display(struct employee);

void main ()
{
struct employee emp;
printf("Enter employee information?\n");
scanf("%s %s %d %s",emp.name, emp.add.city, &emp.add.pin, emp.add.phone);
display(emp);
}
void display(struct employee emp)
{
printf("Printing the details....\n");
printf("%s %s %d %s",emp.name, emp.add.city, emp.add.pin, emp.add.phone);
}
ARRAY OF
#include<stdio.h>
struct student {

STRUCTURE
char name[20];
int id;
float marks;
};
void main()
Consider a case, where we need to {
struct student s1,s2,s3, s4, s5;
store the data of 5 students.
printf("Enter the name, id, and marks of student 1 ");
We can store it by using the structure scanf("%s %d %f",s1.name, &s1.id, &s1.marks);
as given right side. printf("Enter the name, id, and marks of student 2 ");
scanf("%s %d %f",s2.name, &s2.id, &s2.marks);
printf("Enter the name, id, and marks of student 3 ");
scanf("%s %d %f",s3.name, &s3.id, &s3.marks);
However, the complexity of the
program will be increased if there printf("Printing the details....\n");
are 200 students. printf("%s %d %f\n",s1.name, s1.id, s1.marks);
printf("%s %d %f\n",s2.name, s2.id, s2.marks);
printf("%s %d %f\n",s3.name, s3.id, s3.marks);
}
ARRAY OF STRUCTURE
• C enables us to declare an array of structures by using which, we can avoid
declaring the different structure variables;

We make a collection containing all the


structures that store the information of
different entities.
#include<stdio.h>
#include <string.h> #include<stdio.h>

struct student{ struct Point


int rollno; {
char name[10]; int x, y;
}; };
int main(){
int i; int main()
struct student st[5]; {
printf("Enter Records of 5 students"); // Create an array of structures
for(i=0;i<5;i++){ struct Point arr[10];
printf("\nEnter Rollno:");
scanf("%d",&st[i].rollno); // Access array members
printf("\nEnter Name:"); arr[0].x = 10;
scanf("%s",&st[i].name); arr[0].y = 20;
}
printf("\nStudent Information List:"); printf("%d %d", arr[0].x, arr[0].y);
for(i=0;i<5;i++){ return 0;
printf("\nRollno:%d, Name:%s",st[i].rollno,st[i].name); }
} 10 20
return 0;
}
If you really want to kick
butt with C,
you need to understand
how C handles memory.
DYNAMIC MEMORY ALLOCATION OF
STRUCTS
Till now, we know how many variables we have derivated from the
structure. Because we use Static memory allocation (Compile time)
What if we know know the sizeof data?

Allocating memory dynamically at run time helps


us to store data without initially knowing the size
of the data at the time we wrote the program.

Look over: https://www.geeksforgeeks.org/static-and-dynamic-memory-allocation-in-c/


DYNAMIC MEMORY ALLOCATION OF
STRUCTS
• The process of allocating memory to the variables during execution of the
program or at run time is known as dynamic memory allocation

equivalent to
new in Java
(and C++)

When we have to dynamically allocate memory for variables in our programs then
pointers are the only way to go!!.
BIG PICTURE OF A RUNNING PROGRAM’S MEMORY
0x7FFFFFFFFFFF
Unused

User Stack Created at runtime

47 bits of address space Shared Libraries Shared among processes

Heap Created at runtime

Read/Write Data
Loaded from the executable
Read-only Code and Data

Unused
0x000000000000

Slide from Alan L. Cox - Memory Allocation


• free memory region;
• The size of the heap keeps changing
• When an overflow condition occurs, the memory allocation
functions mentioned above will return a null pointer. Thus,
whenever you allocate memory using malloc() or calloc(), you
must check the returned pointer before using it.

Local variables

program instructions
and the global variables
free(p)

if (ptr == NULL) {
fprintf(“Out of memory.\n”);
exit(1);
}
DYNAMIC MEMORY ALLOCATION OF
STRUCTS
#include <stdio.h> for(i = 0; i < n; ++i)
#include <stdlib.h> /* for malloc */ {
printf("Enter first name and age respectively: ");
struct person {
int age; // To access members of 1st struct person,
float weight; // ptr->name and ptr->age is used
char name[30];
}; // To access members of 2nd struct person,
// (ptr+1)->name and (ptr+1)->age is used
int main() scanf("%s %d", (ptr+i)->name, &(ptr+i)->age);
{ }
struct person *ptr;
int i, n; printf("Displaying Information:\n");
for(i = 0; i < n; ++i)
printf("Enter the number of persons: "); printf("Name: %s\tAge: %d\n", (ptr+i)->name, (ptr+i)->age);
scanf("%d", &n);
return 0;
// allocating memory for n numbers of struct person }
ptr = (struct person*) malloc(n * sizeof(struct person));
C STRUCTURE AND FUNCTION
• A function may access the members of a structure in three ways
#include <stdio.h>
void display(struct student s) {
struct student { printf("\nDisplaying information\n");
char name[50]; printf("Name: %s", s.name);
int age; printf("\nAge: %d", s.age);
}; }

void display(struct student s);

int main() { Passing a structure


struct student s1; to a function call
by value
printf("Enter name: ");
scanf("%[^\n]%*c", s1.name); //for reading spaces

printf("Enter age: "); Enter name: Bond


scanf("%d", &s1.age); Enter age: 13
display(s1); // passing struct as an argument
Displaying information
Name: Bond
return 0;
Age: 13
}
PASSING STRUCT BY REFERENCE
• Passing a structure to a function call by value is a very inefficient
method especially when the structure is very big or the function is
called frequently.

• Therefore, in such a situation passing and working with pointers may be


more efficient.
void display(struct student* s); //Function Prototype

void display(&s1); //Calling the function

void display(struct student* s) {


printf("Name: %s", s1->name);
printf("\nAge: %d", s1->age);
}
P.S.

When any array is an argument, it is passed by reference

int avg (StudentRec class[MAX]) { ... }

int main (void) {


StudentRec bt01[MAX];
int average;
...
average = avg_midpt(bt01) ;
}

However, for dynamic memory allocation, it is better to use pointers


PASSING STRUCT BY REFERENCE
#include <stdio.h> printf("For second number, \n");
typedef struct Complex printf("Enter real part: ");
{ scanf("%f", &c2.real);
float real; printf("Enter imaginary part: ");
float imag; scanf("%f", &c2.imag);
} complex;
addNumbers(c1, c2, &result);
void addNumbers(complex c1, complex c2, complex *result);
printf("\nresult.real = %.1f\n", result.real);
int main() printf("result.imag = %.1f", result.imag);
{
complex c1, c2, result; return 0;
}
printf("For first number,\n");
printf("Enter real part: "); void addNumbers(complex c1, complex c2, complex *result)
scanf("%f", &c1.real); {
printf("Enter imaginary part: "); result->real = c1.real + c2.real;
scanf("%f", &c1.imag); result->imag = c1.imag + c2.imag;
}
result->real =>(*results).real
result->imag =>(*results).imag
RETURN STRUCT FROM A FUNCTION
#include <stdio.h> struct student getInformation()
struct student{ {
char name[50]; struct student s1;
int age;
}; printf("Enter name: ");
scanf ("%[^\n]%*c", s1.name);
struct student getInformation();
printf("Enter age: ");
int main() scanf("%d", &s1.age);
{
struct student s; return s1;
}
s = getInformation();

printf("\nDisplaying information\n");
printf("Name: %s", s.name);
printf("\nRoll: %d", s.age);

return 0;
}
STRUCTURE PADDING IN C
struct student {
char a;
char b;
int c;
} stud1;

After the creation of an object, a


contiguous block of memory is allocated to
its structure members. First, the memory
will be allocated to the 'a' variable, then 'b'
variable, and then 'c' variable.
What is the size of the
struct student?
STRUCTURE PADDING IN C
struct student Is the size 6 bytes?
{
char a; // 1 byte NO!
char b; // 1 byte
int c; // 4 bytes
WHY?
}

The processor does not read 1 byte at a time. It reads 1 word at a time.

If we have a 32-bit processor, then the processor reads 4


bytes at a time, which means that 1 word is equal to 4 bytes.

If we have a 64-bit processor, then the processor reads 8


bytes at a time, which means that 1 word is equal to 8 bytes.
WHY STRUCTURE PADDING?
struct student
{
char a; // 1 byte
char b; // 1 byte
int c; // 4 bytes
}

The structure occupies the contiguous block of memory as shown in the above diagram
WHY STRUCTURE PADDING?
If we consider the 32-bit architecture,
in one CPU cycle;

one byte of char a,


one byte of char b,
2 bytes of int c (Actually 4 bytes)

can be accessed.

What if we only want to access the variable 'c' We require two cycles

Lower the number of cycles, better is the performance of the CPU. This is an
unnecessary wastage of CPU cycles. Due to this reason, the structure padding
concept was introduced to save the number of CPU cycles. The structure
padding is done automatically by the compiler.
STRUCTURE PADDING IN C
• Structure padding is a concept in C that adds the one or more empty
bytes between the memory addresses to align the data in memory.

• The compiler can use padding and in that case there will be unused
space created between two data members.
– optional

• The padding is done for the alignment of data members which makes the
access to the member faster.
HOW IS STRUCTURE PADDING DONE?

The 'c' variable can be accessed


in a single CPU cycle

After structure padding, the total memory occupied by the structure is 8 bytes.

Although the memory is wasted, the variable can be accessed within a single cycle.
#include <stdio.h>

struct student If we change the order of the variable


{ types, will we obtain the same size?
char a;
char b;
int c;
};

int main()
{
struct student stud1;

// Displaying the size of the structure student.


printf("The size of the student structure is %d", sizeof(stud1));

return 0;
} The size of the student structure is 8
the total memory required is 12 bytes
struct student
{
char name[20];
int roll;
char gender;
int marks[5];
} stu1;
HOW TO AVOID THE STRUCTURE
PADDING IN C?
• The structural padding is an in-built process that is automatically done by the compiler.

• One way to decrease the amount of padding to a possible minimum is by declaring the
member variables in decreasing order of their size.

• Also, We can avoid the structure padding in C in two ways


– Using #pragma pack(1) directive
• It prevents the compiler from padding and removes the unallocated memory.
– Using attribute
HOW TO AVOID THE STRUCTURE
PADDING IN C?
Using #pragma pack(1) directive By using attribute
#include <stdio.h> #include <stdio.h>
#pragma pack(1)
struct base { struct base {
char a; char a;
int c; int c;
char b; char b;
}; }__attribute__((packed)); ;
int main() int main()
{ {
struct base var; struct base var;
printf("The size of the var is : %d", sizeof(var)); printf("The size of the var is : %d", sizeof(var));
return 0; return 0;
} }
SELF-REFERENTIAL STRUCTURE
• Self Referential structures are those structures that have one or more pointers which
point to the same type of structure, as their member.
SELF-REFERENTIAL STRUCTURE
• A variable of a struct type cannot be declared in the definition of that same struct
type.

• However, a pointer to that struct type may be included.

struct stu {
char name[20];
unsigned int age;
char gender;
float marks[5];
struct stu next; // ERROR
struct stu *next; // pointer
};

You might also like