Aleksandar Makragić
Aleksandar Makragić

Reputation: 1997

Pointers, structure, passing arguments, recursion

I have code like this:

typedef struct _Statistics {

  Some code here

} Statistics;

void function1(char *string, Statistics *statistic){

   Some code here

   function1(string1, statistic);
}
int main(){

   Statistics statistic;
   function1(string, &statistic);
}

This is probably idiotic question, but I don't understand pointers completely: I understand why I use & in main function, & send address of variable statistic, so that in function1 I can modify it. But why don't I use & in recursive function1?

Upvotes: 0

Views: 544

Answers (3)

user447688
user447688

Reputation:

Sometimes it helps to write it this way:

void function1(char* string, Statistics* statistic){

The variable statistic is a pointer to Statistics, not the Statistics itself. If you did this in function1:

   function1(string1, &statistic);

You would be passing a pointer to (because of the &) a pointer to (because of the * in the declaration) Statistics, which would be incorrect.

Your declaration of statistic in main as Statistic adds to the confusion: you're using the same variable name with different types in the two scopes.

With different variable names it's clearer:

typedef struct _Statistics {
  Some code here
} Statistics;

void function1(char* string, Statistics* ptrstat){
   Some code here
   function1(string1, ptrstat);
}

int main(){
   Statistics statistic;
   function1(string, &statistic);
}

Upvotes: 1

koan911
koan911

Reputation: 370

In general (i.e. most languages), you can pass by value or pass by reference. It will depend on the definition of the function and its 'signature'; i.e. the way it and its arguments are declared.

Pass-by-value is like an assignment and, if copying a larger structure, it will take longer. Also, the function only receives a copy, so you can make changes to the argument in the function, but that will only effect the function's local copy (the argument) and will make NO change to the original value (in the caller) that was passed to you.

By contrast, pass-by-reference simply passes a pointer (the address in memory) of the original value. This is much faster, (4 or 8 bytes), but it does means that the function can not only read but also write the caller's value. Sometimes you want this! Sometimes you don't.

In your main, you have the value of statistics. The function you are calling expects the address (*), so instead of passing the value, (statistic), you need to pass its address, (&statistic).

In the function, calling itself, you have a pointer to statistic (Statistics *) and you must pass a pointer to statistic (Statistics *): hence, just pass it, the pointer 'statistic'.

Upvotes: 0

nouney
nouney

Reputation: 4411

Because &statistic (in function1()) is the memory address of the pointer, not the address contained by the pointer.

The type of &statistic is Statistics** in function1().


Few words about pointers

Let's say we define the following variables:

char c = 'a';
char *p_c = &c;

Now, we will print the values and memory addresses of p_c and c:

printf("%c\n", c); // will print 'a'
printf("%c\n", *p_c); // will print 'a' 

printf("%p\n", &c); // will print the memory address of c
printf("%p\n", p_c); // will print the memory address of c

printf("%p\n", &p_c); // will print the memory address of p_c

Finally we define a char**, a pointer to a pointer to char:

char **p_pc = &p_c;

printf("%c\n", **p_pc); // will print 'a'
printf("%p\n", *p_c); // will print the memory address of c
printf("%p\n", p_c); // will print the memory address of p_c

Upvotes: 4

Related Questions