PDA

View Full Version : Simple question about struct members and pointers




animefx
Nov 30, 2011, 12:28 PM
I've been reading the Big Nerd Ranch book on Obj-C and before I get to the chapter on Obj-C and objects, I'm making sure I understand everything he is teaching us about C.

My confusion regards structs... When he first introduces structs he says you are able to access it's members simply like:

typedef struct {

int age;
float weight;
} Person;

int main(int argc, const * char argv[]) {

Person person;

person.age = 29; //very simple
person.weight = 175;

return 0;

}

However, a few pages later (or maybe it is the next chapter) he talks about accessing members of a struct using pointers, but instead of * he uses -> ... There is very little explanation about why -> is used though. If I'm able to access a struct just by saying person.age = 29; then the variable's scope must be available much like a global variable would be so why would I need to use -> ?



gnasher729
Nov 30, 2011, 12:43 PM
I've been reading the Big Nerd Ranch book on Obj-C and before I get to the chapter on Obj-C and objects, I'm making sure I understand everything he is teaching us about C.

My confusion regards structs... When he first introduces structs he says you are able to access it's members simply like:

typedef struct {

int age;
float weight;
} Person;

int main(int argc, const * char argv[]) {

Person person;

person.age = 29; //very simple
person.weight = 175;

return 0;

}

However, a few pages later (or maybe it is the next chapter) he talks about accessing members of a struct using pointers, but instead of * he uses -> ... There is very little explanation about why -> is used though. If I'm able to access a struct just by saying person.age = 29; then the variable's scope must be available much like a global variable would be so why would I need to use -> ?

Let's say you have a Person, and a pointer to a Person:

Person person;
Person* pperson = &person;

You change members of person using "."

person.age = 29;

You access the Person behind the pointer using *; you can change members of that person using ".". Since unary operands like * and . are evaluated from right to left, you need to use parentheses:

(*pperson).age = 29; // Not *pperson.age

An arrow is just a shortcut for (*xxx)., so you write shorter:

pperson->age = 29;

mfram
Nov 30, 2011, 01:07 PM
Pointers to structs are typically used when calling functions. Consider:


#include <stdio.h>

typedef struct {
int age;
float weight;
} Person;

void print_person(const Person *p)
{
printf("Age: %d Weight: %6.1f\n",
p->age,
p->weight);
}

int main(int argc, char *argv[]) {

Person person;

person.age = 29; //very simple
person.weight = 175;

print_person(&person);

return 0;

}


In C, it is usually a good idea to pass structs to functions using pointers. If you pass a struct to a function then the compiler has to allocate space on the stack and make a copy of the struct to send to the function. If you pass a pointer to a struct to a function then the compiler only needs to pass a small pointer to the function. Less space and less time. C++ dealt with this issue by creating the concept of "reference" parameters.

Because "(*p).age" is cumbersome syntax, "p->age" is used.

subsonix
Nov 30, 2011, 02:00 PM
Another important reason to use a pointer to a struct is when you need a function to modify the struct. Passing the struct by value will create a new struct that is local to that functions scope, thus if you modify the struct inside the function you are not modifying the struct you passed to the function but a local copy.

animefx
Nov 30, 2011, 02:04 PM
ok, thanks I think I understand why structs would be passed to other functions via pointers, but I'm still not clear on how exactly to pass a struct as an argument to a function

in main() I could say MyFunction(person); // assuming person is a struct variable

but then when I have the MyFunction parameters I'm not sure how to handle that, example:

void MyFunction(???what type if a struct is being copied into this parameter??? someVar ) {

...do something...

}

subsonix
Nov 30, 2011, 02:11 PM
void MyFunction(???what type if a struct is being copied into this parameter??? someVar ) {

...do something...

}




struct person {
int age;
char *name;
};

// later on
void myFunction(struct person *p) {
p->age = 123;
p->name = strdup("Joe");
}




For a version that does not take a pointer, just omit the *.

BTW, note that if you use strdup, you will need to free p->name as strdup() allocates memory to hold the string: "Joe" in this case.


Edit: actually your example of weight is probably better as an example, then you don't need to worry about the string and it distracts from the discussion about structs here. You could name your struct with the persons name.

Mac_Max
Nov 30, 2011, 02:15 PM
You're getting a little confused by all the keywords flying back and forth. Struct isn't a type. You can't do this:

void MyFunction(struct aPerson){
...
}

Struct is a keyword that signals you're creating a data structure and the name you give it is the type.

typedef struct //struct is a keyword
{
int age;
float weight;
}
Person; //Person is the type's name.

As such you can see how to pass structs from nfram's example:


//in main:
...
print_person(&person);
...

void print_person(const Person *p)
{
printf("Age: %d Weight: %6.1f\n",
p->age,
p->weight);
}

That's how you pass a struct my pointer.

This is how you pass a struct by value:


//in main:
...
print_person(person); //notice the lack of &
...

void print_person(Person p)
{
printf("Age: %d Weight: %6.1f\n",
p.age,
p.weight);
}

At first pointers can be a little weird to think about and sometimes scary. You'll get it though.

Hope this helps :).

animefx
Nov 30, 2011, 02:41 PM
Thank you Mac Max and everyone else who replied. I understand now. When I get home tonight I'll try and write some code. I hope someday soon I can get to the point where pointers are second nature.