Hello, and welcome back. Last thing I want to talk about concerning structures
is how they're related to functions, how you can pass structures
as an argument to a parameter and a function
and how this is more efficient as well.
So structures as arguments to functions.
After declaring a structure
named Family. In this example we're going to create a named family,
how do we pass this structure as an argument to a function.
So we have this structure called Family.
We have a bunch of character arrays in here
name, father and mother and then we have an int age.
That's our structure definition.
We know it's a structure because the struct keyword is there followed by the tag name
we have our curly braces and so forth.
Now how do we actually pass that structure
to a function called siblings?
Well, you would do it just like you declare the structure,
you would say the type as the parameter name.
It's really straightforward. So in this case, we have Boolean siblings.
Siblings is returning a Boolean.
And it's taking two parameters, two struct parameters.
You have to identify the struct type which is type struct family.
Now in more advanced c, you could actually
do a typedf on this struct and name it something else and you could shorten
the name here, but we haven't talked about typeds.
That would probably be better.
But this is really how you would need to do it. You would have to define the entire
type, which is struct family and then the variable name, just like any other parameter.
So here we're passing in two parameters, member one and member two.
They're both of type struct family.
Then inside of our function, if we want to access members,
we access members just like normal.
Member one and member two, they're not pointers so we don't use the dash then greater than,
we only do that on the pointers because we need to de-reference them to see what they're pointing to.
Because they're not pointers, we can just do dot. So member one dot mother, member two dot mother.
Member one dot mother and mother two dot mother
are character arrays, and character arrays are pointers essentially.
So we can pass them to the str compare. Str compare is going to return equals if they're the same,
So what we're doing here is we're checking
member one mother and member two mother are the same. And if they are, we're going to return true.
Because if they both have the same name and that really would be the
last name then they're siblings.
Pretty straightforward.
Easy to pass arguments to functions
as long as the function declaration has that type struct in there.
So this function, again, two parameters each of which is a structure
of type family.
What about if we want to have pointers to structures as function arguments.
And I mentioned earlier, this is better to do because
we are doing pass by value and c.
When you do pass by value, you copy.
If you have a structure that contains a lot of data,
a lot of large structures as arguments,
you have to copy everything in that structure
to the actual function.
So that could take some time
to copy those large structures over.
Well, if you have a pointer, all you have to do is copy the address
which is much quicker. So pointers to structures
are used as parameters and functions to avoid memory consumption
and the time it takes to copy of all the structures.
Now if you have a small structure, no big deal,
but definitely want to use pointers and structures that are big.
So in this case, what do you do, you still specify the name of the types of structure,
you just put the asterisk beforehand,
very simple. And if you didn't want
any of the any of the data inside the structure to change, you could use constant before the structure type.
If you didn't want the address to change, you would put the constant after the struct family pointer.
But here, we're doing the same thing. But now we're going to access it differently
because now that it's a pointer we can use the dash greater than,
that new symbol to access instead of using the dot.
We don't have to use the dot here. Because
remember, pointers you have to de-reference first so you'd have to put it in parentheses,
it's more syntax to de-reference the pointer then you'd have to put the dot outside the parenthesis
because it has higher precedence, much easier to use the dash than greater than.
Dash and greater than mother,
dash and greater than mother they're both pointers, they can be passed in the str compare.
If they're the same, return true. Otherwise, return false, pretty straightforward.
You can also use the const modifier as I mentioned
if you don't want to allow any modification of the members of the struct.
What the struct is pointing to then you put the const before the pointer.
You could put the const actually before family as well.
In this case, family has a typef.
So here
it would really be construct family or struct family const pointer.
And then again access the same way, you're not modifying anything. So you're good to go.
Compiler is not going to complain.
You can also use the constant modifier if you don't want to allow any modification
of the address itself.
Any attempt to change these structures will cause an error message during compilation.
So here you would say
family star and you put the constant after the star.
And what this is saying is you can't change the value of p-member,
the value of the pointer, which is an address.
But again, this is not very useful because
when you pass by value, you're actually passing in a copy the address.
So this is redundant, you don't need to do this, but you can.
And here, again, you want to be able to change the address of what p member is.
And in this case, you're just accessing the data anyways to see if they're equal.
The indirection operator in each parameter definition
is now in front of the constant keyword.
That asterisk, it's not in front of the parameter name.
You cannot modify the address stored in the pointers because it's after the asterisk.
If it was in front of the parameter name type,
then you want to be able to modify the actual what it's pointing to.
If we had that indirection operator in front of the parameter name,
what that would in the constant before it,
that would mean you want to be able to modify what it's pointing to. This is just saying the address.
So you cannot modify the address stored in the pointers.
It's the pointers that are protected here not the structures to which they point,
just like constant and other pointer parameters, no difference with structs.
If you want to return a structure from a function that's a pointer,
the function prototype has to indicate this return value in the normal way
in the declaration.
So here you'd have to say struck to date my fun
pointer or not pointer,
it doesn't matter. This is a prototype for a function taking no arguments that returns a structure of type date,
very easy to return a structure from a function. And what is the value of this.
Well, now we can return more than
one element or one data item from a function.
If you're returning a struct, you could return 10 values, 10 different data items.
How cool is that. The struct allows you to return more than one from a function.
Very, very valuable.
So it's often more convenient to return a pointer to a structure as opposed to just the structure.
When you return a pointer to structure,it's created on the heap
because all pointers are created on the heap.
This means it's going to be around a bit longer.
And this means you can delete it and manage it at arbitrary times.
So in this example, we're creating a struct named funds.
It contains a character array named bank,
contains a double, another character named saved
of a particular length. Just assumed fun length is equal to 50.
And then it has a double saved one.
We have a function called sum which takes that structure as a parameter.
And all we're doing is inside that is we're returning
a - the bank fund from the first structure plus the save fund,
and that's going to return the amount that they have in their bank.
In this example, sum is just a double.
We're not returning a pointer. We're just taking a pointer as a parameter.
And so in our main function, we're creating a structure variable
called stan of type struct funds.
We're initializing it with some values, and then we're printing out
the total of calling sum. And we just pass this structure like we pass any variable.
We don't have to de-reference it it's not a pointer. We don't have to really do anything special.
We just make sure that in the function declaration we have that struct type there,
but everything else looks normal.
A couple reminders.
I mentioned earlier that you should always use pointers when passing structures to a function.
Why? Because remember, older versions of c
don't allow
structures to be passed, but they do allow pointers.
So you can avoid any kind of backward compatibility.
If you're using an older version of c, your program is going to work.
So just passing in that single address
is also more efficient because of time copying.
But if you do this, if you do pass in a parameter that's a pointer
to a struct inside of a function, it does have less protection for your data.
So some operations in the called function could inadvertently affect
the data in the original structure.
And this is where you want to use the const qualifier.
And you'd use the const before
the actual type, not after the asterisk
and before the parameter name, before the type.
The advantage of passing structures is arguments,
the function works with copies of the original data.
It's safer than working with the original data.
So that's really the only time you want to pass a structure as an argument that's not a pointer.
And the programming style tends to be a little bit clearer.
The main disadvantages of passing structures as arguments as opposed
to passing a structured pointer as an argument
is older implementations might not handle the code,
it wastes time and space
and it's especially wasteful when you have large structures we have to do
lot of copying for each member. So keep this in mind.
For the most part you want to pass in pointers to structures,
much more efficient and saves time.
Programmers use structure pointers as function arguments for reasons of efficiency
and they use constant when necessary. And this is the combination that you want to do.
If you're worried about the protection, just use the function
pointer for efficiency and then usethe const
const so nothing gets screwed up inside the function,
just like really normal pointers more or less,
but with pointers it's even more important with the efficiency because
of large structures.
Passing structures by value is most often done for structures that are small,
and those are kind of the rules you want to think about.
Okay to pass a structure that's not a pointer as long as it's small.
Again, some important concepts related to structures
and passing pointers as parameters, arguments
and returning pointers as well. Now, we can actually start implementing
some of this. We provide many examples. We understand the concepts. We understand the syntax.
Now I want to present you with a couple challenges that has you actually doing this,
has you memorized in the syntax that now if you ever want to create a structure in the program,
you know how to do it like the back your hand.
So we're going to have a couple challenges in our next couple lectures
to get you familiar with all this stuff we talked about concerning structures.
Thank you.