-1

I wanted to ask the author, caf , from Understanding functions and pointers in C

I realized I can't ask the question on that same page.

I'm still confused with using & to pass the value of pointer into a function. I always thought &q is just passing the address of q, how is it going to translate the value of q into int sqp(int * x)?

user3782604
  • 330
  • 1
  • 19
  • You should ask there via comment, but unfortunately you do not have enough reputation to comment. Answer some question here and do some editing on posts to get some reputation and then go back to ask same there. Closing (but not down voting) as unclear what you are asking. – haccks Jun 27 '14 at 10:07
  • 5 answers / asked 18 mins ago = 1.39 answers / 5min .. – ikh Jun 27 '14 at 10:19
  • `&`, when used as a prefix operator, means "take the address of". So `&someIntVar` returns an address that is an `int*` (pointer to `int`). When you pass an address of a value, you do not directly pass the value, of course, but the receiver of the address can "dereference" the received pointer to fetch (or set) the value. – Hot Licks Jun 27 '14 at 15:26

8 Answers8

2

There is no "translation".

Your function

int sqp(int *x);

takes one argument, x, whose type is int *, i.e. "pointer to integer".

So, to call it you need to pass it a pointer to an integer, i.e. the address of an integer.

The & prefix operator is used to compute the address of its argument, thus you can do:

int foo = 4711;
sqp(&foo);

to call the sqp() function with the address of the variable foo.

unwind
  • 391,730
  • 64
  • 469
  • 606
1

Using:

sqp(&q);

you pass the address of q as an argument in function int sqp(int *x).

From now on, inside this function, using x you get this address itself.

Using *x you get the value contained in this address in the memory.

This is how we can "simulate" pass by reference in C, by passing by value the address of the variable itself as an argument in the function.

Community
  • 1
  • 1
chrk
  • 4,037
  • 2
  • 39
  • 47
1

Like you said &q pass memory address of the variable q to function, so what we send to the function is just the address of q. The function doesn't need to translate any value because it access directly the original value as it has address stored in the pointer x and every time you do something like *x=7; with the * you dereference a variable, that means that it are not modifying the variable x, instead modifying whatever x is pointing.

haccks
  • 104,019
  • 25
  • 176
  • 264
sir psycho sexy
  • 780
  • 7
  • 19
0

Um, do you know pointers? I'll assume you do ^o^

There are two ways to pass argument. Pass-By-Value and Pass-By-Reference.

Maybe you are usually using pass-by-value.

#include <stdio.h>

void foo(int i)
{
    printf("[foo] `i` was %d\n", i);
    i++;
    printf("[foo] Now `i` is %d\n", i);
}

int main()
{
    int i = 0;
    printf("[main] `i` was %d\n", i);
    foo(i);
    printf("[main] Now `i` is %d\n", i);
}

Output is: (live example)

[main] `i` was 0
[foo] `i` was 0
[foo] Now `i` is 1
[main] Now `i` is 0

Yes, the i of main() is not changed! Why?

Because i is passed by value. When foo(i) runs, the value of i is copied and foo use the copy, not original i. So it cannot be changed.


However, you've seen the function which changes argument - for example, scanf.

int main()
{
    int i = 0;
    scanf("%d", &i);    /* `i` is changed!! */
}

How can it be changed? Because scanf uses pass-by-ref. Look at this example.

#include <stdio.h>

void foo(int *pi)
{
    printf("[foo] `i` was %d\n", *pi);
    (*pi)++; /* please be careful ^o^ */
    printf("[foo] Now `i` is %d\n", *pi);
}

int main()
{
    int i = 0;
    printf("[main] `i` was %d\n", i);
    foo(&i);
    printf("[main] Now `i` is %d\n", i);
}

Output is: (live example)

[main] `i` was 0
[foo] `i` was 0
[foo] Now `i` is 1
[main] Now `i` is 1

How is it possible? Because we passed the pointer of i, not the copy of i. foo has the pointer of i, so it can access the i, which main has. We call it pass-by-reference.

I hope that it can help you!

ikh
  • 10,119
  • 1
  • 31
  • 70
  • *Because `scanf` uses pass-by-ref.*: Where did you learn this ? – haccks Jun 27 '14 at 10:26
  • @haccks Hm, what do you mean? – ikh Jun 27 '14 at 10:30
  • I mean where did you come to know about *pass by reference* in C? – haccks Jun 27 '14 at 10:31
  • @haccks Oh, I've got the point.. speaking strictly, it is pass-by-value of pointers, however the meaning of code is equal to pass-by-reference. OP's case is that (I guess..) – ikh Jun 27 '14 at 10:36
  • Strictly speaking, *pass by value* and *pass by reference* are different things. – haccks Jun 27 '14 at 10:41
  • @haccks You're right of course, but this code means pass-by-ref. (`i` is changed through pointers) I think it's okay to call it pass-by-ref. – ikh Jun 27 '14 at 10:46
  • Read [this](http://www.parashift.com/c++-faq-lite/refs-vs-ptrs.html) and [this](http://stackoverflow.com/q/8571078/2455888). – haccks Jun 27 '14 at 10:54
  • @haccks of course it's not, but with knowledge about arrays, we can use it as if arrays were pointers (although it's different from pointers). And I think our case have much less confusing points than arrays' case. – ikh Jun 27 '14 at 10:57
  • @haccks And notice that we're in C *not C++*. There's no `int &`. – ikh Jun 27 '14 at 10:57
  • Yes. That's why I said there is no *pass by reference* in C. – haccks Jun 27 '14 at 10:59
  • @haccks Yes. Since there's no byref, pass-by-pointer is used as pass-by-ref, and it's widely-used convention, and there's almost no confusing point (except some theoretical arguments, which we're doing), unlike arrays' case. Because of these reasons, I think it's okay to say it pass-by-ref. – ikh Jun 27 '14 at 11:05
0

Slightly shortening the example from the answer in the linked question:

void sqp(int *x) {
   *x = 10;
}

void foo() {
    int value = 42;
    sqp(&value);
}

So sqp is a function which wants to return data via its parameter, which means it has to know where to write to. This information is a pointer -- the memory address to use. When passing the C language won't automatically pass the pointer but a statement like sqp(value); (if the compiler doesn't forbid due to incompatible types) would pass the value, in this case 42. The function sqp then would see the 42 and interpret it as address and try to write to memory location 42 which most likely isn't the place where the data should go.

Now the question is why the compiler can't make the deduction itself. The function requires a pointer to int and we provide an int so it might be deduced automatically.

I see at least two reasons for not doing the deductions

  • It makes the calling code clearer - the & tells the reader we're passing the address and the value might be changed
  • Deduction is not possible in all cases. i.e. with a function expecting a void * it might for the compiler not clear whether an extra level is needed when a pointer is already provided or not.
johannes
  • 15,807
  • 3
  • 44
  • 57
0

Yes, &q is the address of q. The value of q isn't "translated" - it's just that if you have the address of q, one of the things you can do with that address is to access the object q itself.

caf
  • 233,326
  • 40
  • 323
  • 462
0

So let's look at the sqp function definition again:

int sqp( int *x ) { ... }

Declarations in C are based on the types of expressions, not objects; if you have a pointer to an integer named x and you want to access the integer value being pointed to, you dereference x with the unary * operator, like so:

int y = *x;

The type of the expression *x is int, so the declaration of the variable x is written as

int *x;

When you hear someone use the phrase "declaration mimics use", this is what they mean.

When we call the function as

y = sqp( &q );

the expression &q yields the address of q, and the type of the expression is int *. The parameter x in sqp receives that address value.

Thus, the expression *x in sqp is equivalent to the expression q in the calling function; both expressions refer to the same object in memory, and both evaluate to the same value. Likewise, the expression x in sqp is equivalent to the expression &q in the calling function; both will evaluate to the address of q.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

In case of call by reference an address is passed so that changes can be made by referring to address (i.e reference) and if you are passing address in argument you should have some mechanism to point to that address .And Pointer is something that points to the address so in calling if you have passed the address you have to use pointer in definition to point to it. example.

calling(&a); //passing address

void calling(int *b) //Pointing to address of 'a' via pointer 'b'
{   
 //some code

}
Sparsh
  • 247
  • 1
  • 12