0

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?

2
  • 7
    Because it already is a pointer. The statistic in main is an actual object. Calling function1(string, &statistic); hands a pointer to function1. So when function1 calls itself, it can just use the pointer it was given by main(). Commented Apr 10, 2015 at 10:38
  • Declare your function as void function1(char *string, Statistics *ptr) and you'll see why the recursive call is function1(string1, ptr); Commented Apr 10, 2015 at 11:00

3 Answers 3

4

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
Sign up to request clarification or add additional context in comments.

Comments

1

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);
}

2 Comments

So basically, first time when I call function1 (from main) with & I give him address location for example 444555666 and *statistic is something that that address hold for example 444555666 holds 5, but in statistic I still have that same location. Am I right?
That's basically it, yes
0

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'.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.