Velocity Reviews > Trying to understand pointers for function paramaters

# Trying to understand pointers for function paramaters

Richard Hengeveld
Guest
Posts: n/a

 09-29-2004
Hi all,

I'm trying to understand how pointers for function parameters work. As I
understand it, if you got a function like:

void f(int *i)
{
*i = 0;
}

int main()
{
int a;
f(&a);
return 0;
}

It does what you want (namely altering the value of a).
I find this illogical. As far as I can understand, the address of "a" is
passed, and "*i" is set with this address not "i", as it should be in my
understanding.
What am I missing?
TIA

P.S.
I've really searched for this in the groups faq and elsewhere before I
posted.

Mark A. Odell
Guest
Posts: n/a

 09-29-2004
"Richard Hengeveld" <(E-Mail Removed)> wrote in
news:415ae427\$0\$76520\$(E-Mail Removed):

> Hi all,
>
> I'm trying to understand how pointers for function parameters work. As I
> understand it, if you got a function like:
>
> void f(int *i)
> {
> *i = 0;
> }
>
> int main()
> {
> int a;
> f(&a);
> return 0;
> }

Assume that 'a' exist at memory location 0x1000'0000. Now assume 'i' is
located at 0x1000'0004.

Before calling f():
-------------------
C name Mem. Addr. Contents (value located there)
------ ------------ ------------------------------
a 0x1000'0000: ???
i 0x1000'0004: ???

In function f() after the assignment to *i:
-------------------------------------------

C name Mem. Addr. Contents (value located there)
------ ------------ ------------------------------
a 0x1000'0000: 0
i 0x1000'0004: 0x1000'0000

so 'i' is a pointer that contains the value of the address of 'a'. Thus
weh you dereference 'i' via *i you now point to memory location
0x1000'0000. So if you modify what is as 0x1000'0000 then the value of 'a'
will be modified.

Simple, logical.

--
- Mark ->
--

Keith Thompson
Guest
Posts: n/a

 09-29-2004
"Richard Hengeveld" <(E-Mail Removed)> writes:
> Hi all,
>
> I'm trying to understand how pointers for function parameters work. As I
> understand it, if you got a function like:
>
> void f(int *i)
> {
> *i = 0;
> }
>
> int main()
> {
> int a;
> f(&a);
> return 0;
> }
>
> It does what you want (namely altering the value of a).
> I find this illogical. As far as I can understand, the address of "a" is
> passed, and "*i" is set with this address not "i", as it should be in my
> understanding.
> What am I missing?

Yes, you're passing the address of "a" to the function "f".

Incidentally, "i" is a poor name for the parameter. "i" is commonly
used as a name for an int variable; the parameter is a pointer to int.
It's perfectly legal, but potentially confusing.

In the assignment

*i = 0;

"i" is a pointer, and "*i" is an int object. You're assigning the
value 0 to an int object. Which int object? The one i points to,
which happens to be "a".

i = 0;

you'd be assigning a value to "i", which is a pointer object; the
value being assigned would be a null pointer.

It might be clearer if you change the names:

void f(int *ptr_param)
{
*ptr_param = 0;
}

int main(void)
{
int int_object;
f(&int_object);
return 0;
}

(In a real program, of course, variables should generally have names
that reflect what they're used for; for this toy example, it's more
important to show their types.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

E. Robert Tisdale
Guest
Posts: n/a

 09-29-2004
Richard Hengeveld wrote:

>
>
> I'm trying to understand how pointers for function parameters work.
> As I understand it, if you got a function like:
>
> void f(int* p) {
> *p = 0;
> }
>
> int main(int argc, char* argv[]) {
> int a;
> f(&a);
> return 0;
> }
>
> It does what you want (namely altering the value of a).
> I find this illogical. As far as I can understand,
> the address of "a" is passed,
> and "*p" is set with this address not "p"
> as it should be in my understanding.

Probably what is confusing you is the *formal* argument

int* p

This tells you that p is a pointer to an object of type int.
the statement

p = 0;

would assign the address value 0 to p.
The expression

*p

is a *reference* to (another name for) a
so writing

*p = 0;

is the same thing as writing

a = 0;

Richard Hengeveld
Guest
Posts: n/a

 09-29-2004

"E. Robert Tisdale" <(E-Mail Removed)> wrote in message
news:cjf5pb\$fg5\$(E-Mail Removed)...
> Richard Hengeveld wrote:
>
> >
> >
> > I'm trying to understand how pointers for function parameters work.
> > As I understand it, if you got a function like:
> >
> > void f(int* p) {
> > *p = 0;
> > }
> >
> > int main(int argc, char* argv[]) {
> > int a;
> > f(&a);
> > return 0;
> > }
> >
> > It does what you want (namely altering the value of a).
> > I find this illogical. As far as I can understand,
> > the address of "a" is passed,
> > and "*p" is set with this address not "p"
> > as it should be in my understanding.

>
> Probably what is confusing you is the *formal* argument
>
> int* p

Yes, that is exactly what is confusing me.
I understand you set a pointer (if you're not passing to functions) by:

int a, *p;
p = &a;

and not:

p* = &a

Wouldn't it be more logical if it was something like:

void f(int i) {
int *p
p = i;
p* = 0;
}

int main(int argc, char* argv[]) {
int a;
f(&a);
return 0;
}

?

Keith Thompson
Guest
Posts: n/a

 09-29-2004
"E. Robert Tisdale" <(E-Mail Removed)> writes:
> Richard Hengeveld wrote:
>
>>
>>
>> I'm trying to understand how pointers for function parameters work.
>> As I understand it, if you got a function like:
>>
>> void f(int* p) {
>> *p = 0;
>> }
>>
>> int main(int argc, char* argv[]) {
>> int a;
>> f(&a);
>> return 0;
>> }
>>
>> It does what you want (namely altering the value of a).
>> I find this illogical. As far as I can understand,
>> the address of "a" is passed,
>> and "*p" is set with this address not "p"
>> as it should be in my understanding.

Damn it, Tisdale, that's not what he wrote. Here's what Richard
Hengeveld *actually* wrote in the article to which you replied:

] I'm trying to understand how pointers for function parameters work. As I
] understand it, if you got a function like:
]
] void f(int *i)
] {
] *i = 0;
] }
]
] int main()
] {
] int a;
] f(&a);
] return 0;
] }
]
] It does what you want (namely altering the value of a).
] I find this illogical. As far as I can understand, the address of "a" is
] passed, and "*i" is set with this address not "i", as it should be in my
] understanding.

By prefixing the material with "> ", you're telling us that you're
quoting what the previous poster wrote; by preceding it with "Richard
Hengeveld wrote:", you're saying so explicitly. In fact, you're
showing us your version of what you think he should have written.
You've quietly changed the layout of his code (I like his better),
changed the name of the parameter from "i" to "p", and added
gratuitous argc and argv parameters to main.

Now if you had presented your modified version as an improvement of
Richard Hengeveld's code (which is what I did in my response), that
would have been ok. If you had mentioned that you were paraphrasing
what he posted rather than quoting it exactly, that would have been
acceptable as well. You could even have told us why you think your
modified version is an improvement. (In some ways it is, but that's
beside the point.)

You've done this before, and you've been called on it. I have no
realistic expectation that you're going to change your ways this time
either. I'm posting this mostly as a warning to other readers.

If E. Robert Tisdale claims that someone else has written something in
a previous article, don't believe it unless you've verified it by
reading the actual article that he claims to be quoting. Trust him at

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Default User
Guest
Posts: n/a

 09-29-2004
Richard Hengeveld wrote:

> Wouldn't it be more logical if it was something like:
>
> void f(int i) {
> int *p
> p = i;
> p* = 0;

How would it be more logical to assign an integer to a
pointer-to-integer? What problem are you trying to solve?

Brian Rodenborn

Richard Hengeveld
Guest
Posts: n/a

 09-29-2004

"Default User" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Richard Hengeveld wrote:
>
>
> > Wouldn't it be more logical if it was something like:
> >
> > void f(int i) {
> > int *p
> > p = i;
> > p* = 0;

>
>
> How would it be more logical to assign an integer to a
> pointer-to-integer? What problem are you trying to solve?

I'm not trying to solve a problem. I'm just trying to understand C.
In a function without pointer arguments, the argument(s) of that function
are set by value passing:

f(int i)
{
printf("%d", i);
}

int main()
{
int i;
f(i);
return 0;
}

I just don't understand why this is (a little bit) different with pointer
arguments.

E. Robert Tisdale
Guest
Posts: n/a

 09-29-2004
Richard Hengeveld wrote:

> I understand you set a pointer (if you're not passing to functions) by:
>
> int a, *p;
> p = &a;
>
> and not:
>
> p* = &a
>
> Wouldn't it be more logical if it was something like:
>
> void f(int i) {
> int *p
> p = i;
> p* = 0;
> }
>
> int main(int argc, char* argv[]) {
> int a;
> f(&a);
> return 0;
> }
>
> ?

I don't know.
I don't know why K&R chose these semantics
and not the semantics that you suggest.
suppose that you wanted to define a second pointer
to the same object. Would you write

int *p, *q;
p = i;
q = i;

And would you expect (p == q) to be true?

Keith Thompson
Guest
Posts: n/a

 09-29-2004
"Richard Hengeveld" <(E-Mail Removed)> writes:
[...]
> Yes, that is exactly what is confusing me.
> I understand you set a pointer (if you're not passing to functions) by:
>
> int a, *p;
> p = &a;

Right, this sets p to contain the address of a (or, equivalently,
causes p to point to a).

> and not:
>
> p* = &a

The unary '*' operator is prefix, not postfix. You could argue that
it would be easier if it were postfix, but that's not how the language
defines it.

If you meant
*p = &a;
that wouldn't make sense. Since p is a pointer to int, *p is an int,
but &a (address of a) is a pointer to int. The types don't match.

In an assignment, the left hand side has to be an expression (e.g., a
name) that refers to an object of some type, and the right hand side
has to be an expression of that same type (not necessarily an object).
(That's not quite true (there are implicit conversions in some cases),
but it's a good enough first approximation.)

So given:
int a;
int *p;
we can have
a = 42; /* the name "a" refers to an object of type int,
"42" is an expression of type int */
p = &a; /* the name "p" refers to an object of type pointer-to-int,
"&a" is an expression of type pointer-to-int */
*p = 2+2; /* the name "*p" refers to an object of type int
(the object happens to be "a"), and "2+2" is an expression
of type int */

> Wouldn't it be more logical if it was something like:
>
> void f(int i) {
> int *p
> p = i;

No, p refers to an object of type pointer-to-int, but i is an expression
of type int. The types don't match. You can legally say "p = &i;".

> p* = 0;

p* is a syntax error. *p = 0; is legal, since *p refers to an object
of type int (assuming p has been initialized properly), and 0 is an
expression of type int.

> }
>
> int main(int argc, char* argv[]) {
> int a;
> f(&a);

The function f() expects an argument of type int; you're giving it an
argument of type pointer-to-int. Function argument types have to
match, just as the types in an assignment have to match.

> return 0;
> }

If you want the function f() to be able to modify an int object that
you pass to it, you have to pass the object's address, and f() has to
take an argument of type pointer-to-int. If f() takes an argument of
type int, it just gets a copy of the value of whatever you pass to it;
f() can do whatever it likes with its own copy, but that won't affect
the original object.

If f() is defined as:

void f(int i) { ... whatever ... }

then this:

int x;
f(x);

can't change the value of x, any more than this:

f(42);

can change the value of 42.

Some languages do have ways of specifying that an argument is passed
in a way that allows the function to modify the original object
(Pascal has VAR parameters, Ada as "in out" and "out" parameters, C++
has reference parameters). C doesn't have such a mechanism.

If you want to argue that C could be improved, there are several
things I can say in response:

1. You're right. C's declaration syntax in particular causes no end

2. It's not going to change. Any significant change would break
existing code. That's just not going to happen. If you want a
language with better syntax than C (and that's a subjective
judgement), you'll just have to use a language other than C.

3. If you're interested in C, you should probably learn the language
as it is before you start worrying about how it could be better. K&R2
(Kernighan & Ritchie's _The C Programming Language_, Second Edition)
is one of the best tutorials; buy or borrow a copy and read it.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.