Structures
|
Let us see the Student Management System, which stores information of students and allows retrieving, modifying them at operator ease. It has following variables to manipulate student ID [int], student name [string], student address [string], student date-of-birth [int]. Note that all variables are related to single object called student.
Student Management System [using variables] |
main() { int stNo , i ; int std_Id[‘ ‘], std_dob_yy[‘ ‘], std_dob_mm[‘ ‘], std_dob_dd[‘ ‘] ; char std_name[‘ ‘][‘ ‘] , std_addr[‘ ‘][‘ ‘] ;
printf (“Enter No of students to add:”); scanf(“%d” , &stNo );
for(i=0 ; i < stNo ; i++) { printf (“ Enter Student ID: “); scanf (“%d”, &std_id[i] ); printf (“ Enter Student Name: “); scanf (“%s”, &std_name[i] ); printf (“ Enter Student Address: “); scanf (“%s”, &std_address[i] ); printf (“ Enter Student Dob[dd/mm/yyyy]: “); scanf (“%d/%d/%d”, &std_dob_dd[i] , &std_dob_mm[i] , &std_dob_yy[i] ); } …. }//end of main //end of program |
|
Even though all variables are part of student object in code they are loosely connect to each other. This is because arrays are used to store each variable data, which takes only one type of data in it. Such programs are very hard to read, maintain and debug. This is not a good example program of modular type.
The efficient approach is creating a student object with all its attributes and then use that object to manipulate the data. It will be easier to write code, find bugs and understand it too! The C language provides two mechanisms for such object creation called structure and union. Both mechanisms allows user to create user-defined object/data type with different variable types grouped together under single name.
Student Management System [using structure] |
main() { struct date { int day; int month; int year; };
struct student { int id ; char name[‘ ‘] ; char addr[‘ ‘] ; struct date dob; };
int stNo , i ;
//create student object array struct student std[100];
printf (“Enter No of students to add:”); scanf(“%d” , &stNo );
for(i=0 ; i < stNo ; i++) { printf (“ Enter Student ID: “); scanf (“%d”, &std[i].id ); printf (“ Enter Student Name: “); scanf (“%s”, &std[i],name ); printf (“ Enter Student Address: “); scanf (“%s”, &std[i].address ); printf (“ Enter Student Dob[dd mm yyyy]: “); scanf (“%d %d %d”, &std[i].dob.dd , &std[i].dob.mm , &std[i].dob.yy ); } …. }//end of main //end of program |
|
Declaring Structures
The structure is made of many parts: key word struct, tag name, template or body, its objects declaration and template’s terminator symbol semicolon.
There are three steps in constructing and using structures: declare template, create objects from that template, and lastly use or access the objects [not template].
The body of structure is call template, as it acts as standard formatted memory map for all its objects. Whenever new object created, this template reserves set of memory for objects storage.
struct{type member_name_1;type member_name_2;…..type member_name_n;} object1,object2; | struct { int id ; char name[‘ ‘] ; char addr[‘ ‘] ; struct date dob; }std1,std2,std3; |
Declaring & creating structure template & objects in one step |
std1.id = 1234; strcpy(std1.name, “ Michael”); strcpy(std1.addr, “JainCollege”); std1.dob.day = 15; std1.dob.month = 08; std1.dob.year = 1947; | struct student std1 { 1234, Michael, JainCollege, 15, 08, 1947 };
|
struct student std1 = {1234, Michael, JainCollege, 15, 08, 1947 }; | |
printf(“Enter student ID: ”); scanf(“%d”,&std1.id); printf(“Enter student Name: ”); scanf(“%s”,&std1.name); printf(“Enter student Address: ”); scanf(“%s”,&std1.addr); printf(“Enter Date of Birth[dd mm yyyy]: ”); scanf(“%d/%d/%d”, &std1.dob.day, &std1.dob.month, &std1.dob.year);
| |
Different methods of structure initialization. |
The tag name is optional if objects are also declaring at the time of structure creation.
Initializing & Accessing of Structures
Accessing structure fields [they are always part of structure, so refereed along with object name] with the help of dot ‘.’ operator.
The initialization of structure is done at the time of template creation or at object creation or elsewhere in code.
Functions & Structures
Passing Structure Elements to functions is as simple as passing any in-built data type variable. The data type and name of structure element entry will enough to pass them.
displayStudent(int id, char name[10]); //function prototype
main()
{
.....
struct student std1;//create (student type) object
….
displayStudent(std1.id, std1.name);
//call display student info function
.....
}//end of main
//user-defined function implementation
void displayStudent(int s_id, char s_name[25])
{
printf("%d \t %s \n", s_id , s_name );
}
Passing whole structure object to functions is also as simple as passing any in-built data type variable. The data type as struct and name of structure object entry will enough to pass them. The function treats it as student object and accesses all its fields as normally done. However, the passing structure must be declared as global, so that it can be accessed by called function.
struct student { //student struct must be global
......
};
displayStudent(struct student x);
//function prototype
main()
{
struct student std1;//create (student type) object
….
dislayStudent(std1);//display student info to user
....
}//end of main
//user-defined function implementation
void dislayStudent(struct student s)
{
printf("%d %s %s %d-%d-%d \n",
s.id , s.name, s.addr, s.dob.day, s.dob.month, s.dob.year );
}
Returning whole structure object from functions is also as simple as returning any in-built data type variable. Including the name of structure’s object as return data-type in function signature, will enough. However, the passing structure must be declared as global, so that it can be accessed by called code block.
struct student { //student struct must be global
......
};
student getStudentInfo(int id);//function prototype
main()
{
struct student std1;//create (student type) object
….
std1 = getStudentInfo(5);
//get student info by his id=5
printf("%d %s %s %d-%d-%d \n", //display got info
std1.id,std1.name,std1.addr,std1.dob.day,std1.dob.month,std1.dob.year);
....
}//end of main
//user-defined function implementation
student getStudentInfo(int s_id)
{
struct student s; //create student object.
s.id = s_id; //assign received id to object.
strcpy(s.name,”defaultName”);
//fill default values to other members.
......
return(s);
}
Array of Structures
As arrays stores similar data-type variables, declaring array of structures is also possible. Therefore, to store & manipulate 120 students information is very easy if they are declared as array of type student. Accessing them is same as any array element along with structure element dot operator.
struct student
{
int id ;
char name[‘ ‘] ;
char addr[‘ ‘] ;
struct date dob;
} std[100];
.....
std[1].id = 2;
strcpy(std[1].name, “Munna.Micheal”);
Pointers of Structures
The pointer variables are used as member of structure or to refer structure object. The pointer variable with structure can be used to construct a complex data structure such as linked lists, doubly linked lists, binary tree etc.
The syntax to declare structure’s pointer variable to object is as follows:
struct tag_name *variable_name;
The pointer variable accesses its members as following two methods:
(*object_name).field_name = sname ;
The parentheses is necessary as '.' or member operator has high precedence. Alternatively, using arrow operator [made of minus sign & greater than sign] code can access members of structure.
object_name->field_name = sname ;
The code example is as shown below:
main()
{
struct complex
{
int x ;
int y ;
};
struct complex *ptrc1;
//create complex type pointer object
//(*ptrc1).x = 5; (*ptrc1).y = 10;
//get input from user
printf(" Enter Complex No.[real imaginary]:\n" );
scanf("%d %d", &(*ptrc1).x , &(*ptrc1).y );
//display inputted number to user
printf(" %d \t %d \n", ptrc1->x , ptrc1->y );
}//end of main
Unions
|
|
To store such objects where storage sharing is necessary C language provides one mechanism called Union. It is similar to structure, but it’s all elements share longest length for their storage. Hence, the name given Union.
Comparison of struct and union |
|
struct ItemInfo { char sItem ; //1 byte int mItem ; //2 bytes float bItem ; //4 bytes }item;
//total memory reserved by struct template is // 1 + 2 + 4 = 7 bytes per object | union ItemInfo { char sItem ; //1 byte int mItem ; //2 bytes float bItem ; //4 bytes }item;
//total memory reserved by union template is // longest size = 4 bytes per object |
All other processes with union are same as structure type. Creating Union object and then initialzing it at some other place is as shown below:
union ItemInfo item1, item2,item3;
.....
// initializing union member
item1.sItem = 'A';
item2.mItem = 3456;
item3.bItem = 789.2334
It is possible that creating Union object and initialzing it at same instance is as shown below:
//creating union object and initializing it
union ItemInfo item1 = { 'A'};
union ItemInfo item2 = { 3456};
union ItemInfo item3 = { 789.2334};
Bit-fields
Suppose employee information program needs to store sex of the employee in its database, and it should be either male or female only. Then programmer has to declare sex variable as char data type, that takes only one byte.
int sex; //2 bytes memory = 2 x 8 bits = 16 bits
char sex; //1 byte memory = 1 x 8 bits = 8 bits
However, sex data is having information quantity of two: male or female and needs only one bit of memory to store it! [Sex =0 for male and 1 for female].
Since C is mid-level language, it allows programmer to store data in bit level also. That means programmer can specify the variable size in bits also. The syntax is as follows:
modifier data_type variable_name : bitfieldsizenumber;
unsigned int sex:1;
//1 bit is used, If sex=0 male and sex=1 female
unsigned int year:7;
//7 bits are sufficient to store any year value.
Even though bit filed optimizes the code to minimum memory load, they are not recommended in common programming practice. Because not all chips are bit filed addressable and hence code will not be portable in nature. The packing of bits is again machine dependent, either left to right or right to left. This mechanism is widely applied usually in embedded systems where target micro-controller chip is fixed or from same family 8051 or AVR or ARM etc and memory availability is very limited.
One more restriction with bit-field is, the value cannot be directly assigned to it, as it is bit addressable. Code has to read value into a temporary variable and then assign its value to the bit-field.
int s; //temporary variable
//get info from user
printf("Male: 0 Female:1 \? :" );
scanf( "%d", &s ); //store sex value
sex = s ; //transfer sex value to bit-field variable
The bit-field implementation is applied to any variable declaration in program, whether inside function, structure, or union.
typedef: user-defined alias statement
The typedef statement is use when one wants to refer to a variable type by an alternative name, or alias. This is often makes a great convenience for the programmer where application is made of many code files and programmers.
The typedef feature allows users to define new data types that are equivalent to existing data types. Once a user-defined data type has been established, then new variables, arrays, structures, and so on, can be declared in terms of this new data type.
typedef data_type new_type_name;
typedef float real;
//declare float data-type alias, real=float.
real salary, irate, avg;
// salary, irate, avg are all float type now.
The typedef feature makes programme more readable and secured one.
#define 32bit_System #ifdef 32bit_System typedef char items; #elseif typedef int items; #endif ..... items itemId, itemLocation, itemColor;
| uncomment this directive, if system is 64 bit system |
Code file for 32-bit system, all items are 1-byte length and hence char data type is used.
| |
Code file for 64-bit system, all items are 2-byte length and hence int data type is used. | |
Usage of typedef. It makes code more readable, manageable, modular, and portable. |
The typedef feature is particularly convenient when defining structures, since it eliminates the need to repeatedly write struct tag whenever a structure is referenced. As a result, the structure can be referenced more concisely.
Enum: user-defined data type
The enumerated data types helps programmer to write code easily/clearly as they represent integer type value in code.
enum flavours{ sweet, sour, salty=6, pungent, hot, bitter} pickles; actual int values =0 =1 =6 =7 =8 =9 |
enum weekdays{ Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday}; actual int values =1 =2 =3 =4 =5 =6 =7 |
enum colours { red, yellow, green, blue, white, black, ...,}; actual int values =1 =2 =3 =4 =5 =6 |
The declaring enumerated data type is simple as it contains following elements: enum keyword, name, members separated by comma with their position value between flower brackets, and terminator symbol semicolon.
enum user-defined-name { member_name1, m_n2,......};
enum weekdays
{Monday,Tuesday,Wednesday,Thursday,Friday,Saturday, Sunday};
An enumeration is a data-type similar to a structure or a union. Its members are constants that are written as identifiers, though they have signed integer value. The default value of members-of- weekday enum is as follows:
enum weekday { mon , tue , wed , thu , fri , sat };
member value is =0 =1 =2 =3 =4 =5
This can be change to any desired value in any order.
enum weekday { mon=1 , tue , wed , thu , fri , sat };
member value is =1 =2 =3 =4 =5 =6
enum colors {red=1, blue, green=8, violet, pink};
member value is =1 =2 =8 =9 =10
Object creation and accessing its members is done as any structure or union object creation is done, as follows:
//declare weekdays enum data-type
enum weekday { mon , tue , wed , thu , fri , sat };
//create weekdays objects/variables
weekdays day1, day2, day3;
//access each member of enum object’s
int today, lastlogin;
today = day1.mon; //today=0
lastlogin = day2.fri; //lastlogin=4
Though the C compiler stores enumerated values as integer constants, enum variables are a distinct type, and they should not be thought of as ints.
Previous Page | Main Contents | Next Page |
No comments:
Post a Comment