Thread: Pointers with the & symbol

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    80

    Pointers with the & symbol

    Three of the following have the same value. Which value of the following is different?
    a. *&Ptr
    b. &*Ptr
    c. *Ptr
    d. Ptr


    In the books that i have the only ones presented are a,c , d. I read that the asterisk is to tell that its a pointer. The & is a dereference for the address. But I have never seen B. Is B the memory address of a pointer?
    Is D just a variable?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    All of the alternatives show something that is (at least) an rvalue. As the question states, three of them have the same value, a fourth one is different. D is "the value of the pointer itself".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Jul 2008
    Posts
    80
    So D is the value of the pointer
    C is a pointer itself
    A is pointer to the memory address of pointer

    I unerstand that D is the different one, but what is B or is B even legal?

    but B
    a. *&Ptr
    b. &*Ptr
    c. *Ptr
    d. Ptr

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    They are all legal.

    The following compiles without warning in gcc with -Wall -Wextra -pedantic -ansi - of course, it would not show the correct value of the pointers if it was on a 64-bit machine, as int is only 32-bit, so the cast "looses" the upper part of the pointer.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        int *ptr = malloc(sizeof(int));
        *ptr = 42;
        
        printf("%d\n", (int)&*ptr);
        printf("%d\n", (int)*&ptr);
        printf("%d\n", (int)*ptr);
        printf("%d\n", (int)ptr);
    
        return 0;
    }
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Jul 2008
    Posts
    80
    what you just said just went right over my head. I tried to put compile it on my windows vista machine using Dev C++ and it said "Invalid conversion from void to int"

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Emeighty View Post
    what you just said just went right over my head. I tried to put compile it on my windows vista machine using Dev C++ and it said "Invalid conversion from void to int"
    Probably because you are compiling it as C++ - I'm sorry, I posted C code in a C++ forum. Quick fix - insert the following in place of the existing malloc line:
    Code:
        int *ptr = (int *)malloc(sizeof(int));

    Edit: Complete C++ example:
    Code:
    #include <iostream>
    
    int main()
    {
        int *ptr = new int;
        *ptr = 42;
        
        std::cout << reinterpret_cast<int>(&*ptr) << std::endl;
        std::cout << reinterpret_cast<int>(*&ptr) << std::endl;
        std::cout << reinterpret_cast<int>(*ptr) << std::endl;
        std::cout << reinterpret_cast<int>(ptr) << std::endl;
    
        return 0;
    }
    --
    Mats
    Last edited by matsp; 08-18-2008 at 06:42 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #7
    Registered User
    Join Date
    Jul 2008
    Posts
    80
    Thanks alot for the help, really appreciate it.

  8. #8
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by Emeighty View Post
    I read that the asterisk is to tell that its a pointer. The & is a dereference for the address.
    Not exactly.
    * and & have different meaning depending on how they're used.
    If they're used when declaring a variable, like this:
    Code:
    int num;
    int* pInt;
    int& rInt = num;
    The first is a regular int, the second is creating a pointer to an int, and the third is creating a reference to an int.
    But if used like this:
    Code:
    cout << *pInt;
    cout << &num;
    The first is de-referencing a pointer to get the actual value of the int, and the second is getting the address of the num variable (i.e. getting a pointer to it).

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The funny thing is that C++ allows you to stack these operators. And if you do, you might get them to "cancel out" each other.

    Say &*p.
    Dereference p, then take its address. Basically if we call p level 1, then *p becomes level 0 and then &p becomes level 1 again. So it's kind of pointless to do that, but it's possible.

    *&p is another neat one. The result is the address stored in the pointer.
    Basically, the p is level 1. Apply & and you get level 2, which is the address of the pointer, T**. Then dereference the pointer to pointer and it becomes level 1 again, the pointer, T*.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    So it's kind of pointless to do that, but it's possible.
    It's useful when p is a smart pointer and you want the real address.

    Note that in the first post, it's actually C that's the odd one out. Furthermore, a and d are completely identical, whereas b is slightly different in that it's an rvalue, not an lvalue. The difference? Well, it's rather complicated, but for example, you can apply address-of to an lvalue, but not an rvalue.

    d: ptr -> &ptr = valid
    a: *&ptr -> &*&ptr = valid
    b: &*ptr -> & &*ptr = invalid (parsing issue aside - note that I put a space between the two ampersands)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  2. Installing Direct X
    By bumfluff in forum Game Programming
    Replies: 36
    Last Post: 11-15-2006, 07:18 PM
  3. Problem with OpenGL tutorial
    By 2Biaz in forum Windows Programming
    Replies: 18
    Last Post: 09-16-2004, 11:02 AM
  4. debug to release modes
    By DavidP in forum Game Programming
    Replies: 5
    Last Post: 03-20-2003, 03:01 PM
  5. Compiler errors
    By BellosX in forum C Programming
    Replies: 2
    Last Post: 09-21-2001, 03:24 AM