David542
David542

Reputation: 110572

Using a struct vs a pointer to a struct

I was working on the following as an example to see the differences between passing an object directly and then passing a pointer to it:

#include "stdio.h"

// Car object
typedef struct Car {
    char*           name;
    unsigned int    price;
} Car;

void print_car(Car car) {
    printf("<Car: %s, Price: $%d>", car.name, car.price);
};

void print_car2(Car *car) {
    printf("<Car: %s, Price: $%d>", car->name, car->price);
};

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

    Car chevy = {chevy.name = "Chevy", chevy.price = 45000};
    print_car(chevy);

    Car mazda = {chevy.name = "Mazda", chevy.price = 30000};
    print_car2(&mazda);

    return 1;

}

Other than the first approach being much more readable and easier to understand for me, what are the differences between the two? When would passing a pointer be the only option, and why do both work in the above case?

Upvotes: 3

Views: 477

Answers (3)

Tsak
Tsak

Reputation: 133

In general (not only for structs) passing a variable to a function will make a copy of this variable so if you want to alter this variable you ll have to return the value of the altered copy but you may want to alter the variable and return something else, in this case you have no other choice of passing a pointer as argument exemple :

first exemple with passing a variable

int useless_func(int nb) /*nb is actually a copy of the variable passed as argument */
{
    nb++; /* the copy was incremented, not the real variable */
    return nb; /* the new value is returned */
}
int main()
{
    int nb = 1;

    useless_func(nb); /* here nb is still = 1 cause it wasn't altered by the function */
    nb = useless_func(nb); /* here nb is = 2 cause it took the return value of the func */
}

now a second stupid exemple with pointer :

char *useless_func(int *nb) /* nb is now a pointer to the variable */
{
    *nb++; /* the derefencement of the pointer (so the variable value) was incremented */
    return strdup("This is a useless return"); /* we return some other stupid stuff */
}
int main()
{
    int nb = 1;
    char *str = useless_func(&nb); /* now nb is = 2 and str is an allocated useless string woohoo */
}

Upvotes: 3

sekomer
sekomer

Reputation: 742

When a function is called, the arguments in a function can be passed by value or passed by reference.

void print_car(Car car)

In here you are directly passing an object to the function, that means it will be copied into the functions stack and destroyed after function call ends. This method should be avoided because copying is expensive and unnecessary. Also if your objects are quite big, this operation will take a lot of time

void print_car2(Car *car) {

In this situation you are passing a pointer to the object which is called pass by reference, that means you are working with the original object and changes you make will directly affect it. It's a lot faster because you are not moving your object, but you should be careful about alter of original data

Upvotes: 3

klutt
klutt

Reputation: 31459

There are two reasons to use the second approach:

  1. If you want to avoid copying the whole struct. If the struct is big, this can affect performance.
  2. If you want to modify struct that you're passing.

Upvotes: 5

Related Questions