Introduction This article talks about Structures in C/C++. Background Definition Structure is a collection of variables of potentially different types, grouped together under a single name, for ease of handling. Advantages Structure helps to organise complicated data as it allows to encapsulate group of related variables under a single unit. structures make program modular, easier to modify and make things compact Declaraing a Structure Structure is declared by using the keyword struct followed by structure name, also called as tag. Then the structure members (variables) are defined with their type and variable names inside flower braces {} , ended with a semicolon ";". Example: struct EmployeeRecord { int empId; char * name; float salary; }; Here EmployeeRecord is the name of the structure. It contains 3 different variables as shown above. Defining a structure variable It is simlar to any basic data type declaration. Here data type is the structure variable. We can define a structure variable in below ways along with structure declaration: 1. struct EmployeeRecord { int empId; char * name; float salary; }; struct EmployeeRecord rec1, rec2; 2. Declare the structure using typedef and then use the structure name/tag alone to define it's variables as below: typedef struct EmployeeRecord { int empId; char * name; float salary; }; EmployeeRecord rec1, rec2; Characteristics 1. Declaration of a structure gives the template for the structure or gives a customized data type. Whereas variable of it's type reserves the storage. 2. Variables declared inside a structure are called it's members. 3. A member of a structure is refered or can be accessed as below structVarName.member1 or structVarName->member1 in case structVarName is a pointer to a Struct 4. We can have the same name of a member of a structure as non-member or member of another structure in an application. For Example: struct EmployeeRecord { int empId; char * name; }; struct Salary { int empId; float basic float variablePay; }; Here in these structures, name of the member empId is same. 5. Structures can not be compared 6. Can do below operations on a Structure Can be copied, assigned to, passed to a function as arguments Can be returned by a function We can take it's address and thus use pointers of that type Access it's members 7. Structures can be nested. For Example: struct Salary { float basic; float variablePay; }; struct EmployeeRecord { int empId; char * name; struct Salary sal; }; Here we can see, struct Salary is member of another structure called EmployeeRecord. So,we can access basic of an Employee as EmployeeRecord.sal.basic; Initializing a Structure A structure can be initilized by following it's definition with a list of initializers for the members as below: struct EmployeeRecord emp1 = { 100, "mridula", 10,000}; By default structure members are initialized with garbage values. The elements in the aggregate that are not given initilizers are default initialized according to their ata type. Also we can initialize all the elements of a Structure with "0" or "NULL" (depneding on their dayatype) value by just assigning it with an empty {} like below. struct EmployeeRecord emp1 = {}; Example 1: The code Code: #include<iostream.h> class EmployeeRecordC { int data; int sal; public: EmployeeRecordC() { cout<<endl; cout<<"Class::data := "<<data<<endl; cout<<"Class::sal := "<<sal<<endl; }; ~EmployeeRecordC(){}; }; int main() { typedef struct { int data; int sal; }EmployeeRecordS; EmployeeRecordS emp1; cout<<"Default Structure EmployeeRecordS member values\n"; cout<<endl; cout<<"Struct::data :="<<emp1.data<<endl; cout<<"Struct::sal :="<<emp1.sal<<endl; EmployeeRecordS emp2={}; cout<<endl; cout<<"Structure EmployeeRecordS member values when initilized with {} \n"; cout<<endl; cout<<"Struct::data :="<<emp2.data<<endl; cout<<"Struct::sal :="<<emp2.sal<<endl; cout<<endl; cout<<"Class data member values\n"; EmployeeRecordC employee1; return(0); } ./a.out Default Structure EmployeeRecordS member values Struct::data :=4 Struct::sal :=-4265828 Structure EmployeeRecordS member values when initilized with {} Struct::data :=0 Struct::sal :=0 Class data member values Class::data := -4265936 Class::sal := 163952 Structure as a Function argument: A structure can be passed using below ways as argument to a function: Passing it's members seperately Passing by Value Passing by it's Pointer Passing by it's Reference Example 2: The code Code: #include<iostream.h> struct EmployeeRecord { int empId; char name[20]; float salary; }; void displayNameOfEmp(char empName[20]) { cout<<"Name of EmloyeeRecord\n"; cout<<"Name := "<<empName<<endl; } void print1(struct EmployeeRecord emp) { cout<<"Details of EmloyeeRecord\n"; cout<<"EmployeeRecord::empId := "<<emp.empId<<endl; cout<<"EmployeeRecord::name := "<<emp.name<<endl; cout<<"EmployeeRecord::salary :="<<emp.salary<<endl; } void print2(struct EmployeeRecord *empPtr) { cout<<"Details of EmloyeeRecord\n"; cout<<"EmployeeRecord::empId := "<<empPtr->empId<<endl; cout<<"EmployeeRecord::name := "<<empPtr->name<<endl; cout<<"EmployeeRecord::salary :="<<empPtr->salary<<endl; } void print3(struct EmployeeRecord &empRef) { cout<<"Details of EmloyeeRecord\n"; cout<<"EmployeeRecord::empId := "<<empRef.empId<<endl; cout<<"EmployeeRecord::name := "<<empRef.name<<endl; cout<<"EmployeeRecord::salary :="<<empRef.salary<<endl; } int main() { struct EmployeeRecord emp; emp.empId=12345; strcpy(emp.name,"Mridula"); emp.salary=10507.5; cout<<"Pass Structure member as Argument to a function...\n"; displayNameOfEmp(emp.name); cout<<endl; cout<<"Pass Structure by value as Argument to a function...\n"; print1(emp); cout<<endl; cout<<"Pass Structure Pointer as Argument to a function...\n"; print2(&emp); cout<<endl; cout<<"Pass Structure Reference as Argument to a function...\n"; print3(emp); return(0); } ./a.out Pass Structure member as Argument to a function... Name of EmloyeeRecord Name := Mridula Pass Structure by value as Argument to a function... Details of EmloyeeRecord EmployeeRecord::empId := 12345 EmployeeRecord::name := Mridula EmployeeRecord::salary :=10507.5 Pass Structure Pointer as Argument to a function... Details of EmloyeeRecord EmployeeRecord::empId := 12345 EmployeeRecord::name := Mridula EmployeeRecord::salary :=10507.5 Pass Structure Reference as Argument to a function... Details of EmloyeeRecord EmployeeRecord::empId := 12345 EmployeeRecord::name := Mridula EmployeeRecord::salary :=10507.5 Structure as a Return Type of a Function Example 3: The code Code: #include <iostream.h> struct Allowance { int hraAl; int medicalAl; }; struct Salary { int basic; struct Allowance al; }; struct EmployeeRecord { int empId; char name[20]; struct Salary sal; }; Allowance computeAllowance(int basic) { Allowance resAl; resAl.hraAl = basic*12/100; resAl.medicalAl = basic*20/100; return (resAl); } int main() { cout<<"Structure as a return type of a function ...\n"; EmployeeRecord emp1 = {10, "Mridula"}; emp1.sal.basic = 10000; emp1.sal.al = computeAllowance(emp1.sal.basic); cout<<endl; cout << "EmpId :="<<emp1.empId<<endl << "Name :="<<emp1.name<<endl << "Salary.HraAllowance :="<<emp1.sal.al.hraAl<<endl << "Salary.MedicalAllowance :="<<emp1.sal.al.medicalAl << endl; return(0); } ./a.out Structure as a return type of a function ... EmpId :=10 Name :=Mridula Salary.HraAllowance :=1200 Salary.MedicalAllowance :=2000 In this example, we can also see nested structure and it's usage. Same way we can even return Pointer or Reference to a Structure. Assigning one structure to another structure We can Assign an existing structure value to another new structure to initialize it. Example 4: The code Code: #include <iostream.h> struct EmployeeRecord { int empId; char name[20]; float salary; }; int main() { EmployeeRecord emp1 = { 10, "Mridula", 10000.0 }; cout<<"emp1 structure details ...\n"; cout << "EmpId :="<<emp1.empId<<endl << "Name :="<<emp1.name<<endl << "Salary :="<<emp1.salary << endl; cout<<"\nAssigning one structure to another i.e. emp1 to emp2...\n"; EmployeeRecord emp2 = emp1; emp2.empId = 100; cout<<"\nemp2 structure details ...\n"; cout << "EmpId :="<<emp2.empId<<endl << "Name :="<<emp2.name<<endl << "Salary :="<<emp2.salary << endl; return 0; } ./a.out emp1 structure details ... EmpId :=10 Name :=Mridula Salary :=10000 Assigning one structure to another i.e. emp1 to emp2... emp2 structure details ... EmpId :=100 Name :=Mridula Salary :=10000 Here in this example, emp2 is initialized with emp1 details and then later it's empId is modified. Array of structures This example shows an Array of structures. Also Pointer to that Array of structures. Example 5: The code Code: #include <iostream.h> const int SIZE = 3; typedef struct EmployeeRecord{ int empId; char name[20]; float salary; }; int main() { int n; EmployeeRecord empArray[SIZE], *strPtr; for(n=0; n<SIZE; n++) { cout << endl; cout << "Enter empId := "; cin >> empArray[n].empId; cout << "Enter Name := "; cin >> empArray[n].name; cout << "Enter Salary := "; cin >> empArray[n].salary; } cout<<"\nRecords in EmployeeRecord Array using (ptr to Array ) are ...\n"; strPtr = empArray; for(n=0; strPtr<(empArray+SIZE); strPtr++, n++) { cout << "EmpId := " << empArray[n].empId <<" "; cout << "Name := " << empArray[n].name <<" "; cout << "Salary := " << empArray[n].salary << endl; } return 0; } ./a.out Enter empId := 1 Enter Name := Mridula Enter Salary := 10500 Enter empId := 2 Enter Name := Meena Enter Salary := 20500 Enter empId := 3 Enter Name := Milana Enter Salary := 30600 Records in EmployeeRecord Array using (ptr to Array ) are ... EmpId := 1 Name := Mridula Salary := 10500 EmpId := 2 Name := Meena Salary := 20500 EmpId := 3 Name := Milana Salary := 30600 So here, by incrementing strPtr gives the next record in that EmployeeRecord array. Difference between C and C++ structures All data members are public in c where as they are private in C++. In c, structure is defined as struct struct-name struct_variable name, if we have not defined stucture with typedef. where as in C++ we can do the same with struct-name struct_var_name even without using typedef We cannot have methods in c structure whereas we can have methods in C++ structure. Reasons for using structures Use structures to clarify Data-Relationship When all the Data are structured together, it is easy to understand how they are related and why they are grouped in one data type. Use structures to simplify operations on group of data In applications like protocol-development, working on some related data, then it is more reliable and takes less code, operating on them when they are structured, than operating on them individualy. To reduce maintenance Deletion or adding a new element to an existing structure does not need modifications to many places like where it is used as a whole like as a function parameter, assignment statement etc. This makes maintenance easier.
Note also, that structures in C++ may have virtual and static functions just as classes: Code: struct some_struct { void member_func(){} //member function virtual void foo(){} //virtual function static void bar(){} //static function }; The only difference between structures and classes in C++ is member visibility by default, so the structure in C++ is: Code: class Struct { public: }; But it is not recommended to include virtual functions inside structures, because for another programmer it is clear that the structure may be reset by Code: memset(&structure, 0, sizeof(structure)); but if this structure has virtual functions - zeroing the memory this way will result in runtime error which probably will be hard to find.