During the previous episodes, we have discussed arrays and character strings. Today, we will discuss data structures, which are another way to represent data. A program may need to store so-called "structured data". For example, we way wish to to store the age of several people, as is represented here. As we have discussed in a previous video, in such a case, we will need a kind of array, which would in this case be declared as follows. We we will use the "vector" type if we do not know how many people the program will consider. On the other hand, we will use the "array" type if, for example, we know that we will always consider 5 people. Arrays and vectors are homgenous data structures. This means that all the values contained in them share the same type -- int in this example. However, we may also want to consider heterogenous data, data with different types. For example, we could want to consider data regarding people, like here, where the data would be the person's name -- a character string -- the person's height -- a double-type value -- their age -- an int-type value -- and their gender -- a character, either 'M' or 'F', for instance. Here, we cannot resort to an array to store all these data, for they do not share the same type. However, we can regroup them in a new type called "structure". These "structures" allow us to represent the data of a row. We will then create an array/vector of "structures" to store all the data regarding a group of people. In general, we use structures, when we wish to regroup data of different types or natures. Structures have various usage. First of all, we will be able to represented entities. These entities will be defined by several data. For example, such an entity could be a person defined, according to the program's needs, by a first name, a last name and a birth date. Another entity could be a date, defined by a day number, a month and a year. Regrouping these data makes it easier to manipulate such entities. Another useful application of structures is when we need to have a function to return several values. This will be discussed this later. Finally, a third use, generalizing the first one, is to simplify the conception and writing of our programs. Before we burry ourselves in the details, let's provide a few examples of structures. This "Date" structure gathers a day, a month and a year. Such a declaration thus defines a new type, usable in the program. Thanks to this type, we can now declare variables. Here, for example, we are declaring a date-type variable called "aujourdhui" [TN: "aujourd'hui" means "today"] This variable can now have concrete values for the day, the month and the year. This structure "Etudiant" regroups the student's name, and their faculty -- both character strings -- as well as his course inscriptions, an array containing "Cours"-type values. [TN: "cours" means "course"], where "Cours" is another structure, previously declared in the program. The last data in this structure would be the average of the student's grades. This structure "Particule" would be useful for a physics simulation program. It regroups the values related to an elementary particle : first of all, the position of the particle -- a three-dimensional vector -- the velocity of the particle -- another three-dimensional vector -- as well as the mass and charge of the particle -- both of the type double. A structure is thus a new type defined and declared by a programmer respecting the following syntax. We begin with the reserved keyword "struct" followed by the desired name of the structure. Then, between braces, is what we call the list of the structure members regrouped in the structure. As you can see, the declaration of these members looks similar to the declaration of variables. Indeed, the declaration starts with the member's type, followed by its identifier or name, followed by a semicolon. Also, please note that a semicolon is required after the closing brace. Structures are the only circumstance where a semiclon appears after a closing brace. For example here, we define a new structure, a new type called "personne". This structure would be useful in order to define the type of the elements of the array presented in the beginning of this episode. It regroups a person's name, height, age and gender. This other structure called "Complexe" regroups two members. A member x and a member y. This structure could be useful to represent complex numbers -versus real numbers- written "x + iy" in mathematics. SImilarly to arrays, the members of a structure are not limited to scalar types such as int or double. The members of a structure can be arrays or even other structures! For example, we declare here a type "Compliquee" (TN:"compliquée" means "complicated") whose second member is of the type int. Its first member, however, is an array of doubles. And its third member is of the type "Simple", which has been declared here and contains two members of type int and double. A structure is thus a new type which we can use to declare variables. This declaration is no different from any other declaration. Namely, we begin by the type, followed by the variable's name. For example, we rewrote here the code defining the structure "Personne". and here, I declare a variable "untel" (TN: "untel" means "someone") of the type "Personne". Be careful though, the definition of a structure must be written outside any function before we can use it to declare variables. On the other hand, the declaration of variables of this new type has to occur inside a function. For example, the definition will be written outside any function. Then, we will define the variable "untel" inside a function, such as the "main" function, like this. We can represent this variable "untel" like this: it has a member called "nom" (TN:"name") a member called "taille" (TN:"height"), etc. In this other example, we first declare a structure called "Complexe" with a member "x" and a member "y". Then, we declare here a new variable called z of the type "Complexe". z will thus contain two members : a member 'x' and a member 'y'. Similarly to other types, we can initialize a structure-type variable. During the declaration, we will proceed with the following syntax. After the type of the structure and the variable name, we will add the sign equals and, between braces, the values we wish to give to the different members of the variable. And, after the closing brace comes our semicolon. For example, here is our structure "Personne" once again. Here, we declare a personne-type variable "untel". "untel" can be represented like this. This declaration also initializes the members of the variable untel: "Dupond" will go into the first member, the member "nom". Namely, the member "nom" will contain the value "Dupond". The member "taille" will contain the value 1.75 . The member "age" will contain the value 41 . And the member "sexe" (TN: "gender") will contain the character 'M'. Moreover, in C++11, we can also use this syntax outside the initialization, for an assignment and we will obtain the exact same values in the same members. Please note that in C++, before 2011, we could not use this syntax for the assignment; there was no easy way to assign literal values to all the members of a structure. We now know how to initialize the members of a structure-type variable, namely giving a value to its members during the declaration of the variable. Now we would like to access these values. To that end, we have to respect the following syntax. We begin by writing the name of the structure-type variable, followed by a period, followed the member's name. For example, let us go back to our variable "untel" of the previous slide, which was a "Personne"-type variable. We can represent it like this. This instruction is an assignment, which will store the value 1.75 inside the member "taille" of the variable "untel". Namely, we will put the value 1.75 at this place of our representation of the variable "untel". This instruction will add 1 to the member "age" of "untel" (happy birthday!). In other words, it will go from 41 to 42. By the way, please note that the parentheses here are mandatory; we cannot simply write " ++untel.age " since the operator "++" has priority over the operator '.' (dot). This last instruction here will print the value contained in the member "sexe" of the variable "untel"; it will thus print the character 'M'. Now, let us detail a complete example, regarding, inter alia, functions with structure-type parameters. We will start by reusing here the code of our structure "Personne", which data are: a name, a height, an age and a gender. The function "main" will start by declaring a personne-type variable "untel". We can represent "untel" like this. "untel" will be initialized through the return value of the function "naissance" (TN:"birth"), called here. Here is the code of the birth function. Its goal is to ask the user to give us the values of the members of a personne-type variable, namely, a name, a height, an age and a gender. The function will then return, as a structure, the members' values entered by the user. This function does not need any value in order to work: it has no parameters. On the other hand, it returns a structure-type value; more precisely, a "Personne"-type value. The return type of the "naissance" function is thus "Personne". How does the "naissance" function proceed, exactly? It starts by declaring a local personne-type variable called "p". "p" can be represented just like the variable "untel". For now, the members of "p" are not initialized; we do not know what they contain. Then, the function "naissance" will ask the user to enter a name, which will be stored directly inside the field "nom" of the variable "p", right here. Let us suppose, for our example, that the user enters the name "Dupond". Then, the function will ask the user to enter a height and an age; let us use the values of the previous example. The function will then ask the user to enter a character --either 'M' or 'F'-- for the member "sexe" of the variable "p", making sure that the user enters either 'M' or 'F' thanks to a "do-while loop". Let'assume that our person here is a man. Finally, the function will finish by returning the value contained inside the variable "p", that is all the values stored in its members. Let's go back to the call of the function "naissance". What will happen here, exactly? The values of the members of the variable "p" will be copied inside the fields of the variable "untel". Precisely, the member "name" will take the value "Dupond", the member "height", 1.75, "age", 41 and the member "sexe" the character 'M'. The next instruction in the "main" function is this one; a call to the "anniversaire" function (TN: "anniversaire" means "birthday"), passing the variable "untel" as argument. Here is the code of the "anniversaire" function. The goal of this function "anniversaire" is to add 1 to the "age" member of the variable passed as argument. This function has thus only one parameter of the type "Personne", since "untel" is a "Personne"-type variable. We will use a passage by reference since the function aims to modify the value of the variable passed as argument. This function does not return anything; its return type is thus "void". If we execute the function's body in our example, we will change this 41 -- the value contained by the member "age" of the variable "untel" -- to 42. Then, we will keep going in the body of the "main" function, thus reaching this instruction calling the function "affiche" [TN: "print"/"display"] passing the variable "untel" as argument. Here is the code of this "affiche" function. The goal of this "affiche" function is to print the values of the members of a variable passed as argument. This function thus has only one personne-type parameter. It will not need to modify the value of the variable passed as argument. We used here keyword "const" followed by an ampersand similarly to the passage by reference, between the paramter's type and the parameter's name. This is an optimization you do not need to worry about for now. This optimization avoids to make a copy. Indeed, be reminded that during passage by value, a copy is created; a costly copy of a structure containing many members. The function will simply print the values of the different members of the parameter. By the way, we are here using a "switch" instruction to print if the person is man or a woman. This "switch" instruction is explained in the complements. We could also have used an "if" instruction. You can verify yourself that, in the case of our example, the function will print this. Once the "affiche" function has been executed, we will come back in the "main" function, here. We will then execute the "return" instruction, thus ending the program. We can assign a structure-type variable to another variable of the same type. For example, we declare here a personne-type variable p1, initializing its members with these values. Then, we declare another personne-type variable p2 without initializing the value of its members. In this last instruction -- an assignment -- we will copy the value of the members of p1 inside the members of the variable p2. Namely, this assignment is strictly equivalent to these 4 assignments, copying member by member, the variable p1 into p2. In other words, we copy here, for example, the value of the member "nom" of p1 into the member "nom" of p2. Be careful though, the assignment is the only global operator usable for structure-type variables. We cannot compare nor print them in a global way. Reusing the previous example, we were allowed to write "p2 = p1", which is an assignment. However, we are not allowed to write "p1 == p2" to compare p1 and p2 or two write "cout << p1" in order to print the values of the members of p1. In such a case, we have to proceed member by member. For example, we may use this instruction to print the four members of p1. Obviously though, it is much better to write a function tasked with this comparison or printing. This is exactly what we did with the former "affiche" function, in a previous example. By the way, please note that even if the operators == and << are not defined a priori for structures, in C++, a programmer has the possibility to define them himself. This is called operator overloading, But this goes beyond this course's frame. For now, simply remember that you have to compare structures member by member. Now, let us go back to the example of the beginning of this episode Remember, we wanted to store all these values in the memory. Now, we will be able to use an array, the elements of which will be of structure type. First of all, we will declare the structure "Personne", regrouping the four members interesting us, namely the name, the height, the age and the gender of the person. Then, we will declare an array called "Personnes", here. [TN : notice the plural.] Its elements will be of the type "Personne". Now, each row of this table will correspond to an element of our array. Each column of the table will correspond to a member of the array's elements. We can represent the beginning of our "Personnes" array like this : Each element of the "Personnes" array will contain a member "nom", a member "taille" and so on. All this forms the first element of the "Personnes" array. And this assignment will store, among others, these values inside the first element of the "Personnes" array. Therefore, "Dupond" will be stored in this member, 1.75 in this member, 41 here and 'M' here. As we have said, structures can used to let functions returns several values. For example, we may want to write a function "division_euclidienne" (TN:"euclidean division") returning, at the same time, the quotient and the remainder of two values passed as argument. In such a case, we have several possible solutions. We could have the function return a structure containing the different values we wish to have returned. Another possibility is to pass the variables by reference and to have them assigned, inside the function, to the values we wish to calculate. We will see an example on the next slide. A third possibility, if all the values have the same type, is to have the function return a dynamic array containing these values. In more complex cases, we could even combine the solutions 1 and 3, thus returning either a structure, with vector members containing homogenous data or returning vectors of structure containing heterogenous values. For example, in the case of the function "division_euclidienne", which has two parameters: the dividend and the divisor. the first solution would be to start by declaring a structure called here "Resultat" (TN:"result") containing a member for the quotient and a member for the remainder. Then, we will define, as the return type of the function "division_euclidienne", the type "Resultat". In such a case, we will call our function "division_euclidienne" like this: "Resultat" in order to define the type of a variable containing the result, and passing two variables by value, one for the dividend and one for the divisor. The second solution is to add two parameters, passed by reference and to use the function like this. We will start by declaring two supplementary variables; they will store the values calculated by the function. Then, we will call our function like this. The third solution is to define, as the return type of the function, an integer array containing two elements. We will then call the function like this. We have used here the type "array" but we could also have used the type "vector" since "vector" is a more general form of arrays. To sum up, structures let us regroup several data under a same type. They serve to represent entities such as people or dates or to have functions return several values. More generally, they let us simplify the conception and writing of our programs. Now, we invite you to try and take the quizzes, testing the new knowledge acquired during this new lesson.