Before a Structure Can Be Used It Must Be
xiii.1 C-structures
Structures define new types of variables. Unlike the primitive types, like int s or double s, one variable of a structure blazon can contain many pieces of data. Unlike it is in arrays, these pieces of data do not take to be all of the same type.
C-construction is a drove of named members which can be of unlike types, also other construction types.
C-structure can be divers with the following syntax:
struct AName { Type1 memb1; Type2 memb2; ... } ;The names Type1 and Type2 are names of types (other than the name of the construction blazon being defined, AName hither). The names memb1 and memb2 are arbitrary identifiers of fields of this construction. Each variable of this structural blazon will contain members of the types and names corresponding to the structure's fields. So far it is only the definition of a blazon; at that place are no variables of this type.
A semicolon after the endmost brace is necessary!
The proper name of the type just defined is AName in C++ and struct AName in C. In C the keyword struct is a part of the type'south name; in C++ information technology can (just does not accept to) exist omitted.
Having defined a type we can create objects (variables) of this type. The syntax is the same as for primitive types (like double or int ):
struct AName a, b; /* C and C++ */ AName c, d; // C++ butWe can as well ascertain variables of this blazon directly after its definition, before the semicolon:
struct AName { Type1 memb1; Type2 memb2; } a, b, c, d;defines a structural blazon and four variables of this type. It is too possible to define variables of an bearding structure:
struct { Type1 memb1; Type2 memb2; } a, b;Here we synthetic two objects named a and b . Each of them contains two members corresponding to the 2 fields of the construction. Nosotros tin can access these members exactly in the same way every bit we do it for members of other, named, structure types (see below). However, we will not exist able to create any other variable of this blazon, as information technology does not have a proper name past which we could refer it.
Each object (variable) of a C-construction has as many members equally there are fields in its definition — they accept corresponding names and types. In order to access a fellow member of an object it is therefore not enough to specify the proper noun of a member, Nosotros accept to identify which object is meant, as members with the same proper name but belonging to different objects are completely independent. One can exercise it using a member selection operator — one of those listed on positions 4 and 5 in the tabular array of operators, depending on the way we refer to the object: by the name of the object itself or past the proper noun of a pointer which points to this object. If a name a is the proper noun of an object , and then to access its memebr named memb we utilize the „dot" operator:
a.memb
The same rule would utilise if a would exist the proper name of a reference to an object (recollect, however, that there are no references in C). Suppose now that an object is referred to past the name of a pointer pa which currently points to this object. And so to access its member one uses the „arrow" operator: pa->memb
where the arrow is a digraph equanimous of a hyphen and a 'greater than' characters. The same rule applies not only to C-structures but to structures and classes in general.
Annotation that the form pa->memb is essentially a autograph note for (*pa).memb , every bit *pa denotes the object pointed to by pa . Hence, if a is the identifier of an object of a structure which has a field named ten of blazon double , and pa is a pointer which points to this object, then the following statements are equivalent:
1. a.x = three.14 ; 2. (&a)->ten = 3.14 ; iii. pa->10 = 3.xiv ; 4. (*pa).x = iii.fourteen ;The parentheses on lines two and 4 are required, as the member-selection operators (dot and arrow) have higher precedence than the dereference and address operators ( '*' and '&' ).
Summarizing,
the symbol a.b denotes a fellow member
b of an object
a , while pa->b denotes a member
b of the object pointed to by a pointer
pa .
Nosotros can declare/ascertain an object of a C-structure and initialize information technology in the same argument. The syntax is like to that of initializing arrays:
AName ob = {expr_1, expr_2} ;where expr_1 and expr_2 are expressions the values of which are to be used to initialize members of the object being created. They must be given in the gild of the corresponding fields in the structure's definition — as in the case of arrays, if the number of initializers is less than the number of fields, the remaining members will be initialized with zero of an appropriate type. The keyword struct is necessary in C; in C++ it can be omitted.
The program below defines a construction Car (➊) which describes, in a very simplified way, cars. Information technology has two fields: speed and year of type double and int , respectively. Two global variables, skoda and fiat , of this type are defined immediately in the aforementioned statement. The latter is also initialized by the values in braces — they are given in the order corresponding to the order of fields in the definition of the structure. The variable skoda is created, but non initialized — its members remain undefined.
P91:
cstruct.cppC-struktury
1. #include <iostream> 2. using namespace std; 3. 4. struct Car { ➊ 5. double speed; six. int year; vii. } skoda, fiat = { 100 , 1998 } ; eight. 9. void pr ( const char *, const Motorcar*); 10. eleven. int chief () { 12. Car toyota, *myCar = &toyota, *vw; ➋ 13. xiv. cout << "Size of \' Motorcar \' objects is " ➌ 15. << sizeof (Car) << " bytes \due north " ; 16. skoda.speed = 120 ; ➍ 17. skoda.year = 1995 ; eighteen. 19. toyota.twelvemonth = 2012 ; ➎ 20. myCar->speed = 180 ; 21. 22. vw = new Car; ➏ 23. vw->speed = 175 ; 24. vw->year = 2003 ; 25. 26. pr ( "Skoda " ,&skoda); 27. pr ( "Fiat " ,&fiat); 28. pr ( "Toyota" ,&toyota); 29. pr ( "myCar " , myCar); 30. pr ( "VW " , vw); 31. 32. delete vw; 33. } 34. 35. void pr ( const char *proper name, const Automobile *motorcar) { 36. cout << proper noun << ": speed " << car->speed 37. << ", year " << car->year << endl; 38. }
Inside principal function nosotros define another object of type Motorcar named toyota . We also define ii pointers: myCar , initialized with the accost of toyota , and vw which we leave undefined (line ➋).
We print the size of objects of type Car on line ➌. This size can be 12 bytes (8 bytes for the fellow member speed of blazon double and iv bytes for the member twelvemonth of blazon int ). The exact size can be different on some platforms, which, e.g., prefer sizes which are multiples of 8; each object contains and then some unused bytes — the so called padding : this is the case for the author's system, every bit tin exist seen from the printout:
Size of 'Auto' objects is 16 bytes Skoda : speed 120, year 1995 Fiat : speed 100, year 1998 Toyota: speed 180, year 2012 myCar : speed 180, year 2012 VW : speed 175, year 2003We asign sensible values to the members of the object skoda on lines➍ and the side by side. As skoda is the name of an object , and not of a arrow, we use the „dot" notation.
The object toyota is assigned values on lines➎ and the next. On line ➎ nosotros refer to this object by its proper noun, then the „dot" notation is used over again. However, in the next line we refer to the same object (see line ➋) but using the pointer myCar . Therefore we use the notation with an „pointer" here.
Another object of type Automobile is created on line➏. This time we classify information technology on the heap (using new ) and store the address returned in pointer vw . The object created tin now be assigned values using the notation appropriate for pointers, i.e., with an „arrow".
The function pr prints the data on cars passed to it by pointer of type const Car* . Therefore, when we invoke information technology, nosotros have to pass addresses; we tin employ pointer variables (whose value are addresses) or, if nosotros want to apply the proper noun of an object, we have to extract its address with the operator '&' .
C-structures are heavily used in the libraries. Let united states of america consider an example. Including the header sys/timeb.h we brand accessible a construction type timeb and functions operating on variables of this type, in particular the function ftime (actually, the header sys/timeb.h is not standard, but it is present in well-nigh implementations of C/C++, including Linux gcc and the Microsoft'south compilers). The function ftime takes the address of an object of type timeb , which is a structure blazon defined as:
struct timeb { time_t time; unsigned short millitm; short timezone; short dstflag; } ;Given the accost of an object, the functions fills it out with system data about current fourth dimension. The fellow member time volition be the number of seconds since 1st of January 1970 (beginning of the Unix epoch). Its type, time_t , is equivalent (by ways of a typedef ) to a signed integer type. This is ordinarily long , and then for 32-bit machines, where sizeof(long) is 4, the maximum value of time is 231 -1 = 2147483647
![$ \approx$](https://edux.pjwstk.edu.pl/mat/260/lec/PRG2CPP_files/img44.png)
The member millitm will be the number of milliseconds since the showtime of the last total 2nd. The members timezone and dstflag are not very useful.
Using the role ftime one tin measure the execution time of a part of a plan (although it is not the best mode to practise it):
P92:
tim.cppUsing library structures
ane. #include <iostream> 2. #include <cmath> // sin, cos three. #include <sys/timeb.h> // ftime 4. using namespace std; 5. vi. int main () { 7. timeb first, now; ➊ 8. double res = 0 ; 9. x. ftime (&beginning); ➋ xi. 12. for ( int i = 0 ; i <= 90000000 ; ++i) { 13. if (i% 10000000 == 0 ) { 14. ftime (&now); ➌ 15. time_t sec = at present.time - start.time; sixteen. int msec = at present.millitm; 17. msec -= start.millitm; 18. if (msec < 0 ) { nineteen. --sec; 20. msec += 1000 ; 21. } 22. cout << "Afterwards " << i << " iterations: " 23. << sec << "s and " << msec << "ms \northward " ; 24. } 25. res = cos (res+ sin (i)); 26. } 27. cout << "Useless result: " << res << endl; 28. }
Nosotros define (line ➊) two variables of type timeb : outset and now . The first is filled out with current information past a telephone call to the part ftime (line➋). The 2d is updated every ten one thousand thousand iterations of the loop (➌) and the difference betwixt the current time and the start time of the plan is printed:
After 0 iterations: 0s and 0ms After 10000000 iterations: 0s and 875ms After 20000000 iterations: 1s and 746ms After 30000000 iterations: 2s and 618ms After 40000000 iterations: 3s and 492ms Subsequently 50000000 iterations: 4s and 366ms After 60000000 iterations: 5s and 241ms After 70000000 iterations: 6s and 120ms After 80000000 iterations: 6s and 998ms Afterwards 90000000 iterations: 7s and 885ms Useless result: 0.953078The variable res is calculated here just to give the program something to work on...
Structures can incorporate, equally their members, other structures. Of grade, non of the same type, every bit these would also have to incorporate such substructures, and those in turn would also accept to comprise such substructures, and so on ad infinitum .
Suppose we desire to accept a type describing points on a aeroplane. A construction consisting of 2 fields of type double (corresponding to Cartesian coordinates of the point) could provide a natural representation:
struct Point { double ten, y; } ;Now we tin define the triangle as a construction containing iii points corresponding to its vertices:
struct Triangle { Point A, B, C; } ;C-structures do not comprise any methods or constructors. In order to operate on them, 1 has to use global functions. In the example below, we ascertain a function which represents the operation of rotation of points around the origin. A rotation through the bending φ (in radians) tin can be described in terms of coordinates by the formulae:
P93:
rotat.cppStructures equally members of structures
1. #include <iostream> 2. #include <cmath> // sin, cos 3. using namespace std; 4. v. struct Point { 6. double x, y; 7. } ; eight. 9. struct Triangle { 10. Indicate A, B, C; 11. } ; 12. xiii. void info ( const Point*); ➊ fourteen. void info ( const Triangle*); ➋ 15. void rot (Betoken*, double ); ➌ 16. void rot (Triangle*, double ); ➍ 17. xviii. int main () { 19. Point A; 20. A.ten = - 1 ; 21. A.y = 2 ; 22. 23. Point B = { - ane , ane } ; 24. 25. Point C = { 2 } ; 26. C.y = - 1 ; 27. 28. Triangle T = { A, B } ; 29. T.C = C; 30. 31. cout << "Initial points: " ; 32. info (&A); info (&B); info (&C); 33. cout << " \northward Triangle: " ; 34. info (&T); 35. cout << endl; 36. 37. rot (&A, 90 ); rot (&B, ninety ); rot (&C, 90 ); ➎ 38. cout << "A, B, C later rot. through 90 deg: \n " ; 39. info (&A); info (&B); info (&C); forty. cout << endl; 41. 42. rot (&T, ninety ); rot (&T, ninety ); ➏ 43. cout << "T after rot. through ninety deg. twice: \n " ; 44. info (&T); 45. 46. rot (&T, 180 ); ➐ 47. cout << "T afterward rot. through 180 deg. again: \n " ; 48. info (&T); 49. } 50. 51. void info ( const Point* pP) { 52. cout << "(" << pP->x << ", " << pP->y << ") " ; 53. } 54. 55. void info ( const Triangle* pT) { 56. cout << "A=" ; info (&pT->A); ➑ 57. cout << "B=" ; info (&pT->B); 58. cout << "C=" ; info (&pT->C); 59. cout << endl; threescore. } 61. 62. void rot (Point* pP, double phi) { 63. static double conver = atan ( one .)/ 45 ; 64. phi = phi*conver; // degrees -> radians 65. 66. double c = pP->x; 67. pP->x = pP->x * cos (phi) - pP->y * sin (phi); 68. pP->y = c * sin (phi) + pP->y * cos (phi); 69. } 70. 71. void rot (Triangle* pT, double phi) { 72. rot ( &pT->A, phi); ➒ 73. rot ( &pT->B, phi); 74. rot ( &pT->C, phi); 75. }
The function rot takes a bespeak past pointer, and then it tin piece of work on the original and modify information technology (that is why we utilize „arrows" and not dots in its definition). Permit us define iii points A = (- 1, 2), B = (- i, 1) and C = (2, - ane), as on the left mitt side of the effigy:
Nosotros then define a triangle with vertices in A , B and C . Note that assigning values of A , B and C to the members of T implies copying them — the original points and the members of T are independent. Press information on the triangle and points nosotros see that the situation corresponds to the left hand side of the figure.
The 3 points are then rotated by the function rot through xc o (line➎). The functions calculates new coordinates and changes the members of the input objects — as the points were passed by pointer, it ways that the original points become modified. New location of points is depicted in the middle role of the figure; note that the triangle T has not been modified as its members are copies of the original points before rotation.
Initial points: (-1, 2) (-1, 1) (2, -one) Triangle: A=(-1, ii) B=(-1, 1) C=(2, -1) A, B, C after rot. through 90 deg: (-2, -1) (-1, -1) (1, 2) T after rot. through xc deg. twice: A=(1, -2) B=(one, -1) C=(-two, ane) T after rot. through 180 deg. again: A=(-1, two) B=(-1, 1) C=(2, -i)Now we rotate the triangle (line➏). Note that the office rotating triangles has the name rot , exactly the same as the function which rotates the points (➌ and ➍). However, its parameters are of unlike type, and so the compiler will know which i is meant (similar overloading is used for two functions info : for points ➊ and for triangles ➋). The function rot for triangles is very simple and does not require any noesis of trigonometry: information technology but rotates all three vertices using the previous version of the rot part and passing to information technology the addresses of the iii members of a triangle for which information technology was invoked (which themselves are points). The strange looking construct &pT->A on lines ➑ and ➒ is correct: it denotes the address of the point A which is a fellow member of an object of type Triangle pointed to by pT . The notation &(pT->A) would exist mayhap more than legible, but is not necessary, every bit the precedence of fellow member option operator ( '->' ) is higher than that of the address operator ( '&' ).
After rotating the triangle twice through 90 o , i.e., through 180 o , it is located as shown in the right hand side of the effigy: the printout shows that this is in fact the case. Rotating the triangle through 180 o again (line➐) reverts information technology to the initial position (see the last line of the printout).
As we already stated, structures cannot comprise members of its ain type. However, it can comprise, as its fellow member, a pointer to objects of its type. This is often used for building lists . Each object (elements) of a listing contains some information and also the address of the next element of this listing — what we go is called one-directional, or singly linked, list (at that place are as well two-directional, or doubly linked, lists, where each object contains addresses of the side by side and previous elements of the list).
Let usa now construct such a (simplified) singly linked list. We define a structure Node which contains, as fields, some data. In our example these are just two double s wdth and hght — very often information technology would rather be a arrow to an object which holds more complicated data. Besides the data, there will exist an additional field next of blazon Node* . Members of objects of blazon Node which represent to this field will contain the address of the node which comes next in the list. For the last element in the list there is no next element, and then the member next of this node will be set to nullptr (or NULL ). Sometimes information technology is more user-friendly if information technology points to the node itself, or to the starting time node — nosotros and then get a cyclic list).
P94:
simplist.cppA simple list
1. #include <iostream> 2. using namespace std; iii. iv. struct Node { v. double wdth; 6. double hght; 7. Node *next; 8. } ; 9. 10. void put_data (Node* north, double south, double w, Node* side by side); 11. void print_list ( const Node* northward); 12. void print_list_reverse ( const Node* n); xiii. xiv. int master () { 15. Node A = { iv , 44 , nullptr} ; ➊ 16. Node B, D, *head; 17. eighteen. Node* pC = new Node; ➋ 19. 20. put_data (&B, iii , 33 ,&A); 21. put_data (pC, 2 , 22 ,&B); 22. put_data (&D, i , xi ,pC); 23. 24. head = &D; ➌ 25. 26. print_list (head); 27. print_list_reverse (head); 28. 29. delete pC; 30. } 31. 32. void put_data (Node* n, double due south, double west, Node* next) { 33. n->wdth = south; 34. n->hght = westward; 35. n->adjacent = adjacent; 36. } 37. 38. void print_list ( const Node* n) { 39. for ( ; northward; due north = n->next ) 40. cout << n->wdth << " " << n->hght << "; " ; 41. cout << endl; 42. } 43. 44. void print_list_reverse ( const Node* northward) { 45. if (n == nullptr) render ; // empty list 46. if (n->side by side != nullptr) ➍ 47. print_list_reverse (due north->next); 48. cout << n->wdth << " " << n->hght << "; " ; 49. }
We create a variable A of type Node on line➊ and initialize its 3 members using the syntax immune for C-structures (but non for more complicated structures in C++). In the side by side line we define two more than nodes, B and D , and a pointer to objects of this structure head . On line ➋ we allocate on the heap another object; the accost returned by new is assigned to pC . The objects are then filled with data by invoking the role put_data . It takes the address of an object which is to exist filled together with information, represented by two double southward, and address of another object which volition be assigned to the fellow member next equally the accost of the next object of the listing. In order to extract the address of objects A , B and D , we employ the address operator '&' ; for pC we practice not do it considering it is already a pointer with an address equally its value (the object which is pointed to by pC is on the heap and does not have any proper name). Therefore, B contains the address of A as the next element, the object pointed to by pC has the address of B , and for D it is *pC which is the next. The situation is depicted in the figure
The accost of the beginning element is remembered in the variable head (line➌). Annotation that in order to have access to the whole list it is sufficient to know head ; in its next member we tin can find the accost of the next element, etc.
Two functions illustrating some basic operations on lists are divers in the program: print_list and print_list_reverse . They both take but the head : the accost of the first element of the listing. The get-go of them loops over the elements of the list printing information from the nodes. After each iteration, the pointer due north , pointing to the electric current node, is assigned the value of 'n->next' , so it points to the adjacent node. The loop terminates when n becomes nullptr — this must eventually happen because the terminal element (which is A ) has nullptr equally the value of its next member.
The 2nd of the two functions, print_list_reverse , is more interesting. Its task is to print data from the nodes but in reverse order: from the tail to the caput. This is nontrivial, as nodes only know their successors, but not predecessors. The recurrence comes to the rescue here: we call the office passing the head (which is the address of D ). Before press information on the electric current node, even so, the role calls itself passing the pointer to its successor (line➍); this incarnation of the function invokes itself once more, this time passing the pointer to its successor, then on. For A (the tail), the condition on line➍ becomes false, so printing is executed and the last incarnation of the function returns to the incarnation invoked for B — at present information on B is printed and the function returns to its incarnation for *pC etc. We see that traversing the list backwards was ensured by stack rewinding after consecutive returns from the function:
1 eleven; two 22; 3 33; four 44; iv 44; 3 33; two 22; 1 11;
Objects of C-structures tin also be passed as a function argument or the value returned. However, one should recollect that such objects can be quite large and passing them past value can be rather ineffective. It is so better to work on pointers to structures (or references), non the structures themselves; copying or moving objects physically in the computer'south memory should then exist avoided. The same applies to arrays of objects — information technology is oft amend to operate on arrays of pointers rather than of objects themselves.
In the program beneath, object of type Writer are at least 44 bytes long (40 bytes for the member name and iv bytes for the integer member born ). All the same, the pointers are only 4 (or 8) bytes long:
P95:
writers.cppUsing pointers for sorting arrays
i. #include <iostream> 2. #include <iomanip> /* setw */ iii. using namespace std; 4. 5. struct Writer { 6. int built-in; 7. char name[ 40 ]; 8. } ; ix. 10. void insertionSort (Writer*[], int ); 11. 12. int main () { 13. Writer gl = { 1896 , "Giuseppe Tomasi di Lampedusa" } , 14. ws = { 1564 , "William Shakespeare" } , 15. ib = { 1894 , "Isaak Babel" } , 16. jg = { 1749 , "Johann Wolfgang von Goethe" } , 17. fk = { 1883 , "Franz Kafka" } , 18. bs = { 1892 , "Bruno Schulz" } ; 19. twenty. Author* writers[] = { &gl,&ws,&ib,&jg,&fk,&bs } ; ➊ 21. 22. const int ile = sizeof (writers)/ sizeof (writers[ 0 ]); 23. 24. cout << "sizeof(Writer )=" << sizeof (Writer ) << endl; 25. cout << "sizeof(Author*)=" << sizeof (Writer*) << endl 26. << endl; 27. insertionSort (writers, ile); 28. 29. for ( int i = 0 ; i < ile; i++ ) ➋ 30. cout << setw ( 28 ) << writers[i]->name 31. << setw ( five ) << writers[i]->born << endl; 32. } 33. 34. void insertionSort (Author* a[], int size) { 35. if ( size <= 1 ) return ; 36. 37. for ( int i = 1 ; i < size ; ++i ) { 38. int j = i; 39. Writer* v = a[i]; xl. while ( j >= one && v->born < a[j- 1 ]->born ) { ➌ 41. a[j] = a[j- 1 ]; ➍ 42. j--; 43. } 44. a[j] = v; 45. } 46. }
Suppose nosotros want to sort writers according to their year of birth. Information technology is better to sort a array of pointers to objects representing writers than an assortment of Writer objects. Sorting means copying and moving objects, but objects of type Writer are long while pointers are short. Therefore we build an array of pointers to Writer objects (line➊) and laissez passer it to a sorting function. The benchmark of sorting is based on the value of the fellow member born of the object pointed to by a arrow being an element of the array of pointers (line➌), but only pointers from this array are copied and moved effectually, never the objects themselves (as on line➍). Still, the the job has been washed — we tin impress information on writers in the sorted social club (➋):
sizeof(Writer )=44 sizeof(Writer*)=8 William Shakespeare 1564 Johann Wolfgang von Goethe 1749 Franz Kafka 1883 Bruno Schulz 1892 Isaak Babel 1894 Giuseppe Tomasi di Lampedusa 1896The manipulator setw has been used here just to meliorate format the printout. The sorting function implements insertion sort algorithm (without watch).
Sometimes nosotros want, or take to, declare a construction (wedlock, class) without really defining it. Every bit the definition, and the size of objects in particular, of this type is non known, 1 cannot create any object of it. Such a type is, as we say, incomplete . The announcement is chosen a forrad announcement and is sometimes unavoidable. The proper name of a construction which has been declared but lacks definition can be used in situations where a definition and size of objects is not necessary — e.thou., to define pointers to such objects (but non to initialize them, equally one cannot create any object which could be pointed to).
Suppose, for case, that a construction AA has a field which is the arrow to objects of type BB , and BB has a field which is the pointer to objects of blazon AA . Something like
1. struct AA { 2. BB *b; // Wrong three. // ... 4. } ; 5. 6. struct BB { 7. AA *a; 8. // ... 9. }would be wrong considering in the second line information technology is not known what the name BB denotes. Irresolute the order of definitions will not help, equally nosotros will have the same trouble with AA . One has to use a announcement to tell the compiler that the name BB is the proper name of a structure which will be divers later. From now on one tin can define pointers to object of blazon BB , although one cannot create any object of this type. The declaration of a structure has the form
struct AName ;where AName is the proper name of a alleged structure (the same applies to unions and classes). In our example we should write
1. struct BB ; two. iii. struct AA { iv. BB *b; 5. // ... 6. } ; vii. 8. struct BB { 9. AA *a; 10. // ... 11. }and at present information technology is known that the name BB in the definition of AA is the name od a construction which will exist defined afterward. The size of an object of AA can exist calculated past the compiler because it contains merely a pointer to BB but not an object of BB ; the size of pointers is of form known to the compiler.
Let us consider an case:
P96:
wife.cppFrontward declarations of structures
1. #include <iostream> 2. #include <cstring> // strcpy iii. using namespace std; 4. v. struct Husband ; vi. struct Wife ; 7. 8. void prinfo ( const Married man*); 9. void prinfo ( const Married woman*); 10. 11. struct Wife { 12. Husband *hus; thirteen. char name[ 20 ]; 14. } heather = { 0 , "Heather" } ; 15. 16. struct Married man { 17. Married woman *wif; 18. char proper name[ 20 ]; 19. } anthony = { 0 } ; twenty. 21. int main () { 22. strcpy (anthony.name, "Anthony" ); ➊ 23. 24. anthony.wif = &heather; 25. heather.hus = &anthony; 26. 27. Husband zachary = { 0 , "Zachary" } ; 28. Wife cecilia = { 0 , "Cecilia" } ; 29. 30. prinfo (&anthony); 31. prinfo (&heather); 32. prinfo (&zachary); 33. prinfo (&cecilia); 34. } 35. 36. void prinfo ( const Married man *h) { 37. cout << "Man: " << h->proper name; 38. if ( h->wif ) 39. cout << "; wife " 40. << h->wif->proper noun << " \n " ; ➋ 41. else 42. cout << "; (single) \n " ; 43. } 44. 45. void prinfo ( const Wife *w) { 46. cout << "Woman: " << westward->name; 47. if ( w->hus ) 48. cout << "; hubby " 49. << (*((*w).hus)).name << " \north " ; ➌ 50. else 51. cout << "; (single) \northward " ; 52. }
Two structures, Husband and Wife , are first declared. The declarations are necessary in club to declare the functions prinfo which take, as parameters, pointers to these structures. Nosotros cannot define these functions here, because in their torso we will use names of the structures' members, which are not known still. Annotation that we declare ii functions of the same name. They differ sufficiently in the type of their parameter, so this overloading is valid.
We and then define the structures Husband and Wife . This is the case when either of them contains a field which is the pointer to the other – therefore, declaring them was necessary. Note that it would be impossible for the structure Wife to contain a field of blazon Hubby (and not Married man* ) if Husband would comprise Wife — in such a case every Wife object would contain Husband which in turn would contain Wife , which in turn would comprise Husband , etc., ad infinitum. The function strcpy on line➊ copies C-strings and will be described in department on strings . The balance of the program should be clear; it produces:
Homo: Anthony; married woman Heather Woman: Heather; husband Anthony Human: Zachary; (single) Woman: Cecilia; (unmarried)Let us look at lines➋ and ➌. On line➋ the expression
h->wif->namedenotes the value of the fellow member proper noun of the object pointed to by the pointer wif which in turn is a member of the object pointed to by h . In this way, having a pointer to a husband, we are able to extract the name of his married woman. Line ➌ contains an analogous expression
(*((*w).hus)).proper nounwhich allows united states of america to admission the name of the husband given a pointer to his wife. Note how the annotation with an „arrow" simplifies such expressions – all parentheses are necessary here.
T.R. Werner, April 18, 2013; 18:23
Source: https://edux.pjwstk.edu.pl/mat/260/lec/PRG2CPP_files/node81.html
0 Response to "Before a Structure Can Be Used It Must Be"
Post a Comment