Structures. Part 4. Structures and functions. Passing a structure to a function in the CLR. Returning a structure from a function
Contents
- 1. What are the ways of passing a structure to a function?
- 2. What are the ways to return a structure from a function?
- 3. Example of passing a native structure to a function by value
- 4. Example of passing a native-structure to a function by a pointer
- 5. How to pass in function a managed-structure which is declared with qualifier ref? Example
- 6. How to pass in function a managed-structure which is declared with ‘value’ qualifier? An example
- 7. How do I implement a return of a native-structure instance from a function? Example
- 8. Example of returning the pointer to a native-structure from function
- 9. How return a value-structure instance from a function?
- 10. Example of returning a pointer (^) to a value-structure
- 11. An example of a return a structure from function that is declared with the ref qualifier
- Related topics
Search other websites:
1. What are the ways of passing a structure to a function?
There are 2 ways to pass a native-structure to a function as a parameter:
- passing the structure by value. With this passing, a copy of the structural variable is made in memory. If the structure is large, then this method is inefficient. The advantage of this method is that all manipulations with a copy of the structure in a function do not affect the original variable;
- passing a pointer to the structure. In this case, only the pointer to the structure is passed and not the entire structure. If the structure occupies a large amount of memory, such a method provides rapid passing the values of structural variable in function. This is due to the fact that only the pointer to the structure is passed. The disadvantage of this method is that in a function you can accidentally change the values of the original structural variable, in those cases when it is undesirable.
2. What are the ways to return a structure from a function?
Just as with the transfer of a structure to a function (see p. 1), there are 2 ways to return:
- returning the structure by value;
- returning the pointer to structure.
Advantages and disadvantages of each method are the same as described in paragraph 1.
3. Example of passing a native structure to a function by value
Let the “MyStruct.h” module have the native-structure declarations:
// A native structure that describes a point on the coordinate plane struct MyPoint { int x; int y; };
Let in some class the function EqualPoints(), which compares two points on a coordinate plane is declared. The function returns true if the points are equivalent (equal to each other). Otherwise, the function returns false.
// a function that compares two points public: bool EqualPoints(MyPoint p1, MyPoint p2) { bool f = false; if ((p1.x == p2.x) && (p1.y == p2.y)) f = true; return f; }
Then the use of the EqualPoints() function can be:
// connecting the module "MyStruct.h" #include "MyStruct.h" ... // Passing of a native-structure to a function by value bool f_equal; MyPoint pt1, pt2; // p1, p2 – Variables of type "structure" // Filling in with values pt1.x = 23; pt1.y = 35; pt2.x = 23; pt2.y = 35; f_equal = this->EqualPoints(pt1, pt2); // f_equal = true pt1.x = 100; f_equal = EqualPoints(pt1, pt2);
4. Example of passing a native-structure to a function by a pointer
Let the native-structure be given:
// native-структура struct MyPoint { int x; int y; };
Below is implemented a function that compares the value of structural variables for equality. The function receives a pointer to a structure.
// Passing a pointer to the MyPoint structure bool EqualPointsP(MyPoint * p1, MyPoint * p2) { bool f = false; if ((p1->x == p2->x) && (p1->y == p2->y)) f = true; return f; }
The program code that demonstrates the use of the EqualPoints() function.
// Passing the structure using a pointer MyPoint p1; MyPoint p2; bool f_equal; p1.x = 28; p1.y = 35; p2.x = 28; p2.y = 35; f_equal = EqualPointsP(&p1, &p2); // f_equal = true p2.y = 100; f_equal = EqualPointsP(&p1, &p2); // f_equal = false
5. How to pass in function a managed-structure which is declared with qualifier ref? Example
Let the following ref-structure be given.
// ref-structure ref struct MyPointRef { int x; int y; };
Structures with ref-qualifier are structures of referenced type. For such structures, memory should be allocated using the gcnew utility. Therefore, it is possible to pass a reference to such structures in a function.
Let the function LengthRef() be given, which determines the length of the line that connects 2 points. The function receives two ref-structures as parameters.
// a function that determines the length between two points float LengthRef(MyPointRef ^p1, MyPointRef ^p2) { float l; l = Math::Sqrt((p1->x-p2->x)*(p1->x-p2->x) + (p1->y-p2->y)*(p1->y-p2->y)); return l; }
Using the LengthRef() function in some code.
// passing the ref-structure to a function MyPointRef ^ pt1; MyPointRef ^ pt2; float len; // memory allocation for ref-structures pt1 = gcnew MyPointRef; pt2 = gcnew MyPointRef; // filling ref-structures with values pt1->x = 35; pt1->y = 35; pt2->x = 40; pt2->y = 40; len = LengthRef(pt1, pt2); // len = 7.071068
6. How to pass in function a managed-structure which is declared with ‘value’ qualifier? An example
A managed structure declared with a ‘value’ qualifier can be passed to the function in one of two ways:
- by value;
- using a pointer.
Below are both ways for the value-structure MyPointValue, which has the following declaration.
// value-structure value struct MyPointValue { int x; int y; };
Way 1.
Let the function LengthValue(), which defines the distance between two points, be given. The function receives two structures of the MyPointValue type as the input parameter. Structures are passed as a parameter-value.
// determination of the distance between two points float LengthValue(MyPointValue p1, MyPointValue p2) { float len; len = (float)Math::Sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); return len; }
An example of using the LengthValue() function in another code.
// passing the value-structure MyPointValue pt1; MyPointValue pt2; float len; pt1.x = 35; pt1.y = 50; pt2.x = 40; pt2.y = 55; len = LengthValue(pt1, pt2); // len = 7.071068
Way 2. Passing of the structure by pointer.
Let the function LengthValue() be given, which receives two pointers to structures of type MyPointValue.
// function receives a pointer to the value-structure float LengthValueP(MyPointValue *p1, MyPointValue *p2) { float len; len = Math::Sqrt((p1->x-p2->x)*(p1->x-p2->x) + (p1->y-p2->y)*(p1->y-p2->y)); return len; }
Using the LengthValue() function in the program.
// passing the value-structure using pointer MyPointValue pt1; MyPointValue pt2; float len; pt1.x = 0; pt1.y = 0; pt2.x = 10; pt2.y = 10; len = LengthValueP(&pt1, &pt2); // len = 14.14214
7. How do I implement a return of a native-structure instance from a function? Example
You can return a native-structure:
- by value;
- using a pointer.
Let the structure MyPoint be given
// native-structure struct MyPoint { int x; int y; };
Let the program implement the function GetCenterLine(), which calculates the coordinates of the middle of the segment connecting 2 points. The function receives 2 parameters – the coordinates of the ends of the segment.
// Function that returns a native-structure // The function calculates the coordinates of the middle of the segment MyPoint GetCenterLine(MyPoint p1, MyPoint p2) { MyPoint res; res.x = (p1.x + p2.x)/2; res.y = (p1.y + p2.y)/2; return res; }
Demonstration of the return of the native-structure by value.
MyPoint pt1; MyPoint pt2; MyPoint res; // result, the memory is allocated pt1.x = 30; pt1.y = 20; pt2.x = 36; pt2.y = 40; res = GetCenterLine(pt1, pt2); // res - coordinates of the middle of the segment
8. Example of returning the pointer to a native-structure from function
Let the structure MyPoint be given
// native-structure struct MyPoint { int x; int y; };
Let’s implement the function GetCenterLine(), which gets 2 points and returns a pointer to the structure. In the body of the function, memory allocation for the structure is implemented using the operator new.
MyPoint * GetCenterLine(MyPoint p1, MyPoint p2) { MyPoint * res; // pointer to MyPoint structure // allocating memory for the structure res = new MyPoint; // Calculation of the middle of a segment - filling with values resP->x = (p1.x + p2.x)/2; resP->y = (p1.y + p2.y)/2; return res; }
Demonstration of work with the function GetCenterLine().
// Return the native structure using the pointer MyPoint * resPt; // Pointer to the structure - the memory for the structure has not yet been allocated MyPoint pt1, pt2; // instances of the structure pt1.x = 28; pt1.y = 40; pt2.x = 38; pt2.y = 50; // Call the GetCenterLine() function // for the pointer resPt, memory is allocated inside the function resPt = GetCenterLine(pt1, pt2); // test int d; d = resPt->x; // d = 33 d = resPt->y; // d = 45
9. How to return a value-structure instance from a function?
If a structure with a value qualifier is described in the CLR, then returning an instance of such a structure from the function is no different from the return of the native-structure (see section 7).
10. Example of returning a pointer (^) to a value-structure
If a structure is declared with a ‘value’ qualifier, then the function can return a pointer to this structure. Two types of pointers are allowed:
- A classic pointer, which is denoted by the symbol ‘*’. Returning such pointer from a function is no different from returning a pointer to a native-structure (see p. 8);
- a pointer designed to work with objects in the CLR. Such pointer is indicated by the symbol ‘^’. The memory for this pointer is allocated by the gcnew utility. The following is an example of a return from a function of such a pointer to a value-structure.
Let the structure with qualifier ‘value’ is declared
// value-structure value struct MyPointValue { int x; int y; };
Let’s implement the function GetCenterLineVP(), which receives 2 points and returns a pointer to the resulting value-structure. The resulting structure contains the coordinates of the center of the segment that connects the points. The function is as follows:
// Function returns a pointer to the 'value'-structure MyPointValue ^ GetCenterLineVP(MyPointValue p1, MyPointValue p2) { MyPointValue ^ pv; // Pointer to MyPointValue structure pv = gcnew MyPointValue; pv->x = (p1.x + p2.x)/2; pv->y = (p1.y + p2.y)/2; return pv; }
Demonstration of a function call from another program code:
// Creating instances of structures with initialization MyPointValue pt1 = { 20, 30 }; MyPointValue pt2 = { 40, 60 }; // pointer to the structure MyPointValue MyPointValue ^ resPt; // calling the function GetCenterLineVP() // Inside the function, memory for the structure is allocated, // to which resPt points resPt = GetCenterLineVP(pt1, pt2); // test int d; d = resPt->x; // d = 30 d = resPt->y; // d = 45
11. An example of a return a structure from function that is declared with the ref qualifier
For the structure, which is declared with the qualifier ref has certain features of use. Such structure is a reference type structure. Therefore, the function should return a reference to such a structure (a pointer to the structure). You can not return an instance of the ref-structure (by value) from the function (see paragraph 5).
Let the structure be declared
// ref-structure ref struct MyPointRef { int x; int y; };
Then the function that gets the 2 points as parameters and finds the center between the two points will be approximately as follows:
// Function that returns a ref-structure MyPointRef ^ GetCenterLineRef(MyPointRef ^p1, MyPointRef ^p2) { MyPointRef ^resPt; // Allocating memory for the resPt pointer resPt = gcnew MyPointRef; // Filling in the values of the pointer fields resPt->x = (p1->x + p2->x)/2; resPt->y = (p1->y + p2->y)/2; return resPt; }
Demonstration of the use of the function in another program code.
// pointers to the ref-structure MyPointRef ^pt1; MyPointRef ^pt2; MyPointRef ^resPt; // memory allocation for pointers pt1, pt2 pt1 = gcnew MyPointRef; pt2 = gcnew MyPointRef; // Filling in with values pt1->x = 20; pt1->y = 20; pt2->x = 30; pt2->y = 40; // calling the function GetCenterLineRef() // the memory for the resPt pointer is allocated inside the function resPt = GetCenterLineRef(pt1, pt2); // test int d; d = resPt->x; // d = 25 d = resPt->y; // d = 30
Related topics
- Structures. Part 1. Composite data types. The template of structure. Structural variable. Structures in CLR. Declaring and initializing a structured variable
- Structures. Part 2. Memory allocation for the structure. Nested structures. Arrays of native structures
- Structures. Part 3. Working with managed-structures in CLR. Qualifiers ref and value. Declaring structural variables. Arrays of managed-structured variables. Initializing of managed-structures
- Functions. Part 1. Function declaration. Actual and formal parameters (arguments). Passing arguments to a function by value and by reference. Function prototype
- Functions. Part 2. Functions and arrays. Passing a one-dimensional and multidimensional array to a function. Passing a structure and a class to a function