Re: Clarification: strtof won't work

From: Karl Heinz Buchegger (kbuchegg_at_gascad.at)
Date: 08/13/04


Date: Fri, 13 Aug 2004 14:11:33 +0200

OzBob wrote:
>
> Alwyn
>
> The <stdlib.h> library was not included initially but added in subsequently,
> with the result being a change in the incorrect values posted by the
> statement (but still incorrect, none-the-less)
>
> Now, what you referred to as pointer arithmetic,....
>
> Are you telling me that C will alter the value of a pointer as a result of a
> function, such as "strtof"? In other words, the compiler is altering the
> values of variables I have assigned (in this case the position of a pointer)
> without my explicit instruction to do so? Just to clarify, the system cannot
> guarantee that the contents I set of a variable (ie the position of a
> pointer) will not change when it is interrogated (not explicity altered,
> just when interrogated?). Is that what you are telling me?

It's basic C knowledge:

Assume you have a function

void foo( int i )
{
  i = 5;
}

int main()
{
  int j = 0;

  foo( j );

  // will j have a value of 0 or 5 ?
}

Now what happens here?
When foo is called, a copy of j is made and given to function foo,
where it becomes known as i. So i starts out with a value of 0.
Then in foo, i gets a new value: 5. But since i only received a copy
of the value in j, altering the value of i, will not alter j.

But sometimes this is exactly what one wants to do: alter the variable
passed to a function. In C this cannot be done directly. With the
only exception of arrays, everything in C is passed by value (that
is: a copy is made). So what can you do? You can pass the address
of j to foo(). foo() thus has access to j through it's memory address
and thus can change j;

void foo( int *i )
{
  *i = 5;
}

int main()
{
  int j = 0;

  foo( &j );

  // will j have a value of 0 or 5 ?
}

Here again, a copy is made that is passed to foo. But this time it is not
a copy of the content of j, but it is a copy of the memory address of j.

So the general idea is: If you want to enable a function to alter the
callers variable, which is of type T, then write

void foo( T *pT)
{
  *pT = whatever_you_want;
}

int main()
{
  T CallersVariable;

  foo( &CallersVariable );
}

Now, strtof (and strtod) has a capability: You give it a pointer to the start of the
string and strtof tells you where it stopped reading from that string. You do this
by passing a second character pointer to this function. But in order to alter that
second character pointer, the above pattern applies (the function wants to modify
the callers argument). Hence

T in this case is char*, so substitute T with char*

void foo( char* *pT )
{
  *pT = whatever_you_want_as_long_as_it_is_a_char_pointer
}

int main()
{
  char * SecondPointer;
  foo( &SecondPointer );
}

Now compare this with

  char* string = "15.88";
  char* EndOfParsing;

  strtof( string, &EndOfParsing );

It now should be fairly obvious, what is going on:
strtof parses the text, starting at string. When strtof
has finished, it alters EndOfParsing to point to where
it left off. It can do so, because you are not passing
EndOfParsing directly (which would result in passing a copy
of the pointer value in it), but you pass the *address* of that
pointer variable. Thus strtof has access to that variable and
can alter it.

It should also be now fairly obvious, why the first argument
is passed without an &, while the second one is: The first
argument is just put into the function, the function uses that
as initial value to start parsing. But it does not need to
alter the callers variable. But the same is not true for the
second argument. The function *wants* to alter the callers
variable, hence you need to pass the address of that variable.

strtof (and strtod) also understand a special case, which can be
denoted by: I am not interested in where you left of. You do
this by passing a NULL pointer to the function. So strtof will
only try to modify the callers second pointer variable, if the
address it gets is not NULL.

HTH

-- 
Karl Heinz Buchegger
kbuchegg@gascad.at


Relevant Pages

  • Re: Virtual function and multiple inheritance
    ... virtual int func(); ... class Derived: Foo, Goo { ... Here pF is a pointer to an object with the same memory layout as a Foo and pG is a pointer to an object with the same memory layout as a Goo. ...
    (microsoft.public.vc.language)
  • Re: About C++ memory management
    ... int * ptr = new int; ... delete ptr; ... But if I copy this pointer like below should I also delete copied ... Foo ...
    (microsoft.public.vc.language)
  • Re: would C be easier to read if...
    ... That indicates that it's a pointer to a function. ... int *a a is pointer to int ... In my case a type declaration that reads linearly from left to right would ... Let's say we have a regular int identifier named "foo". ...
    (comp.lang.c)
  • Re: help with left-right cdecl rule
    ... This "const int * foo" also makes sense, foo is a pointer to a const ...
    (comp.lang.c)
  • Re: Trap rvalues
    ... representation and is read by an lvalue expression that does not have ... pointers, both are pointers to the same object (including a pointer to ... pointers to one past the last element of the same array object, ...
    (comp.std.c)