C++ Struct Array Assignment

We have already dealt with arrays. Arrays are used to store similar type of data. Have you ever thought if there is any way to store dissimilar data?

The answer is yes. We use structures to store different types of data. For example, you are a student. Your name is a string and your phone number and roll_no are integers. So, here name, address and phone number are those different types of data. Here, structure comes in the picture.

Defining a Structure


The syntax for structure is:

struct structure_name
{
data-type member-1;
data-type member-2;
data-type member-3;
data-type member-4;
};

In our case, let's name the structure as student. The members of the structure in our case are name, roll_no and phone_number.

So, our structure will look like:

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

Declaration of Structure Variable


Just as we declare variables of type int, char etc, we can declare variables of a structure as well.

Suppose we want to store the roll no, name and phone number of three students. For this, we will define a structure named student (as declared above) and then declare three variables, say p1, p2 and p3 (which will represent the three students respectively) of type 'student'. This declaration will be done in the main function.

struct student
{
    int roll_no;
    std::string name;
    int phone_number;
};
int main()
{
    struct student p1, p2, p3;
    return 0;
}

We can also declare structure variables at the time of defining the structure as follows.

struct student
{
    int roll_no;
    std::string name;
    int phone_number;
}p1, p2, p3;

Now, let's see how to enter the details of each student i.e. roll_no, name and phone number.

Suppose we want to assign a roll number to the first student. For that, we need to access the roll number of the first student. We do this by writing

This means that we use dot (.) to use variables in a structure. p1.roll_no can be understood as roll_no of p1.

Now, let's store the details of all the three students.

Output

#include<iostream>#include<cstring>usingnamespacestd;intmain(){structstudent{introll_no;stringname;intphone_number;};structstudentp1={1,"Brown",123443};structstudentp2,p3;p2.roll_no=2;p2.name="Sam";p2.phone_number=1234567822;p3.roll_no=3;p3.name="Addy";p3.phone_number=1234567844;cout<<"First Student"<<endl;cout<<"roll no : "<<p1.roll_no<<endl;cout<<"name : "<<p1.name<<endl;cout<<"phone no : "<<p1.phone_number<<endl;cout<<"Second Student"<<endl;cout<<"roll no : "<<p2.roll_no<<endl;cout<<"name : "<<p2.name<<endl;cout<<"phone no : "<<p2.phone_number<<endl;cout<<"Third Student"<<endl;cout<<"roll no : "<<p3.roll_no<<endl;cout<<"name : "<<p3.name<<endl;cout<<"phone no : "<<p3.phone_number<<endl;return0;}

First Student
roll no : 1
name : Brown
phone no : 123443
Second Student
roll no : 2
name : Sam
phone no : 1234567822
Third Student
roll no : 3
name : Addy
phone no : 1234567844

struct student p1 = {1,"Brown",123443}; - This line is just to show that we can also initialize a structure in this way.

In the next line, we are just giving values to the variables and printing those.

Structures use continuous memory locations.

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 children. Declaring 100 separate variables of the structure is definitely not a good option. For that, we need to create an array of structures.

Let's see an example for 5 students.

Output

#include<iostream>#include<cstring>usingnamespacestd;structstudent{introll_no;stringname;intphone_number;};intmain(){structstudentstud[5];inti;for(i=0;i<5;i++){//taking values from usercout<<"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 valuescout<<"Student "<<i+1<<endl;cout<<"Roll no : "<<stud[i].roll_no<<endl;cout<<"Name : "<<stud[i].name<<endl;cout<<"Phone no : "<<stud[i].phone_number<<endl;}return0;}

Student 1
Enter roll no
1
Enter name
Sam
Enter phone number
12345345
Student 2
Enter roll no
2
Enter name
Brown
Enter phone number
56793234
Student 3
Enter roll no
3
Enter name
Peter
Enter phone number
54729678
Student 4
Enter roll no
4
Enter name
Addy
Enter phone number
98326265
Student 5
Enter roll no
5
Enter name
Max
Enter phone number
43576476
Student 1
Roll no : 1
Name : Sam
Phone no : 12345345
Student 2
Roll no : 2
Name : Brown
Phone no : 56793234
Student 3
Roll no : 3
Name : Peter
Phone no : 54729678
Student 4
Roll no : 4
Name : Addy
Phone no : 98326265
Student 5
Roll no : 5
Name : Max
Phone no : 43576476

Here we created an array named stud having 5 elements of structure student. Each of the element stores the information of a student. For example, stud[0] stores the information of the first student, stud[1] for the second and so on.

We can also copy two structures at one go.

Output

#include<iostream>#include<cstring>usingnamespacestd;structstudent{introll_no;stringname;intphone_number;};intmain(){structstudentp1={1,"Brown",123443};structstudentp2;p2=p1;cout<<"roll no : "<<p2.roll_no<<endl;cout<<"name : "<<p2.name<<endl;cout<<"phone number : "<<p2.phone_number<<endl;return0;}

roll no : 1
name : Brown
phone number : 123443

We just have to write p1 = p2 and that's it. By writing this, all the elements of p1 will get copied to p2.

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.

Now, how to define a pointer to a structure? The answer is below:

struct structure_name
{
data-type member-1;
data-type member-1;
data-type member-1;
data-type member-1;
};
int main()
{
struct structure_name *ptr;
}

Let's see an example using structure pointer.

struct student *ptr; - We declared 'ptr' as a pointer to the structure student.

ptr = &stud; - We made our pointer ptr to point to the structure variable stud. Thus, 'ptr' now stores the address of the structure variable 'stud'.

This is the same which we do while defining a pointer to any other variable.

cout << ptr->name << ptr->roll_no << endl; - We use -> operator to access the members of a structure using a pointer to that structure.


Structure to Function


We can also pass a structure to a function.

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

  • Passing by Value
  • Passing by Reference

Passing by Value


In this, we pass structure variable as an argument to a function. Let's see an example to make it clearer.

Output

#include<iostream>#include<cstring>usingnamespacestd;structstudent{introll_no;stringname;intphone_number;};voiddisplay(structstudentst){cout<<"Roll no : "<<st.roll_no<<endl;cout<<"Name : "<<st.name<<endl;cout<<"Phone no : "<<st.phone_number<<endl;}intmain(){structstudents;s.roll_no=4;s.name="Ron";s.phone_number=888888;display(s);return0;}

Roll no : 4
Name : Ron
Phone no : 888888

In this example, we are printing roll number, name and phone number of a student using a function. We first declared a structure named student with roll_no, name and phone number as its members and 's' as its variable. Then we assigned the values of roll number, name and phone number to the structure variable s. 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. Finally, in the function, we printed the name, roll number and phone number of the structure variable.

Passing by Reference


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.

Output

#include<iostream>#include<cstring>usingnamespacestd;structstudent{introll_no;stringname;intphone_number;};voiddisplay(structstudent*st){cout<<"Roll no : "<<st->roll_no<<endl;cout<<"Name : "<<st->name<<endl;cout<<"Phone no : "<<st->phone_number<<endl;}intmain(){structstudents;s.roll_no=4;s.name="Ron";s.phone_number=888888;display(&s;);return0;}

Roll no : 4
Name : Ron
Phone no : 888888

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. Since the pointer is of a variable of type structure named student, we wrote 'struct student' before the name of the pointer in the argument of the function. In the function , we accessed the members of the pointer using -> sign as discussed before.

Try to change the value of the variables inside the function in both the cases and see the changes in the real variables.

If you do not practice, you don't deserve to win.
-Andre Agassi

PrevNext









Output

#include<iostream>#include<cstring>usingnamespacestd;structstudent{stringname;introll_no;};intmain(){structstudentstud={"Sam",1};structstudent*ptr;ptr=&stud;cout<<stud.name<<stud.roll_no<<endl;cout<<ptr->name<<ptr->roll_no<<endl;return0;}

A struct in the C programming language (and many derivatives) is a composite data type (or record) declaration that defines a physically grouped list of variables to be placed under one name in a block of memory, allowing the different variables to be accessed via a single pointer, or the struct declared name which returns the same address. The struct can contain many other complex and simple data types in an association, so is a natural organizing type for records like the mixed data types in lists of directory entries reading a hard drive (file length, name, extension, physical (cylinder, disk, head indexes) address, etc.), or other mixed record type (patient names, address, telephone... insurance codes, balance, etc.).

The C struct directly references a contiguous block of physical memory, usually delimited (sized) by word-length boundaries. It corresponds to the similarly named feature available in some assemblers for Intel processors. Language implementations that could utilize half-word or byte boundaries (giving denser packing, using less memory) were considered advanced in the mid-eighties. Being a block of contiguous memory, each field within a struct located at a certain fixed offset from the start. As an illustration, many BASIC interpreters once fielded a string data struct organization with one value recording string length, one indexing (cursor value of) the previous line, one pointing to the string data.

Because the contents of a struct are stored in contiguous memory, the sizeof operator must be used to get the number of bytes needed to store a particular type of struct, just as it can be used for primitives. The alignment of particular fields in the struct (with respect to word boundaries) is implementation-specific and may include padding, although modern compilers typically support the directive, which changes the size in bytes used for alignment.[1]

In the C++ language, a struct is identical to a C++ class but a difference in the default visibility exists: class members are by default private, whereas struct members are by default public.

In other languages[edit]

The struct data type in C was derived from the ALGOL 68 struct data type.[2]

Like its C counterpart, the struct data type in C# (Structure in Visual Basic .NET) is similar to a class. The biggest difference between a struct and a class in these languages is that when a struct is passed as an argument to a function, any modifications to the struct in that function will not be reflected in the original variable (unless pass-by-reference is used).[3]

This differs from C++, where classes or structs can be statically allocated or dynamically allocated either on the stack (similar to C#) or on the heap, with an explicit pointer. In C++, the only difference between a struct and a class is that the members and base classes of a struct are public by default. (A class defined with the keyword has private members and base classes by default.)

Declaration[edit]

The general syntax for a struct declaration in C is:

structtag_name{typemember1;typemember2;/* declare as many members as desired, but the entire structure size must be known to the compiler. */};

Here is optional in some contexts.

Such a declaration may also appear in the context of a typedef declaration of a type alias or the declaration or definition of a variable:

typedefstructtag_name{typemember1;typemember2;}struct_alias;

Often, such entities are better declared separately, as in:

typedefstructtag_namestruct_alias;// These two statements now have the same meaning:// struct tag_name struct_instance;// struct_alias struct_instance;

For example:

structaccount{intaccount_number;char*first_name;char*last_name;floatbalance;};

defines a type, referred to as . To create a new variable of this type, we can write

which has an integer component, accessed by , and a floating-point component, accessed by , as well as the and components. The structure contains all four values, and all four fields may be changed independently.

A pointer to an instance of the "account" structure will point to the memory address of the first variable, "account_number". The total storage required for a object is the sum of the storage requirements of all the fields, plus any internal padding.

Struct initialization[edit]

There are three ways to initialize a structure. For the type

/* Forward declare a type "point" to be a struct. */typedefstructpointpoint;/* Declare the struct with integer members x, y */structpoint{intx;inty;};

C89-style initializers are used when contiguous members may be given.[4]

/* Define a variable p of type point, and initialize its first two members in place */pointp={1,2};

For non contiguous or out of order members list, designated initializer style[5] may be used

/* Define a variable p of type point, and set members using designated initializers*/pointp={.y=2,.x=1};

If an initializer is given or if the object is statically allocated, omitted elements are initialized to 0.[6]

A third way of initializing a structure is to copy the value of an existing object of the same type

/* Define a variable q of type point, and set members to the same values as those of p */pointq=p;

Assignment[edit]

The following assignment of a struct to another struct will copy as one might expect. Depending on the contents, a compiler might use in order to perform this operation.

#include<stdio.h>/* Define a type point to be a struct with integer members x, y */typedefstruct{intx;inty;}point;intmain(void){/* Define a variable p of type point, and initialize all its members inline! */pointp={1,3};/* Define a variable q of type point. Members are uninitialized. */pointq;/* Assign the value of p to q, copies the member values from p into q. */q=p;/* Change the member x of q to have the value of 3 */q.x=3;/* Demonstrate we have a copy and that they are now different. */if(p.x!=q.x)printf("The members are not equal! %d != %d",p.x,q.x);/* Define a variable r of type point. Members are uninitialized. */pointr;/* Assign values using compound literal (ISO C99/supported by GCC > 2.95) */r=(point){1,2};return0;}

Pointers to struct[edit]

Pointers can be used to refer to a by its address. This is particularly useful for passing structs to a function by reference or to refer to another instance of the type as a field. The pointer can be dereferenced just like any other pointer in C, using the operator. There is also a operator in C which dereferences the pointer to struct (left operand) and then accesses the value of a member of the struct (right operand).

structpoint{intx;inty;};structpointmy_point={3,7};structpoint*p=&my_point;/* To declare and define p as a pointer of type struct point, and initialize it with the address of my_point. */(*p).x=8;/* To access the first member of the struct */p->x=8;/* Another way to access the first member of the struct */

C does not allow recursive declaration of ; a can not contain a field that has the type of the itself. But pointers can be used to refer to an instance of it:

typedefstructlist_elementlist_element;structlist_element{pointp;list_element*next;};list_elementel={.p={.x=3,.y=7},};list_elementle={.p={.x=4,.y=5},.next=&el};

Here the instance would contain a with coordinates 3 and 7. Its pointer would be a null pointer since the initializer for that field is omitted. The instance in turn would have its own and its pointer would refer to .

typedef[edit]

Main article: typedef

Typedefs can be used as shortcuts, for example:

typedefstruct{intaccount_number;char*first_name;char*last_name;floatbalance;}account;

Different users have differing preferences; proponents usually claim:

  • shorter to write
  • can simplify more complex type definitions
  • can be used to forward declare a type

As an example, consider a type that defines a pointer to a function that accepts pointers to struct types and returns a pointer to struct:

Without typedef:

structpoint{intx;inty;};structpoint*(*point_compare_func)(structpoint*a,structpoint*b);

With typedef:

typedefstructpointpoint_type;structpoint{intx;inty;};point_type*(*point_compare_func)(point_type*a,point_type*b);

A common naming convention for such a is to append a "" (here ) to the tag name, but such names are reserved by POSIX so such a practice should be avoided. A much easier convention is to use just the same identifier for the tag name and the type name:

typedefstructpointpoint;structpoint{intx;inty;};point*(*point_compare_func)(point*a,point*b);

Without a function that takes function pointer the following code would have to be used. Although valid, it becomes increasingly hard to read.

/* Using the struct point type from before *//* Define a function that returns a pointer to the biggest point, using a function to do the comparison. */structpoint*biggest_point(size_tsize,structpoint*points,structpoint*(*point_compare)(structpoint*a,structpoint*b)){inti;structpoint*biggest=NULL;for(i=0;i<size;i++){biggest=point_compare(biggest,points+i);}returnbiggest;}

Here a second for a function pointer type can be useful

typedefpoint*(*point_compare_func_type)(point*a,point*b);

Now with the two s being used the complexity of the function signature is drastically reduced.

/* Using the struct point type from before and the typedef for the function pointer *//* Define a function that returns a pointer to the biggest point, using a function to do the comparison. */point*biggest_point(size_tsize,point*points,point_compare_func_typepoint_compare){inti;point*biggest=NULL;for(i=0;i<size;i++){biggest=point_compare(biggest,points+i);}returnbiggest;}

However, there are a handful of disadvantages in using them:

  • They pollute the main namespace (see below), however this is easily overcome with prefixing a library name to the type name.
  • Harder to figure out the aliased type (having to scan/grep through code), though most IDEs provide this lookup automatically.
  • Typedefs do not really "hide" anything in a struct or union — members are still accessible (). To really hide struct members, one needs to use 'incompletely-declared' structs.
/* Example for namespace clash */typedefstructaccount{floatbalance;}account;structaccountaccount;/* possible */accountaccount;/* error */

See also[edit]

References[edit]

  1. ^C struct memory layout? - Stack Overflow
  2. ^Ritchie, Dennis M. (March 1993). "The Development of the C Language". ACM SIGPLAN Notices. 28 (3): 201–208. doi:10.1145/155360.155580.  
  3. ^Parameter passing in C#
  4. ^Kelley, Al; Pohl, Ira (2004). A Book On C: Programming in C (Fourth ed.). p. 418. ISBN 0-201-18399-4. 
  5. ^"IBM Linux compilers. Initialization of structures and unions". 
  6. ^"The New C Standard, §6.7.8 Initialization". 

0 comments

Leave a Reply

Your email address will not be published. Required fields are marked *