Pointers

Discussion in 'C Programming' started by j.wagner1024@gmail.com, Mar 13, 2013.

  1. Guest

    Hi, I have started programming in C recently and started learning about pointers. Insofar, all the material has been easy to digest and understand. But pointers are really giving me a hard time! I've read quite a few articlesand some pdfs on pointers, but I'm still having trouble. If someone could point me to (no pun intended) some good tutorials or try to explain it, I'dbe indebted! Thanks!
     
    , Mar 13, 2013
    #1
    1. Advertising

  2. Eric Sosman Guest

    On 3/12/2013 9:57 PM, wrote:
    > Hi, I have started programming in C recently and started learning about pointers. Insofar, all the material has been easy to digest and understand. But pointers are really giving me a hard time! I've read quite a few articles and some pdfs on pointers, but I'm still having trouble. If someone could point me to (no pun intended) some good tutorials or try to explain it, I'd be indebted! Thanks!


    Take a look at Section 4 on the comp.lang.c Frequently Asked
    Questions (FAQ) page at <http://www.c-faq.com/ptrs/index.html>, and
    post again if you're still puzzled. (The FAQ isn't a tutorial on
    pointers, but it touches on a lot of their uses. You may find the
    examples helpful.)

    --
    Eric Sosman
    d
     
    Eric Sosman, Mar 13, 2013
    #2
    1. Advertising

  3. Guest

    Will do, thanks!
     
    , Mar 13, 2013
    #3
  4. Guest

    I read the entire FAQ for pointers, and I'm still stuck :(. What I (think) I understand is that when you declare pointer such as:

    int *ptr;

    Then that points the address of a variable and not the value inside the address. What I'm not understanding is, what do these do:

    1. &ptr
    2. null pointers
    3.ptr++ vs ++ptr vs (*ptr)++ etc...
    4. void *ptr
     
    , Mar 13, 2013
    #4
  5. Ian Collins Guest

    wrote:
    > I read the entire FAQ for pointers, and I'm still stuck :(. What I
    > (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside
    > the address. What I'm not understanding is, what do these do:


    "int*" is a type which is used to store the address of an int. Just
    declaring one does not assign a value to it.

    int n 42;
    int *ptr = &n;

    declares ptr as a pointer to int and initialises it with the address of n.

    printf( "%d %d\n", n, *ptr );

    will print "42 42"

    > 1. &ptr


    This is the address of ptr.

    > 2. null pointers


    The null pointer is a pointer with a value of 0. Zero is nearly always
    an invalid address, so it gets used as an error value for most
    operations that return a pointer.

    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    ptr++ and ++ptr increment the value of ptr be the size of the type it is
    pointer to "move on to the next item" if p is pointer to something in an
    array. (*ptr)++ increments the value pointed to by ptr.

    > 4. void *ptr


    "void*" is C's generic pointer type.

    --
    Ian Collins
     
    Ian Collins, Mar 13, 2013
    #5
  6. Guest

    That helps a bit, especially the first example, thanks.
     
    , Mar 13, 2013
    #6
  7. Shao Miller Guest

    On 3/12/2013 22:40, wrote:
    > I read the entire FAQ for pointers, and I'm still stuck :(. What I (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside the address.


    Roughly speaking:

    A pointer is an object. An object contains a value. So: A pointer
    object contains a pointer value.

    > What I'm not understanding is, what do these do:
    >
    > 1. &ptr


    '&identifier' gives a pointer value, which points to the identified
    object. Since 'ptr' is a pointer object, '&ptr' points to a pointer
    object; a pointer to a pointer to an 'int'.

    > 2. null pointers


    A null pointer value means "points to no object nor function". A
    pointer object can hold a null pointer value.

    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    The first two increment a pointer value, which means "Increment 'ptr' to
    point to the next 'int' object in the array of 'int' objects."
    (Assuming there _is_ an 'int' array, and that you've pointed to one of
    its elements.)

    > 4. void *ptr
    >


    A 'void *' value points to any object, which means that since different
    objects have different sizes, you cannot increment a 'void *'; there's
    no way to know how to advance to "the next object" if you do not know
    the size of each object.

    --
    - Shao Miller
    --
    "Thank you for the kind words; those are the kind of words I like to hear.

    Cheerily," -- Richard Harter
     
    Shao Miller, Mar 13, 2013
    #7
  8. Guest

    Could someone recommend some material that I could study?
     
    , Mar 13, 2013
    #8
  9. Eric Sosman Guest

    On 3/12/2013 10:40 PM, wrote:
    > I read the entire FAQ for pointers, and I'm still stuck :(. What I (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside the address. What I'm not understanding is, what do these do:


    Here, ptr is a variable. Its value (once you give it one) will
    not be an int, but a value that locates an int somewhere else. By
    way of analogy, ptr is a telephone number and the thing it points at
    is the telephone.

    > 1. &ptr


    Like most operators, the unary & operator produces a value. The
    value it produces is a pointer to its operand, so &ptr is a value
    that points at the variable ptr.

    ... which is itself a pointer, so maybe we're getting a little
    deep for beginners. Let's go back to shallower water for a while:

    int foo = 42;
    int bar = 56;
    int *ptr;

    Here we have two int variables, each with its own integer value.
    We've also got a pointer variable capable of pointing at ints, but
    it hasn't been given a value yet (just as in `int x;' the x has
    not yet been given a value). So, let's assign a value:

    ptr = &foo;

    The &foo part produces a pointer value aiming at the variable
    foo, and then we store that value in ptr, making ptr point at foo.
    Later on, we might change our mind:

    ptr = &bar;

    Again &bar produces a pointer value, this one aimed at bar, and we
    store that value in ptr. Now ptr points at bar instead of at foo.

    Why is this useful? Because we can do things like

    printf("The Answer is %d\n", *ptr);

    .... without caring whether ptr is aimed at foo or at bar or perhaps
    at some other int altogether. The prefix * operator looks at its
    operand -- a pointer -- finds out what it points at, and delivers
    the value of the pointed-at thing. By using ptr, we can make this
    single printf() call able to print the value of any int variable in
    the program: We just aim ptr at it, and execute the call.

    We can also use this on the left-hand side of an assignment:

    *ptr = -17;

    This stores minus seventeen in ... well, in whatever ptr is
    aimed at when the statement is executed. We don't have to write
    different assignments for foo and for bar, the same assignment
    works for either of them -- or for anything else we've aimed ptr at.

    > 2. null pointers


    It's useful to have a special pointer value that means "I'm
    not pointing at anything whatsoever." That's what a null pointer
    is for; the FAQ goes into some detail on how they're used.

    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    When the pointer's target variable is not isolated but is one
    element of an array, it makes sense to do arithmetic on the pointer
    values: "Whatever you're pointing at, find the next-door neighbor."
    You can move forward and back in single steps with ++ and --, or
    in larger steps by adding/subtracting bigger integers.

    > 4. void *ptr


    This is a special case: A pointer to something whose nature
    is not stated. It might be pointing at an int, or at a char, or
    at a float, or at anything at all. That flexibility makes it
    useful for writing "generic" code that can operate on many different
    kinds of data, rather than writing separate routines for int, char,
    float, and so on.

    The flexibility comes at a price: Since the type of the target
    is unknown, you can't use *ptr to fetch a value from it, nor to store
    a value in it. Nor can you do arithmetic on the pointer, since you
    don't know how big a step takes you from one unknown-type variable to
    its neighbors. You can pass arbitrary pointer values around in your
    program by using void*, but you can't actually do much with them
    until you say "Aha: I happen to know that the target is a double,
    so I'll convert my void* to a double* and proceed."

    ... which brings up another part of the price: Loss of type
    safety. Since you can convert any kind of data pointer to void*
    easily, and then convert a void* to a data pointer again equally
    easily, it's absurdly easy to get the types wrong. You start with
    &foo (an int* from an earlier example), convert it to void*, then
    arrive at the "Aha" moment and convert the void* to a double*. You
    are now In Trouble, because you're trying to do double-ish things
    on an int. It's like packing all the picnic lunches in identical
    paper bags, then giving the ham and Swiss on whole wheat to the
    vegetarian Jewish celiac sufferer because all the bags looked alike.
    Be watchful always, and be extra watchful when converting pointers
    from one type to another.

    --
    Eric Sosman
    d
     
    Eric Sosman, Mar 13, 2013
    #9
  10. Joe Pfeiffer Guest

    writes:

    > I read the entire FAQ for pointers, and I'm still stuck :(. What I (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside
    > the address. What I'm not understanding is, what do these do:


    One small point: it *is* the address of the object it "points" to. To
    digress, doing some assembly language programming did more to help me
    understand pointers than anything else ever did.

    > 1. &ptr


    That's the address of the pointer itself. Let's suppose you've got

    int a;
    int *ptr;
    int **ptrptr;

    Now you can say:
    ptr = &a; // ptr is now contains the address of a --
    // it's a pointer to a
    ptrptr = &ptr; // ptrptr now contains the address of ptr --
    // it's a pointer to ptr, or a pointer to a pointer
    // to a


    and we can make some assertions:
    *ptr == a
    *ptrptr = ptr
    **ptrptr = a

    > 2. null pointers


    A pointer need not "point to" (contain the adddress of) any actual
    object. We can set the pointer to NULL to give it a specific value we
    can test against, to see if it's valid. It's really common that
    functions that return a pointer (like malloc()) will return NULL to let
    you know they've failed.

    Unfortunately, there are myriad ways a pointer can just contain what
    amounts to a random number; then it won't point to an object we'd like
    it to, probably won't point to any object at all, and almost certainly
    won't be NULL. Making sure an invalid pointer contains NULL is the
    programmer's responsibility.

    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    ptr++ : access the pointer, then increment it.
    If you say
    ptr2 = ptr++;
    then ptr2 points to the object ptr used to point to, and ptr points to
    the next object (I'll describe what the "next" object is in a moment)

    ++ptr : increment the pointer, then access it.
    If you say
    ptr3 = ++ptr;
    then ptr and ptr3 both point to the next object.

    The increment in these cases may not be by 1, like you'd (well, OK, like
    I'd) expect. It's by the right amount to get to get past the object
    you're pointing to.

    So if ptr is a pointer to char like
    char *ptr;
    then the increment works like you'd think: it adds 1 to ptr.

    But if it's a pointer to an int like
    int *ptr;
    and the system has four chars to an int (which is almost, but not quite,
    universally true), then it increments by 4.

    And if it's a pointer to some sort of struct like
    struct bogus *ptr;
    and struct bogus is 42 bytes (a number picked in honor of Douglas Adams,
    whose birthday was yesterday), then it increments by 42.

    *(ptr++)

    dereferences the pointer, and then increments it. So going back to the
    earlier example where
    ptr = &a;
    then
    b = *(ptr++);
    will set b to a, and then increment ptr to point to the next object of
    the same size as a.

    > 4. void *ptr


    This amounts to being a pointer to an undefined type. The idea is that
    a function like malloc() can return a plain ol' pointer, and let your
    program deal with what type of pointer it is. So you can say things
    like

    int *ptr;

    ptr = malloc(sizeof *ptr);

    and
    (1) the sizeof operator will understand that the size of what ptr
    points to is 4 (if there are 4 chars to an int, as above), and
    tell malloc() that you need an object of size 4 (in practice, an
    object 4 bytes long).
    (2) malloc() will return a pointer to 4 bytes in memory
    (3) ptr will be pointed at these 4 bytes.
     
    Joe Pfeiffer, Mar 13, 2013
    #10
  11. Les Cargill Guest

    wrote:
    > I read the entire FAQ for pointers, and I'm still stuck :(. What I (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside the address. What I'm not understanding is, what do these do:
    >
    > 1. &ptr


    That is a pointer to ( a pointer to ) an int.

    int **qtr = &ptr;

    > 2. null pointers


    NULL pointers are a marker for "this pointer points to nothing. Yet."
    In many archiectures, dereferencing a NULL pointer would generate an
    exception which would stop your program.

    We're Pavlovian-ly conditioned away from this ( your program crashed! )
    but it's really a *safety* thing - if the program tried to soldier on,
    who knows what it might have damaged?


    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    Post increment (ptr++) is evaluated after other things happen.
    Pre increment (++ptr) is evaluated before other things happen.

    (*ptr)++ is the same as ptr[0]++ - the thing pointed to by
    ptr is incremented.

    > 4. void *ptr
    >



    "... and the world was *void* and *without form*..."

    A void * is an opaque type with no meaning which can be
    converted to another type of pointer, but it's tactically
    convenient for that type to not be specified then - like as an argument
    to the compare function in qsort().

    It means "we'll assign this to a meaningful pointer later on."

    typedef struct {
    ....
    int el;
    ....
    } twoomba;

    twoomba *t = (twoomba *)ptr;
    // now it has a meaning.

    *ptr = 0;
    // there is no type void... error

    t->el = 42;
    // allowed.


    >
    >


    --
    Les Cargill
     
    Les Cargill, Mar 13, 2013
    #11
  12. On Tue, 12 Mar 2013 19:40:19 -0700, j.wagner1024 wrote:

    > I read the entire FAQ for pointers, and I'm still stuck :(. What I
    > (think) I understand is that when you declare pointer such as:
    >
    > int *ptr;
    >
    > Then that points the address of a variable and not the value inside the
    > address.


    You are slightly off with your understanding.
    The most important thing to remember is that variables _store_ something.
    If you have
    int foo;
    int *ptr;
    then foo stores an integer and ptr stores the address of an integer
    (pointer variables store addresses).

    If you like real-world examples, then variables are like pieces of paper
    with things written on them. An integer variable is then a piece of paper
    with a number written on it. A pointer variable is then a piece of paper
    with directions on it where to find something else, like your street
    address if it is a pointer to your house, or where you left that piece of
    paper with the number on it.

    > What I'm not understanding is, what do these do:
    >
    > 1. &ptr


    That gives you the address of the pointer variable, so you can find out
    where the pointer variable itself is located and possibly store it in
    another pointer variable (one that stores pointer addresses, like `int
    **bar`).
    As C does not support pass-by-reference semantics for function arguments,
    this can be useful if you want to pass ptr to some function that causes
    it to point to some other integer. To see the change in the calling
    function, you need to pass the address of ptr.
    For example:

    int a;
    void assign(int** p)
    {
    *p = &a;
    }
    void foo()
    {
    int* ptr = NULL;
    assign(&ptr);
    // ptr now points at a
    }

    > 2. null pointers

    A null pointer is a pointer that explicitly states that it points at
    nothing.
    The big advantage of null pointers over uninitialized pointers is that
    you can actually test if a pointer is a null pointer.

    > 3.ptr++ vs ++ptr vs (*ptr)++ etc...


    Pointers can not only point to single values, but also to elements of an
    array.
    With ++ptr and ptr++, you go to the next element of the array (if you
    remember the pointer pointing at your house, ++ptr makes it point to your
    next door neighbor's house.
    With (*ptr)++, you are dealing with two operators. operator* takes the
    address stored in a pointer and gives you whatever is stored at that
    address. In (*ptr)++, operator++ increments the result of operator*.

    When multiple operators are used in an expression, you get to deal with
    operator precedence (basically, which operator gets to do its job first).
    That is too large a topic to cover here, so you should look it up in your
    textbook.

    > 4. void *ptr


    A void* is special, because it stores addresses without knowing what
    might be located at that location.
    It could have been
    anything *ptr
    but for some reason they did not want to add to many keywords to the
    language, so they decided to reuse the keyword void for this purpose.

    Bart v Ingen Schenau
     
    Bart van Ingen Schenau, Mar 13, 2013
    #12
  13. James Kuyper Guest

    On 03/12/2013 10:52 PM, Ian Collins wrote:
    > wrote:
    >> I read the entire FAQ for pointers, and I'm still stuck :(. What I
    >> (think) I understand is that when you declare pointer such as:
    >>
    >> int *ptr;
    >>
    >> Then that points the address of a variable and not the value inside
    >> the address. What I'm not understanding is, what do these do:

    ....
    >> 2. null pointers

    >
    > The null pointer is a pointer with a value of 0. ...


    That's true only in the sense that an integer constant expression with a
    value of 0 is a null pointer constant, and therefore is converted to a
    null pointer when used in an appropriate context. A null pointer need
    not refer to memory address 0, and when stored in an object need not
    cause all of the bits of that object to be 0, and there are real systems
    where neither of those things are true.

    > ... Zero is nearly always
    > an invalid address, ...


    Possibly, though that's not guaranteed, and therefore not really
    relevant. What's relevant is the fact, that is guaranteed by the C
    standard, that a null pointer never compares equal to a pointer to any
    object or function. It is used as a special pointer value to indicate
    that the pointer doesn't point at anything.
    --
    James Kuyper
     
    James Kuyper, Mar 13, 2013
    #13
  14. Mark Bluemel Guest

    On 13/03/2013 03:23, wrote:
    > Could someone recommend some material that I could study?


    Any reference book on C will cover pointers - they're pretty
    fundamental to the language. What have you read so far? If it's just
    online material, you probably ought to look at a real book. (Try
    <http://www.c-faq.com/resources/books.html> for some suggestions).
     
    Mark Bluemel, Mar 13, 2013
    #14
  15. army1987 Guest

    On Wed, 13 Mar 2013 06:29:30 -0400, James Kuyper wrote:

    > That's true only in the sense that an integer constant expression with a
    > value of 0 is a null pointer constant, and therefore is converted to a
    > null pointer when used in an appropriate context.


    And also in the sense that a null pointer is treated as false when used
    as a condition.



    --
    [ T H I S S P A C E I S F O R R E N T ]
    Troppo poca cultura ci rende ignoranti, troppa ci rende folli.
    -- fathermckenzie di it.cultura.linguistica.italiano
    <http://xkcd.com/397/>
     
    army1987, Mar 13, 2013
    #15
  16. Guest

    On Wednesday, March 13, 2013 6:52:55 AM UTC-4, Mark Bluemel wrote:
    > On 13/03/2013 03:23, wrote:
    >


    > What have you read so far?


    So far I've gone through a few pdf's, such as Gray Hat C, and C Programming, and I am currnetly working on Let Us C. I think I should probably read K&R next. Thansk for the link!
     
    , Mar 13, 2013
    #16
  17. James Kuyper Guest

    On 03/13/2013 07:10 AM, army1987 wrote:
    > On Wed, 13 Mar 2013 06:29:30 -0400, James Kuyper wrote:
    >
    >> That's true only in the sense that an integer constant expression with a
    >> value of 0 is a null pointer constant, and therefore is converted to a
    >> null pointer when used in an appropriate context.

    >
    > And also in the sense that a null pointer is treated as false when used
    > as a condition.


    The standard merely says "unequal to 0" in all of the relevant places:
    !, &&, ||, ?:, _Static_assert(), if(), while(), do while(), for(). It's
    the fact that 0 is a null pointer constant, and is therefore implicitly
    converts to a null pointer whenever compared for equality with a
    pointer, and the fact that all null pointers must compare equal, that
    causes null pointers to be treated the same way as 0 in those contexts.
     
    James Kuyper, Mar 13, 2013
    #17
  18. Shao Miller <> writes:
    > On 3/12/2013 22:40, wrote:
    >> I read the entire FAQ for pointers, and I'm still stuck :(. What I
    >> (think) I understand is that when you declare pointer such as:
    >>
    >> int *ptr;
    >>
    >> Then that points the address of a variable and not the value inside
    >> the address.

    >
    > Roughly speaking:
    >
    > A pointer is an object. An object contains a value. So: A pointer
    > object contains a pointer value.


    The unqualified word "pointer" is ambiguous; it could mean either
    a pointer object (an object of pointer type) or a pointer value
    (a value of pointer type). In fact, the C standard uses the word
    "pointer" to refer to a pointer value not stored in any object;
    see the description of the value returned by malloc, for example.

    If there's any chance of misunderstanding (such as in a discussion
    with someone who's still stuck on pointers), I suggest using the word
    "pointer" only as an adjective, not as a noun: "pointer object",
    "pointer value", "pointer expression", "pointer type".

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 13, 2013
    #18
  19. Bart van Ingen Schenau <> writes:
    [...]
    > The most important thing to remember is that variables _store_ something.
    > If you have
    > int foo;
    > int *ptr;
    > then foo stores an integer and ptr stores the address of an integer
    > (pointer variables store addresses).


    A clairification: foo stores an integer *value*, and ptr stores the
    address of an integer *object* (or an integer variable).

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Working, but not speaking, for JetHead Development, Inc.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Mar 13, 2013
    #19
  20. James Kuyper Guest

    On 03/15/2013 05:17 AM, sake wrote:
    > Ian Collins <> Wrote in message:
    >> wrote:
    >>> I read the entire FAQ for pointers, and I'm still stuck :(. What I
    >>> (think) I understand is that when you declare pointer such as:
    >>>
    >>> int *ptr;
    >>>
    >>> Then that points the address of a variable and not the value inside
    >>> the address. What I'm not understanding is, what do these do:

    >>
    >> "int*" is a type which is used to store the address of an int. Just
    >> declaring one does not assign a value to it.
    >>
    >> int n 42;
    >> int *ptr = &n;
    >>
    >> declares ptr as a pointer to int and initialises it with the address of n.
    >>
    >> printf( "%d %d\n", n, *ptr );
    >>

    >
    > hey
    > this doesn't work in my enviorment.


    What do you mean by "doesn't work"? Can you provide evidence supporting
    that claim, such as a program with defined behavior that's inconsistent
    with what he said?

    > *ptr is actually the value pointed to and ptr is the pointer.


    Agreed - and he wrote nothing that's inconsistent with that statement.
    --
    James Kuyper
     
    James Kuyper, Mar 15, 2013
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Phil
    Replies:
    1
    Views:
    664
    llewelly
    Sep 16, 2003
  2. muser
    Replies:
    3
    Views:
    776
    Ron Natalie
    Sep 18, 2003
  3. A
    Replies:
    3
    Views:
    467
    Alan Kelon
    Oct 29, 2003
  4. Xamalek
    Replies:
    7
    Views:
    697
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    696
Loading...

Share This Page