Pointers...What good are they? 
Author Message
 Pointers...What good are they?

Well fellow programmers, there is a new one among you.  I have been
studying C for about a month now, and pointers puzzle me.  I can never get
passed the use of pointers, no matter how much I read over them.  I have
even posted different pointer questions on other groups, but everyone
seems to type something from a book.  If possible, I'd like a
"translation" of what books/online tutorials have to say.  Here is an
example (though it's not great):

#include <stido.h>

/* Die stuct, die! */
struct rec
{
        int i;
        float f;
        char c;

Quote:
};

void main()
{
        struct rec *p
        p=(struct rec*) malloc(sizeof(struct rec));

        /* I know it somehow asigns values
         * but I am quit puzzled
         */
        (*p).i=10;      /* or p->i=10 */
        (*p).f=3.14;    /* or p->i=10 */
        (*p).c='a';     /* or p->i=10 */

        /* Prints the values it just assigned
         * but why so many pointers?
         */
        printf("%d %f %c\n",(*p).i,(*p).f,(*p).c);

        /* Yeah, yeah...deallocate and stuff...
        free(p);

Quote:
}

That example is a bit advanced for me, so here is another one.

#include <stdio.h>

void main()
{
        int *p;         /* our good friend the pointer =) */

        p=(int *) malloc(sizeof(int)); /* I know "p is generic"
                                        * but I need the reason for
                                        */ the (int *) in english.      

        *p=10                   /* And then all this */
        printf("%d\n",*p);    /* croc that means   */
        free(p)                 /* nothing to me     */
                                /* knowing what the  */
                                /* heck a pointer is */

Quote:
}

Thank for your time (and patience) and I hope that you can help me out!

--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>Well fellow programmers, there is a new one among you.  I have been
>studying C for about a month now, and pointers puzzle me.  I can never get
>passed the use of pointers, no matter how much I read over them.  I have
>even posted different pointer questions on other groups, but everyone
>seems to type something from a book.  If possible, I'd like a
>"translation" of what books/online tutorials have to say.  Here is an
>example (though it's not great):

To put it very simple: a pointer is a variable that literally points
to some block of memory. Simpler than that I can't make it.
<snip - example with struct>
Quote:

>That example is a bit advanced for me, so here is another one.

>#include <stdio.h>

>void main()
>{
>    int *p;         /* our good friend the pointer =) */

>    p=(int *) malloc(sizeof(int)); /* I know "p is generic"
>                                    * but I need the reason for
>                                    */ the (int *) in english.      

>    *p=10                   /* And then all this */

The asteriks (*) before the pointer is an indication you want to work
with the memory the pointer is pointing to, not the pointer itself.
Think of '*p' as a new variable you introduced with the call to
malloc.
Quote:
>    printf("%d\n",*p);    /* croc that means   */
The same here.
>    free(p)                 /* nothing to me     */

Here you don't have the *, bacause free wants to have a variable that
points somewhere.

Quote:
>                            /* knowing what the  */
>                            /* heck a pointer is */
>}

>Thank for your time (and patience) and I hope that you can help me out!

I hope I have been of assistance

Quote:


>--


Bart v Ingen Schenau
--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>Well fellow programmers, there is a new one among you.  I have been
>studying C for about a month now, and pointers puzzle me.  I can never get
>passed the use of pointers, no matter how much I read over them.

They're tricky.

It really sounds to me like your problem isn't any specific technical
question, but rather, that pointers Just Don't Make Sense To You.

Quote:
>struct rec
>{
>    int i;
>    float f;
>    char c;
>};

>void main()

Hmph.  main() should return int; your book is weak.

Quote:
>    struct rec *p

Okay.  Here's the idea.

Imagine that you have a bunch of pieces of paper.  You have, here, a piece
of paper labeled "p".  p is a piece of paper that is special, because all it
holds is a description of another piece of paper.

Quote:
>    p=(struct rec*) malloc(sizeof(struct rec));

You call your friend "malloc", and say "sizeof struct rec", and he says
"here's a piece of paper big enough to write the contents of a struct rec".

You put that piece of paper on your desk, in the upper left-hand corner.

On "p", you write "the piece of paper in the upper left-hand corner of my
desk".

Quote:
>    /* I know it somehow asigns values
>     * but I am quit puzzled
>     */
>    (*p).i=10;      /* or p->i=10 */

Okay, here's what happens.

You look at "p", and it says "the piece of paper in the upper left-hand
corner of my desk".  "*p" means "the paper described by p", so you go look
at the piece of paper in the upper left-hand corner of your desk.  On that
piece of paper is a little form that looks like
        i       ________
        f       ________
        c       ________
so, in the field "i", you write "10".

Quote:
>    (*p).f=3.14;    /* or p->i=10 */

Same thing, except this time, in the filed "f", you write "3.14".

Quote:
>    (*p).c='a';     /* or p->i=10 */

And now, in  "c", you write 'a'.

Quote:
>    /* Prints the values it just assigned
>     * but why so many pointers?
>     */
>    printf("%d %f %c\n",(*p).i,(*p).f,(*p).c);

Now, you do the same thing, but you're reading the fields from the piece
of paper, and you hand them to printf.

Quote:
>#include <stdio.h>
>void main()
>{
>    int *p;         /* our good friend the pointer =) */

Yup.  "p" is now a blank piece of paper.

Quote:
>    p=(int *) malloc(sizeof(int)); /* I know "p is generic"
>                                    * but I need the reason for
>                                    */ the (int *) in english.      

It's not really strictly necessary in C.

We'll have to get a bit more advanced.  Imagine that there are different
kinds of paper, and "p" says, not just which piece of paper you're looking
for, but what kind of paper it is.  This is used to catch errors; if you
try to store the location of a different kind of paper, you get a warning.
The function "malloc" returns a description of "any old piece of paper", so
you don't really need the cast, but you would in C++.  Don't worry about it.
:)

So, what really happened is, malloc gave you a piece of paper labeled
        integer _________
and you took the description of where that paper is, and wrote it on "p".

Quote:
>    *p=10                   /* And then all this */

This says "find the piece of paper p describes, and write 10 on it".

Quote:
>    printf("%d\n",*p);    /* croc that means   */

This means "find the piece of paper that p describes, read the number from
it, and print it".

Quote:
>    free(p)                 /* nothing to me     */
>                            /* knowing what the  */
>                            /* heck a pointer is */

This says "throw away the piece of paper that p describes".

Quote:
>Thank for your time (and patience) and I hope that you can help me out!

Well, we'll certainly try.

I'm quite the master of awful analogies.

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

> Well fellow programmers, there is a new one among you.  I have been
> studying C for about a month now, and pointers puzzle me.  I can never get
> passed the use of pointers, no matter how much I read over them.  I have
> even posted different pointer questions on other groups, but everyone
> seems to type something from a book.  If possible, I'd like a
> "translation" of what books/online tutorials have to say.  Here is an
> example (though it's not great):

> #include <stido.h>

> /* Die stuct, die! */
> struct rec
> {
>         int i;
>         float f;
>         char c;
> };

> void main()
> {
>         struct rec *p

p is declared to hold a value, which is the memory address of the beginning of
a region having the size and structure of a "rec"

Quote:
>         p=(struct rec*) malloc(sizeof(struct rec));

p is assigned the value returned from malloc (which, because it is used to
allocate storage for all kinds of things, the actual type of which isn't known
when malloc is written, it is declared to return a value of type "void *" or
in other words, a generic pointer. The cast to (struct rec*) is used primarily
for self-documentation, so that the human reader knows that the type of the
thing on the right of the assignment is "address of a rec structure" or
"pointer to rec"). malloc() just takes a size (in bytes), and returns a
generic pointer to a region in memory that is large enough to hold that many
bytes.

Quote:

>         /* I know it somehow asigns values
>          * but I am quit puzzled
>          */
>         (*p).i=10;      /* or p->i=10 */

first, the two forms are equivalent.  x->y is just syntactic sugar for (*x).y

since p is a pointer to a rec structure, you want some way to get at the
members of the structure. If there were a statically-allocated instance of
this structure, call it sr, declared as follows:

struct rec sr;

then, in order to get at the members, you use the member access operator, "."
But p is a pointer to rec, not a rec.
The way to get the "thing pointed to" by p, use the dereference operator on
the reference (another word for pointer) variable. So, (*p) is just the thing
pointed to by p, and (*p).i is just the "i member of the thing pointed to by
p"

I hope I'm not being too pedantic, I'm not trying to insult anyone, but just
help.

Quote:
>         (*p).f=3.14;    /* or p->i=10 */
>         (*p).c='a';     /* or p->i=10 */

>         /* Prints the values it just assigned
>          * but why so many pointers?
>          */
>         printf("%d %f %c\n",(*p).i,(*p).f,(*p).c);

the first %d field in the format specifier argument to printf wants an
additional argument of integral type. Well, that's what "i member of thing
pointed to by p" is.
Likewise for "f member..." being a float, and "c member..." being a char.

Quote:

>         /* Yeah, yeah...deallocate and stuff...
>         free(p);
> }

> That example is a bit advanced for me, so here is another one.

> #include <stdio.h>

> void main()
> {
>         int *p;         /* our good friend the pointer =) */

p is just a number, representing a memory location that holds an integer.

Quote:

>         p=(int *) malloc(sizeof(int)); /* I know "p is generic"
>                                         * but I need the reason for
>                                         */ the (int *) in english.

again, it's not useful to the compiler, just to the human reading the code. It
basically says, the type of the thing on the right hand side will be "address
of an integer-sized chunk of memory". Since that agrees with the type of the
thing on the left-hand side, everything is good. I believe ANSI actually
requires the cast, but even so, it is only enforcing good style, it does
nothing to help code-generation, since (on every computer I've ever worked on)
pointers are all the same size, regardless of what they're pointing to. So,
it's just a formality, but it is good programming practice, and is required
for static type-checking.

Again, the issue is, the malloc() function is declared as follows:

void *malloc(size_t);

Which means it takes an argument of type size_t (usually that translates to
"unsigned" after preprocessing), and returns a pointer to (the address of) a
chunk of memory reserved of that size.

In order to store that value into a pointer declared for ints, you "cast" the
return value, which just changes its effective type at compile-time.

Quote:

>         *p=10                   /* And then all this */

the integer value 10 is stored to the address in p, or alternative way of
thinking
about it is, thing pointed to by p has its value changed to 10.

Quote:

>         printf("%d\n",*p);      /* croc that means   */

%d format specifier wants an integer type argument. "thing pointed to by p" is
indeed an integer. (In fact, it's 10 at this point in the program).

Quote:

>         free(p)                 /* nothing to me     */

free() does the opposite of malloc(): basically, it gives the space back to
the
runtime system, to use for some new purpose. It "gives up" (or frees) the
memory reserved by the previous call to malloc().

Quote:

>                                 /* knowing what the  */
>                                 /* heck a pointer is */
> }

> Thank for your time (and patience) and I hope that you can help me out!

I hope that I have been able to help.

Quote:


> --


--Tommy.
--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

> Well fellow programmers, there is a new one among you.  I have been
> studying C for about a month now, and pointers puzzle me.  I can never get
> passed the use of pointers, no matter how much I read over them.  I have
> even posted different pointer questions on other groups, but everyone
> seems to type something from a book.  If possible, I'd like a
> "translation" of what books/online tutorials have to say.  Here is an
> example (though it's not great):

You've got the technique, but the question seems to be "Why bother with
pointers?  Why not just use regular old variables?  It's just more compilcated
and looks uglier."  

The answer is, sometimes you need a "variable" variable.  It lets you access
*another* variable, by making a decision at run time.  Otherwise, you would
only be able to access variables specified at compile time.

You need pointers in C frequently to do very important, common things:

  - simulate pass-by-reference
  - allocating storage whose size is determined at run time

...among a zillion other things.
--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>Well fellow programmers, there is a new one among you.  I have been
>studying C for about a month now, and pointers puzzle me.  I can never get
>passed the use of pointers, no matter how much I read over them.  I have

Pointers can be a difficult subject until the light clicks on (and
sometimes even after that).  They tend to be more important in C than
most other languages, which is one reason I recommend beginning
programmers learn some other language first.

Quote:
>even posted different pointer questions on other groups, but everyone
>seems to type something from a book.  If possible, I'd like a
>"translation" of what books/online tutorials have to say.  Here is an
>example (though it's not great):

[...struct example...]

Quote:
>That example is a bit advanced for me, so here is another one.

Actually, it might just have been too simple.  You did nothing with
the pointer that could not have been done without a pointer (other
than malloc and free the memory, that is).  Lets work a little bit
with this second example.

A pointer is a variable that "points" to another.  Kind of circular.
*How* does it point to another?  It is itself a variable.  It contains
the "address" of the variable it points to.  You can operate on the
pointer the same way you operate on other variables (within limits).
To operate on the variable the pointer points to, you have to
"dereference" the pointer using * or ->.  

It's not a particularly good analogy, but think of

   ptr = address;

as writing an address in your little black book, and

   *ptr = value;

as looking that address up, copying it on an envelope, putting "value"
in the envelope and mailing it.

If we have a (valid, non-NULL) pointer to type "X" we know there is an
X out there somewhere that we can work with, and we know where to find
it.  There may or may not be other ways to get to that same X.

Quote:

>#include <stdio.h>

>void main()
>{
>    int *p;         /* our good friend the pointer =) */

        int *p2;        /* another pointer */
        int q;          /* a new friend to play with, not a pointer */

Quote:

>    p=(int *) malloc(sizeof(int)); /* I know "p is generic"
>                                    * but I need the reason for
>                                    */ the (int *) in english.      

Actually, the cast is not required.  I for one would prefer it was not
there: it can conceal a bug (i.e. if the prototype for malloc is
missing).
        p2 = &q;        /* p2 now points to q */

Quote:

>    *p=10                   /* And then all this */

This statement sets the int pointed to by p (which you previously
malloc'ed) to 10.  Or at least it would if the semicolon were there...

        *p2 = 20;               /* sets q to 20 */

Quote:
>    printf("%d\n",*p);    /* croc that means   */

The above should print "10"

        printf("%d, %d\n", q, *p2);

should print "20, 20"

Now let's have some real fun:

        p2 = p;
        printf("%d, %d\n", q, *p2);

Although the print statement is the same as it was the last time, it
should now print "20, 10"

       *p2 = 30;
       printf("%d, %d, %d", q, *p2, *p);

should print "20, 30, 30".  

Quote:
>    free(p)                 /* nothing to me     */
>                            /* knowing what the  */
>                            /* heck a pointer is */
>}

>Thank for your time (and patience) and I hope that you can help me out!

Hope this helps.

                          -=Dave
Just my (10-010) cents
I can barely speak for myself, so I certainly can't speak for B-Tree.
Change is inevitable.  Progress is not.
--



Tue, 05 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?
Quote:

>Well fellow programmers, there is a new one among you.  I have been
>studying C for about a month now, and pointers puzzle me.  I can never get
>passed the use of pointers, no matter how much I read over them.  I have
>even posted different pointer questions on other groups, but everyone
>seems to type something from a book.  If possible, I'd like a
>"translation" of what books/online tutorials have to say.  Here is an
>example (though it's not great):

[snip]
First, let me type something from a book: "A pointer is a variable that
contains the address of a variable."

You use a pointer when you don't know the actual variable that part of
the program will use.  This typically happens when part of a program
needs to operate on different variables at different times when the
program runs.  Here is a simple example.

   #include <stdio.h>

   int main() {
      int a = 4, b = 9, *p;
      printf("before a=%d b=%d\n", a, b);
      p = &a;
      *p = 0;
      p = &b;
      *p = 0;
      printf("after  a=%d, b=%d\n", a, b);
   }

At different times during the program the pointer contained the address
of differnet variables.

In such a simple program there is no need to use a pointer, you know
what variables you want to set to zero.  However, a program does not
always know the variables that it will use.  This is especially true
with functions in C.

Here is another way to write the above program.

   #include <stdio.h>

   static void setToZero(int *p) {*p = 0;}

   int main() {
      int a = 4, b = 9;
      printf("before a=%d b=%d\n", a, b);
      setToZero(&a);
      setToZero(&b);
      printf("after  a=%d, b=%d\n", a, b);
   }

The function setToZero works with any variable of type int.  The function
will be called to operate on different variables at different times when
the program runs.

A pointer is used because in C function arguments are passed by value.
When a function is called, each argument is evaluated and the body of the
function uses a copy of that value when it uses the corresponding
parameter declared in the function definition.

Some other programming languages allow function parameters to be declared
in a way such that when the parameter is used in the body of the function,
the program uses the variable that was the corresponding argument of the
function (rather than a copy of the value of the argument).  C does not.

Pointers allow parts of a C program to operate on different variables at
different times by setting the pointer to the address of the variable to
be operated on.
--



Wed, 06 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

says...

Quote:
> Well fellow programmers, there is a new one among you.  I have been
> studying C for about a month now, and pointers puzzle me.  I can never get
> passed the use of pointers, no matter how much I read over them.

Okay, let's leave your question alone for the moment, and start with
yet another attempt at explaining what pointers are.  Since your
question dealt with pointers to structures, I'll use something similar
as an analogy.

Assume for the moment that you want to know the definition of a word,
and for some crazy reason you can't just look it up in the dictionary
on your own.  For the moment, let's also assume that we're using
something like the Oxford English Dictionary, where a complete
definition can be pretty long.

If I wanted to tell you the definition of a word, I could do a couple
of different things.  One would be for me to copy the whole definition
for the word out of the dictionary onto a piece of paper, and give you
the piece of paper.  Unfortunately, if the definition is big, this is
going to take me a while, and will probably also require more paper
than I want to use.

Therefore, to make my life a bit simpler, I might just copy down
something like "the 10th word on page 1027".

This way, I don't have to make a copy of the definition.  Instead,
I've simply given you some directions to be able to find the original
definition yourself.

A pointer is almost exactly like that piece of paper I'd hand you --
it doesn't contain the value (definition) itself; it just tells you
where you can find the original value.  When you've been given a
pointer, and go to look up the value it points to, you "dereference"
the pointer, using the "*" operator.  The basic dereferencing
operator, however, assumes something similar to you receiving ONLY a
page number in the dictionary, with no number of a word on that page.  
If you happen to use a dictionary that has only one definition per
page, that's perfectly fine.  That's pretty similar to having, say, an
array of int's -- each int is (more or less) a thing by itself, and
you can use the dereferencing operator to get to the correct int.

Our dictionary is more like a struct in C though: when you get to a
particular page, it's got a number of definitions on it.  Once you get
to the right page, you also have to find the right word.  A struct is
pretty much the same way -- if you have a pointer to a struct, you
don't just want the beginning of the struct, but you also want to pick
out a particular part of the struct.  You can do that by using the
normal dereferencing operator to "pick the right page", then
separately look for the right word on the page.  Since this happens
quite a bit, C provides us with a way of combining the two operations:
we can tell it both the struct we want, AND the member of the struct
we want, and it'll look figure out both at once.  This is where the "-

Quote:
>" operator comes in -- we put the pointer to the struct on its left,

and the member of the struct on its right, and it allows us to do
whatever we want with that member of that struct.

There are two main reasons for using pointers in C: one (analogous
with the example of the dictionary definition above) is that a pointer
is typically smaller and quicker to pass around than whatever it
points at.  Much like with definitions, you might occasionally see one
that's not much larger than the page number, and some kinds of
variables aren't much slower to copy/pass than pointers.  OTOH,
pointers are pretty dependably at least reasonably small and fast,
while the things they point at can vary quite widely.

The other reason shouldn't (usually) be very applicable to
dictionaries, but it's still easy to describe in that context.  When
you want to change a value of a variable, you often need a pointer to
be able to do so.  If I wanted to say that (for example) there was an
error in the definition of a word, I could pass you a copy of the
definition, and you could change the definition on that piece of
paper.  You'd then have to do something like return the piece of paper
to me, and I could write the new definition into the dictionary.  If,
however, I don't tell you what dictionary we're modifying, you
probably can't go in an make the change yourself.

OTOH, if I wanted you to make the change yourself, I could give you
the pointer to the right place, and by looking there (again, using the
dereferencing operator) you could write the new definition yourself.

C is VERY much the same way: if I want you to modify a variable, I can
pass you a copy of the variable, in which case you usually have to do
something like return a new value, which I can then use to overwrite
the old one.  If I want you to change a variable directly, I can pass
you a pointer, and by overwriting what the pointer points at, you can
modify the original variable directly.

Hopefully, that gives a more understandable idea of how pointers work,
and when and why you use them.  Once you figure out the basic idea of
pointers, understanding how C uses them (for example) is mostly a
matter of getting used to the particular symbols it uses to represent
the operations involved.
--



Wed, 06 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>{
>   int *p;      /* our good friend the pointer =) */

 PS> Yup.  "p" is now a blank piece of paper.

Mmh, I think p is now an indeterminate piece of paper. Use static or an
explicit initializer to make it blank :-)

greetings,
Tom

--



Wed, 06 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:


>>{
>>   int *p;      /* our good friend the pointer =) */

> PS> Yup.  "p" is now a blank piece of paper.

>Mmh, I think p is now an indeterminate piece of paper. Use static or an
>explicit initializer to make it blank :-)

Ahh, not so!

p is a blank piece of paper.  It is unclear what should happen if you say
"find the paper p refers to".

By contrast, if you initialize it, you might end up with a piece of paper
saying "mu", which would make more sense.

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Wed, 06 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:


>>{
>>   int *p;      /* our good friend the pointer =) */

> PS> Yup.  "p" is now a blank piece of paper.

>Mmh, I think p is now an indeterminate piece of paper.

It's not indeterminate, but you may have nasal problems if you look at
it before writing anything on it.

-- Mat.
--



Thu, 07 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>>{
>>   int *p;      /* our good friend the pointer =) */
> PS> Yup.  "p" is now a blank piece of paper.
>Mmh, I think p is now an indeterminate piece of paper. Use static or an
>explicit initializer to make it blank :-)

 PS> Ahh, not so!
 PS> p is a blank piece of paper.  It is unclear what should happen if
 PS> you say "find the paper p refers to".

No, that would be the case if it were implicitly (by making it static) or
explicitly initialized to NULL. In this case, however, the value of p
itself is indeterminate, so it is undefined behaviour to read from p, let
alone what it refers to.

(I suspect the analogy is now thinking "I didn't mean to be taken so
seriously")

greetings,
Tom

--



Thu, 07 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:

>>{
>>   int *p;      /* our good friend the pointer =) */
> PS> Yup.  "p" is now a blank piece of paper.
>Mmh, I think p is now an indeterminate piece of paper.

 MH> It's not indeterminate, but you may have nasal problems if you look
 MH> at it before writing anything on it.

It's not ? In what way do I mis-read the below paragraph then ?

3.5.7 Initialization
<snip>
If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate.

greetings,
Tom

--



Thu, 07 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?

Quote:


>>>{
>>>   int *p;      /* our good friend the pointer =) */
>> PS> Yup.  "p" is now a blank piece of paper.
>>Mmh, I think p is now an indeterminate piece of paper. Use static or an
>>explicit initializer to make it blank :-)
> PS> Ahh, not so!
> PS> p is a blank piece of paper.  It is unclear what should happen if
> PS> you say "find the paper p refers to".
>No, that would be the case if it were implicitly (by making it static) or
>explicitly initialized to NULL. In this case, however, the value of p
>itself is indeterminate, so it is undefined behaviour to read from p, let
>alone what it refers to.

It's an implementation-defined thing.  I agree, I said that wrong.  If a
piece of paper is blank, it is undefined behavior to even ask the question
"what is written on this piece of paper".  That's not indeterminate, but it
is the way I chose to implement "indeterminately valued".  When you
initialize p to a null pointer, the paper stops being blank, and starts saying
"I refer to no paper".

Quote:
>(I suspect the analogy is now thinking "I didn't mean to be taken so
>seriously")

Poor defenseless little analogy.

-s
--

C/Unix wizard, Pro-commerce radical, Spam fighter.  Boycott Spamazon!
Will work for interesting hardware.  http://www.plethora.net/~seebs/
Visit my new ISP <URL:http://www.plethora.net/> --- More Net, Less Spam!
--



Fri, 08 Feb 2002 03:00:00 GMT  
 Pointers...What good are they?
The thread with the above "subject" line got placed adjacent to
the ongoing one about pronouns, which made me realize that, in
a way, pointers are somewhat like pronouns.

"Pronouns ... what good are they?"

Suppose we did not have pronouns.  Instead of saying "me", "you",
"him", "her", and the like, suppose we had to use nouns all the
time.  One might say to Jack:  "Jane took Jane's car to Bob's Auto
Service.  Bob needs to keep Jane's car overnight.  Jack should go
pick Jane up at 4 PM."  (Think of old Tarzan movies or something. :-) )

This would *work*, but I think people would find it awkward (cf.
the "more natural" phrasing, "Jane took her car to Bob's Auto
Service.  He needs to keep her car overnight.  You should go pick
her up at 4 PM.").  Instead of naming something explicitly over and
over again, we have "short forms" by which we can name something
conveniently.

In addition, this allows us to use pronouns "generically", such as
"you", addressed to the reader.  "You" are reading this right now,
no matter whether your name is Jack, Jane, Bob, or something else
entirely.  The pronoun "you" magically refers to the correct person,
regardless of your name.

Similarly, consider a procedure like strtol():

        long strtol(const char *nptr, char **endptr, int base);

The sequence-of-characters we want to convert might be in buf[0]
through buf[3]:

        char buf[BUFSIZ];
        long l;
        char *ep;
        ...
        if (fgets(buf, sizeof buf, stdin) == NULL)
                errexit("end of file, quitting");
        l = strtol(&buf[0], &ep, 0);

Inside strtol(), the pointer "nptr" refers to &buf[0].  We could
try to write a different strtol() without using "nptr", but then
we would have to name "buf[0]" explicitly inside our replacement:

        long alt_strtol(void) {
                extern char buf[BUFSIZ];
                int first_digit, second_digit, third_digit, fourth_digit;
                ...
                first_digit = buf[0] - '0';
                second_digit = buf[1] - '0';
                third_digit = buf[2] - '0';
                fourth_digit = buf[3] - '0';
                ...
        }

If a second number we want to convert happens to be in buf[9]
through buf[12], this alt_strtol() is useless.  (We could write an
"alt2_strtol", but this way lies madness, or at least Microsoft-sized
code.)

Similarly, "endptr" inside strtol winds up referring to the variable
"ep".  Here "ep" itself is a pointer, so "endptr = &ep" -- this
assignment effectively happens at the time of the call to strtol()
-- sets up a pointer to a pointer.  Just as a pronoun is also a
word, a pointer is also an ordinary object; and just as a pronoun
can stand in for some other word, a pointer can stand in for some
other object; so a pointer can stand in for another pointer.

To follow a pointer, you simply use the unary "*" operator:

        this_digit = *nptr - '0';

is more or less equivalent to:

        this_digit = buf[0] - '0';

because nptr refers to (points to) buf[0].

Ultimately, each pointer had better stand in for *some* object,
before you try to use that particular object.  Any uninitalized
automatic variable (more or less, "one local to a set of {}s")
contains garbage, and this is true of pointers as well.  So if you
declare a pointer of your own (such as "ep" above), you will have
to set it before you try to follow it to where it points.

The language reserves one particular value -- the "null pointer"
-- to be used as a valid value that explicitly points to *no*
object.  This is very much *un*like the normal use of pronouns;
"you" refers to a real person, but the pointer "endptr" can be set
to NULL.  The strtol() function checks "endptr != NULL" before
trying to use the object for which "endptr" might stand:

        long strtol(const char *nptr, char **endptr, int base) {
                ...
                if (endptr != NULL)
                        *endptr = some_valid_value;
                return (value);
        }

That means that after the call to strtol(), "ep" -- the thing to
which "endptr" pointed while strtol() was doing its work -- will
have been written with some valid value.  The actual definition of
strtol() says that it will locate a digit sequence, convert it,
and set *endptr to the first "invalid" (non-digit) character in
the buffer.  Thus, we can write a function like this:

void simple_arithmetic(void) {
        char buf[BUFSIZ];
        long n1, n2;
        char *ep1, *ep2;

        if (fgets(buf, sizeof buf, stdin) == NULL)
                errexit("end of file, quitting");

        /* group 1 (see note below) */
        n1 = strtol(&buf[0], &ep1, 0);
        if (ep1 == buf)
                errexit(
"missing <number1> -- expected <number1> + <number2> or <number1> - <number2>");
        while (isspace(*ep1))
                ep1++;

        operator = *ep1++;
        if (operator != '+' && operator != '-')
                errexit("missing/invalid operator -- expected + or -");

        /* group 2 (see note below) */
        n2 = strtol(ep1, &ep2, 0);
        if (ep1 == ep2)
                errexit(
"missing <number2> -- expected <number1> + <number2> or <number1> - <number2>");
        while (isspace(*ep2))
                ep2++;

        if (*ep2 != '\0')
                warn("junk after expression");
        if (operator == '+')
                printf("%d + %d = %d\n", n1, n2, n1 + n2);
        else
                printf("%d - %d = %d\n", n1, n2, n1 - n2);

Quote:
}

(proper include files, support functions -- including main -- and
testing of this code left as an exercise to the reader :-) ).

Note: As a more interesting exercise, once you have written the
support functions and gotten this working, try writing a routine
that handles the sequence "do a strtol, and errexit() if no number
was supplied; then skip over trailing whitespace", which appears
twice in simple_arithmetic() above.  This will simplify the two
marked groups of code.  What parameters will you need inside
this "get_number" routine?
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc


--



Fri, 08 Feb 2002 03:00:00 GMT  
 
 [ 20 post ]  Go to page: [1] [2]

 Relevant Pages 

1. how good am I? Am I Good Enough????

2. HELP, I am having problems with pointer...

3. Am I being paranoid about vector pointers?

4. I am new to programming and am lost

5. Any pointers to a good component-writing tutorial?

6. Pointers...What good are they?

7. pointers: which of these is better?

8. Good programming style: multidimensional arrays or pointer technique

9. pointers: which of these is better?

10. what r function pointers better for?

11. Better pointer reassignment method ??

12. Best book for learning pointers & reference book

 

 
Powered by phpBB® Forum Software