Hello, and welcome back.
I would like to provide a solution to previous challenge in this lecture.
A demonstration of how you can have pointers as elements
inside of structure and also pass around pointers two
functions that are structures.
So let's bring up code blocks, create a new project.
This is going to be a console application, and we're going to name
this structure pointers example.
And so if you remember for the requirements for this, this was
basically just a product type structure that stored an item name,
a quantity, a price and an amount.
And the item name was going to be a character pointer.
You were going to have an amount that basically just
multiplied the quantity in price.
And then we had two functions that will take as parameters
pointers to a struct.
So the first thing we're going to do is we're going
to create our structure.
And I mentioned this earlier, but it's good to create the structure
globally because if you want to use it in multiple functions.
Creating the structure is really defining it.
You're not allocating any memory.
So there's no harm putting it globally.
And they usually go inside the header file anyways.
So to create a structure, we just say struct.
We're going to call this item, and we're going to have four elements.
We're going to have a character pointer, which we're just
going to call item name.
We're going to have a quantity.
We're going to have a float for price, and we're going to
have a float for the amount.
And that's how we can define our structure, pretty basic.
Now inside of our main function, we want to create a variable for the
structure type and also a pointer.
So the first thing we want to do is we just want to say struct item
with the name of the structure and then we'll just call this item.
And this is just creating an odd pointer.
This is going to allocate memory for the four variables and
elements inside the structure.
And so we want to create our pointer now, and we can just say struct item.
We're going to say p item because we usually name our
pointers with the prefix p.
So we say the asterisk, and we say p item.
And then in the next line, we just want to assign to
our pointer item, our item.
So we need to use the address of and we say item.
And so here we have memory allocated for elements in our
structure for our pointer.
We don't have any memory allocated for our character
pointer which is our item name, so that would be the next step.
Now you may ask why do we need to create the item struct.
We don't really.
We could just create the pointer, and the pointer is only going to create
memory for that struct item pointer.
It will allocate memory for the int and floats, but we still have
to do the item name allocation.
I just like doing this because this is usually the good practice.
Typically what you would do with the first item struct is you
would initialize it, and so you would have some initialization.
But we don't need to do that.
So the first thing we want to do is allocate memory for our item name.
So we can basically use a special operator to access
elements if it's a pointer.
Remember, for structures that are pointers, you have the dash
then greater than symbol that you can use to access the elements.
Otherwise, you'd have to de-reference the pointer to access the elements.
We could do something like this inside parentheses.
We could de-reference the pointer, so we'd have to do something
like star p item and then use the dot to access elements.
This is perfectly valid to do something like this.
But it is kind of extra syntax that you don't really need.
So c has special syntax that you can use whenever your
structure is a pointer if you want to access the elements.
You can basically just say the name of the pointer which is p item and
then use the dash then greater than.
And in this case, we want to allocate memory for item name.
So we're going to assign it what is returned from the malloc function.
Remember, the malloc function returns a void pointer.
So we have to cast it to a character star.
But we can just call malloc, just say malloc and then the size of
the bytes that we want to create.
In this case, we'll just say 30, and we'll multiply it by the size
of char, just in case char is a different size on different computers.
And this is going to allocate memory for our item name.
We need to do this because item name is a pointer inside the structure.
It doesn't have memory allocated for it when you
assign it to an other structure.
So we have to do this.
Now the first thing you want to do after you've allocated
the memory is check the malloc.
so we do want to check for null here.
We're just going to say if p item, if it's null that would say it's null.
Otherwise, you'd say if not, you could just say return or exit would probably
be better, exit the program if we weren't able to allocate memory and
you could pass it into negative one.
Otherwise, we want to read in an item, so we want to create a function.
The function that we're going to create is called read item.
Let's put up a function declaration up here above the structure.
It's just going to be reading in data into the struct that we passed to it.
It's not going to return any data.
So we can just say read item and it takes a struct, and
that's going to be a pointer.
So it's a struct item, asterisk I.
Now we could make this a constant so the values kind of change,
but we are changing the values.
But we could say constant struct, the values would not be able to change for
that pointer that it's pointing to.
If we did the constant after the asterisk, that would say the
address can't change or right before the asterisk something
like that after the name.
That would say the address can't change, but that's redundant
because we're passing by copy value.
We have our read item.
And while I'm up here I might as well do my print item.
That's just going to be the function declaration, function prototype.
Here, it's going to be very similar, also take a pointer.
Can have a space if you want after the asterisk or not?
Now we can define our read item below our main method.
And this is going to read in values of item and then
calculate the total amount.
So we can say void read item, have our pointer.
And inside here, we just want to use some scanfs really.
We're going to print out some messages to tell the user to enter information.
So we're going to say enter product name, and then
we're going to read it in.
So we're going to say scanf, and we have a pointer to a
struct, so we can access it using the dash then greater than.
We want to read in for scanf, the product name is a character buffer.
So we want to say percent s and then we're going to say I, we're
going to store it in the item name.
And we could go back and use the intellisense just go to item name.
We don't have to use the address of operator because
it's a character pointer.
We then want to print out and get the price, probably want to add some
line feeds in here, enter the price.
We're going to store that in the structure.
So again, the price is a float though.
So I'm going to say percent f, but we're going to also access it because
it's a pointer, we still want to use the dash then greater than.
Except this time, we're going to say price, and we need to get the
address of it, so we're going to put an ampersand in front of it
because price is not a pointer.
And then we're going to do the same thing for the quantity.
So quantity is an integer.
So we can say percent d, we still need to get the address of it, but we want
to store it in a different element, we want to store it in the quantity.
Now that we've stored or asked the user to enter three items
of information, now we can actually calculate the amount,
stored something in the amount.
The amount is just the quantity times the price.
So we still want to access the structure using our syntax, we
want to cast it, we want to sign the quantity times the price.
And that's the read item function.
Takes a structure pointer.
And so when we modify this pointer inside of the read item, it's going to
get modified outside of the function.
So whatever structure we pass into this function,
it's going to get modified.
It's going to store all the items, the item name, price
and quantity and amount.
So that reads in the data.
At this point, you'd want to test and you probably want to
compile and test before this.
But we can now call the read item method up in our main and pass it
in our structure that we created.
So we can say read item, and we can just say p item.
We don't have to pass in the address because it's a pointer,
so we just pass in our structure.
And then the next thing we can do is we can print it out.
And what this will show you is that the data is saved, p item is
being modified inside the function and it's being saved outside of
the function, the main function actually has saved those values.
So we can say print item passing in the pointer again, and then we
can define the print item function.
Print item is pretty basic.
It doesn't return anything, so we say void and we say
print item takes a pointer.
So we just say struct item star I, whatever you want to name it.
And then we just print out the data for the structure that was passed in.
So we would do something like printf name percent s, I item
name, I price, I quantity and I amount and then we format the data.
What's the last thing we have to do in the main after we
printed out the data, the really important free function.
We got to call free because we want to free the memory that
we allocated for the item name.
So we can just say free p item and then access the item name.
We don't want to free the entire structure because the entire
structure will be deleted on the stack when the function returns.
We just want to free what we malloced.
We only malloced for item name so we free that, and
then we return from the main.
So let's go ahead and try to build this.
And we do have an error.
Let's see it says struct item star.
So we had a mistake where the functions were defined
above the structure.
But the function of taking a parameter as a struct type.
So we have to have the structure defined above where we're using it.
So I move the functions down to lines 12 and 13.
Now we're able to compile.
Let's go ahead and run this.
And let's see what we get here.
We have one more error.
You have to make sure you check p item for null.
If you just say if p item for true, it's always going to be true.
So you can either check to say it's not true with the not symbol
meaning it's not null or you can check to see if it is null.
So I just added the null there.
So now we run it, we should be good to go.
We can enter the product name.
We'll say serial, and we'll say the price is 1.99.
And we'll say we have five of those.
And now we print it out, and we say serial dollar 99.
5, the total amount is 9.95.
The price though I don't like how the price is printed out.
So let's fix that.
In our print item, we can just say for price dor 2 f floats, now we'll look
a little bit better, and we run it.
We'll get a little bit of better format.
Four of them and now it looks a little bit better,
and everything's good to go.
So again, basic program using structures and pointers.
We created the structure at the top.
We have a member that contains a pointer, it's very efficient
to do that because we can just copy and addresses as
opposed to character arrays.
We have our two func declarations, read item print item that
take pointers destructs.
And then we create the pointer and assign it to a regular
structure inside of our main.
We allocate memory on line 22.
We make sure the memory is allocated successfully if it
wasn't we exit the program.
And then we call our two functions that take pointers
to structures, pass them in.
And then last but not least, we free the memory and
then we exit the program.
And the functions are pretty straightforward.
You take that pointer.
You access the pointer using the dash then greater than.
And you get the address of it for scanfs that don't
have pointers as elements.
And that's basically it.
I'll save this program, you take a look at it.
Let me know if you have any questions. Thank you.