User Defined Data Types in C++

User-defined datatypes in C++

A user-defined data type is a special type created and customized by the user through existing predefined types

User defined types in C++

Structure

  • An array can store elements of one data type at a time
    Example: int a[5] can hold only integer elements
  • Definition of Structure: A structure is a collection of multiple variables of different data types grouped under a single name for convenience handling
  • The members of structures can be ordinary variables, pointers, arrays or even another structure

Declaring Structures:

Using struct keyword structures are created

struct 
{
  member 1;
  member 2;
  ....;
  member n;
};

Creating a structure to store student record

struct student  // student as structure name
{
//structure members
int sid;
char sname[20];
float marks, attendance;
};

Allocating Memory to structure

Declaration of structure will allocate no memory, memory is allocated by creating structure variable

struct student s1;
User defined Data types in Cpp

C++ program to demonstrate declaration, initialization, and access to structure types

The member elements of the structure can be accessed using 2 operators

  1. Member access operator(.)
  2. Pointer to member access operator(->)
#include <iostream>
#include <string.h>
using namespace std;

struct student //student as structure name
{
int id;
char name[20];
float marks,attendance;
};//no memory allocated as of now

int main()
{

struct student s1 = {66,"Ronaldo",75.0,50.0}; //memory allocated
struct student s2; //memory allocated now
struct student s3; //memory allocated now

//Method 2 of initialisation
cout << "Enter Student ID for S2:" << endl;
cin >> s2.id;

cout << "\nEnter Student Name for S2:" << endl;
cin >> s2.name;

cout << "\nEnter Marks for S2:" << endl;
cin >> s2.marks;

cout << "\nEnter attendance for S2:" << endl;
cin >> s2.attendance;

//Method 3 of initilisation
s3.id = 36;
s3.marks = 79;
strcpy(s3.name, "Neymar");
s3.attendance = 200;

//acessing structure members
cout << "\n\nDetails of Student 1:\n";

cout << "Name: " << s1.name << "\nID: "
<< s1.id << "\nMarks: "<< s1.marks << "\nAttendance: " << s1.attendance;

return 0;
}

Output

Enter Student ID for S2: 
100
Enter Student Name for S2:
Atul
Enter Marks for S2:
90
Enter attendance for S2:
100

Details of Student 1:

Name: Ronaldo
ID: 66
Marks: 75
Attendance: 50

Array of Structures

  • We can also make an array of structures. In the first example in structures, we stored the data of 3 students. Now suppose we need to store the data of 100 such students, Declaring 100 separate variables of the structure is definitely not a good option. For that, we need to create an array of structures.
  • struct student s1, s2, s3… s100; can be written struct s[100];

An array of structure that stores records of 5 students

#include<iostream>
using namespace std;
struct student 
{ 
  int roll_no; 
  string name; 
  int phone_number;
};

int main()
{
  struct student stud[5];  //array of structure variables
  int i;

  for(i = 0; i < 5; i++)
  { 
    //taking values from user
    cout << "Student " << i + 1 << endl;
    
    cout << "Enter roll no: " << endl;
    cin >> stud[i].roll_no;
    
    cout << "Enter name: " << endl;
    cin >> stud[i].name;
    
    cout << "Enter phone number: " << endl;
    cin >> stud[i].phone_number;
  }

  for(i = 0; i < 5; i++)
  { 
    //printing values
    cout << "\nStudent " << i + 1 << endl;

    //accessing struture members
    cout << "\nRoll no : " << stud[i].roll_no << endl;
    cout << "Name : " << stud[i].name << endl;
    cout << "Phone no : " << stud[i].phone_number << endl;
  }
  return 0;
}

Output –

Printing the first 2 only

Student 1 

Enter roll no: 1 
Enter name: John 
Enter phone number: 890780109 

Student 2 

Enter roll no: 2 
Enter name: Kallis 
Enter phone number: 780182912 

Student 1 
Roll no : 1 
Name : John 
Phone no : 890780109 

Student 2 
Roll no : 2 
Name : Kallis 
Phone no : 780182912

Local and global structure

Defining a structure inside the main can be accessible only inside the main but not outs whereas as structures defined outside can be accessed anywhere in the program

#include<iostream>
using namespace std;

int main() {
struct emp
{
int id;
char ename[20];
int sal;
};

emp e1, e2;
}

//outside main declared in a function
void abc()
{
//error:elements are not accesible outside main
emp e3,e4;
}

Structure within Structure:

One Structure variable acting as a member element of another structure is called a structure to structure

struct X
{
  int a;
};

struct Y
{
  int b;

  //structure variable x as a member of struct Y };
  struct X x;

int main()
{
  struct Y y;

//indirect initilaisation by through x y.b = 10; y.x.a = 20 }

Nested Structures:

A structure can contain another structure, the structure can be nested just like a loop

#include <iostream>
#include <string.h>
using namespace std;
struct emp //structure declaration { int eno;
char ename[20]; struct fac //structure inside a structure { char pno[20]; char sub[20]; }f; //must declare structure variable here only };
int main() { struct emp e; //24 bytes e.eno=66; strcpy(e.ename, "trish"); strcpy(e.f.pno, "Bzc"); //iniliasting a nested structure strcpy(e.f.sub, "Azc"); }

Copying Structures:

We can copy one structure into another by assignment of structure variables

#include <iostream>
using namespace std;
struct student{ 
  long long int roll_no; 
  string name; 
  int phone_number;
};

int main()
{
  struct student p1 = {160815733066,"trishaank",12345};
  struct student p2;
  p2 = p1;//copying structures

  cout << "roll no : " << p2.roll_no << endl;  //accessing
  cout << "name : " << p2.name << endl;
  cout << "phone number : " << p2.phone_number << endl;
}

Output

roll no : 160815733066
name : trishaank
phone number : 12345

Pointers to Structures

Like we have pointers to int, char and other data-types, we also have pointers pointing to structures. These pointers are called structure pointers.

Example demonstrating structure pointer.

#include<iostream>
using namespace std;

struct student{
    
    string name;
    int roll_no;
};

int main()
{
    struct student stud = {"Micheal Scott", 66};
    struct student *ptr;  //declaring structure pointer
    ptr = &stud; //initialsing structure pointer
    
    cout << stud.name << endl;
    cout << ptr->name << endl;  //access using ->operator
    
    return 0;
}

Output

Micheal Scott
Micheal Scott

Passing Structure to function

There are two methods by which we can pass structures to functions.

Passing by Value in structures

In this, we pass a structure variable as an argument to a function.

#include<iostream>
using namespace std;

struct student
{
int roll_no;
string name;
int phone_number;
};

void display(struct student st) //structure variable in function
{
cout << "Roll no : " << st.roll_no << endl;
cout << "Name : " << st.name << endl;
cout << "Phone no : " << st.phone_number << endl;
}

int main()
{
struct student s; //memory allocated

s.roll_no = 66;
s.name = "Jim Halpert";
s.phone_number = 756888;

display(s); // function call with structure variable

return 0;
}

Output

Roll no : 66 Name : 3sh Phone no : 756888
  •  Just as we pass any other variable to a function, we passed the structure variable ‘s’ to a function ‘display’.
  • Now, while defining the function, we passed a copy of the variable ‘s’ as its argument with ‘struct student’ written before it, because the variable which we have passed is of type structure named student

Passing by Reference in structures

  • In passing by reference, the address of a structure variable is passed to a function.
  • In this, if we change the structure variable which is inside the function, the original structure variable which is used for calling the function changes. This was not the case in calling by value.
#include<iostream>
using namespace std;

struct student
{
int roll_no;
string name;
int phone_number;
};

void display(struct student *st) //structure pointer in function definition
{
cout << "Roll no : " << st -> roll_no << endl;
cout << "Name : " << st -> name << endl;
cout << "Phone no : " << st -> phone_number << endl;
}

int main()
{
struct student s;

s.roll_no = 66;
s.name = "Ron";
s.phone_number = 12345;

display(&s); //passing address of struct variable in function call

return 0;
}

Output

Roll no : 66
Name : 3sh
Phone no : 12345
  • This case is similar to the previous one, the only difference is that this time, we are passing the address of the structure variable to the function.
  • While declaring the function, we passed the pointer of the copy ‘st’ of the structure variable ‘s’ in its parameter.
  • Try to change the value of the variables inside the function in both the cases and see the changes in the actual and formal parameters

Unions in C++

Usage of the union is exactly the same as Structure only difference is the size of the structure is the sum of sizes of types of all members whereas memory allocated for the union is the size of the member which is having a larger size than all other members

  • Before Introducing, structures Unions were introduced where is a severe concern for memory but nowadays memory is cheaper and unions are no more used
  • Union definition: A union is Collection of different types where each element can be accessed one at a time
  • It is based on the common memory mechanism: A single memory space is shared by all members of the union one at a time
#include <iostream>
using namespace std;

union demo //declaring union
{
int a;
float b;

}d;
// 4 bytes allocated

int main()
{
//Whole union memory i.e. 4 bytes allocated to a
d.a = 12;

cout << "a: " << d.a << endl; //prints 12
cout << "b: " << d.b << endl; //will print garbage

//Union memory deallocated from int a & allocated to float b
d.b = 14.5;

cout << "a: " << d.a << endl; //will print garbage
cout << "b: " << d.b << endl; //prints 14.5

cout << "\nMemory allocated for this union is "<< sizeof(d) << " bytes" << endl;

return 0;
}

O/P

a: 12 
b: 1.68156e-44

a: 1097334784
b: 14.5

Memory allocated for this union is 4 bytes

  • In the above example size of the union is 4 bytes because among int a and float b, float is larger than int hence .hence size of the float will be the size of the union here
  • As there is only single space, initialization of a member with value makes all members initialize with that value and any changes one member reflect the same change in all the union members
  • If d.a=14 then the value of b also become s14

Enums in C++

Definition: consists of various constants that are just grouped under a single name just to make our codes neat and more readable.

Enumeration

Example: So this becomes an enumeration with name season and Summer, Spring, Winter and Autumn as its elements.

enum is created by keyword andenum the elements separated by ‘comma’ as follows.

enum enum_name
{
  element1,
  element2,
  .......
  elementn
};

Creating enum of type seasons

enum Season{
  //creating enum
  Summer,
  Spring,
  Winter,
  Autumn
};

Here, we have defined an enum with name ‘Season’ and Summer, Spring, Winter and Autumn’ as its elements.

Values of the Members of Enum

  • All the elements of an enum have a value.
  • By default, the value of the first element is 0, that of the second element is 1 and so on.
  • size of enum is the no of elements present in it

Example

enum Season{ Summer, Spring, Winter, Autumn}; //creating an enum
int main()
{
  enum Season s;  // s is a variable with datatype season
  s = Spring;  //initialising enum members
  cout << s << endl;
  cout << "\nsize of enum" << sizeof(s); //4bytes
}

Output

1 size of enum 4 bytes
  • Here, first, we defined an enum named ‘Season’ and declared its variable ‘s’in the main function as we have seen before.
  • The values of Summer, Spring, Winter, and Autumn are 0, 1, 2 and 3 respectively.
  • So, by writing  s = Spring, we assigned a value ‘1’ to the variable ‘s’ since the value of ‘Spring’ is 1.

 Directly print the value of any element of an enum.

enum Season{ Summer, Spring, Winter, Autumn};  //creating a type season
int main()
{
  cout << Winter;  //position ordering is printed
}

Output

2

Customizing the ordering of enum values

Once we change the default value of an enum element, then the values of all the elements after it will also be changed accordingly. An example will make this point clearer.

//customising default values of enum members
enum
Days{ sun, mon, tue = 5, wed, thurs, fri, sat};
int main() { enum Days day; // s is a varible with datatype season
day = thurs;//initialising enum members
cout << day <<endl; cout << day+2 << endl;//In this example, the value of thurs i.e.
//Since we are printing 'day+2' i.e. 7 (=5+2), so the output will be 9

return 0;

}

Output

7
9
  • The default value of sun will be 0, Mon will be 1, tue will be 2 and so on.
  • In the above example, we defined the value of tue as 5. So the values of wed, thurs, fri andsat will become 6, 7, 8 and 9 respectively.
  • There will be no effect on the values of sun and mon which will remain 0 and 1 respectively. Thus the value of thurs i.e. 9 will get printed.

Enum class(Exclusively in C++)

  • On comparison of normal enum values Positions are compared and the output is true
  • ex: if we compare the first element of the enum (say spring) and the first element of another enum (say blue) .it always returns true because positions are compared .we can  overcome this by enum class
  •  unlike enum, enum class compares the values rather than positions

To make an enum class, we simply have to add the keyword class after the keyword enum.

enum class Season
{
  Summer, Spring, Winter, Autumn
};

We made our enum Season an enum class by adding the keyword class after the keyword enum. accessing any element (enumerator) of enum class.

Season::Summer

The :: symbol simply means belong to. Here, Summer belongs to the enum class Season and thus cannot be directly accessed anywhere.

We can compare the enumerators which belong to the same enum class only

#include <iostream>
using namespace std;

enum class names{
  trish,
  rishi
};

int main()
{
  names n = names::trish;
  if( n == names::trish )
    cout << "Your name is trish" <<endl;
  else
    cout << "Your name is rishi" << endl;

  return 0;
}

Output

Your name is trish
  • In this example, we compared the enumerators within the enum class ‘names’.
  • Note that enumerators are not converted to integers in the case of enum class.
  • By writing names n = names::trish, we are assigning the colour Blue of enum class names to the variable n. So the condition ( n == names::trish ) became true and “Your name is trish” got printed.
  • In this condition, we compared n and names::trish, both of which belong to the enum class names.

Difference between C and C++ structures

Direct Initialization: We cannot directly initialize structure data members in C but we can do it in C++.

struct Record 
{ int x = 3; //this type of initialisation not possible in C };

Member functions inside the structure: Structures in C cannot have member functions inside the structure but Structures in C++ can have member functions along with data members.

struct demo
{
int a;
void display() //function inside structure { cout<<"My name is Trishaank"<< endl;
} }T;

int main()
{
  T.get_data();

  return 0;
}

Using struct keyword:

In C, we need to use the struct to declare a struct variable. In C++, a struct is optional in the variable declaration.

struct emp e;
or
emp e  //valid and same as above in C++

C structures cannot have static members, constructors, data hiding, constructors but is allowed in C++.

struct sample 
{ static int a; //static memer inside structure int roll;
Student(int x) //constructor inside structure { roll = x; } };
int main() { struct Student s(3); cout << s.x; }

sizeof operator:

This operator will assign 0 for an empty structure in C whereas 1 for an empty structure in C++.

// empty structure
struct Record
{
  //empty
}r;
int main() { cout<<sizeof(r); // 1 in C++ and 0 in C }

Difference between structure and union

Structure
  • Members do not share memory in a structure.
  • Any member can be retrieved at any time in a structure.
  • Several members of a structure can beinitialized 
  • Size of the structure is equal to the sum of the size of each member.
  • Altering the value of one member will not affect the value of another.
  • Stores different values for all the members.
Union
  • Members share the memory space in a union.
  • Only one member can be accessed at a time in a union.
  • Only the first member can be initialized
  • Size of the union is equal to the size of the largest member.
  • Change in value of one member will affect other member values.
  • Stores same value for all the members.