What is the difference between float pointer and int pointer address?

后端 未结 3 1390
醉话见心
醉话见心 2021-01-02 09:20

I tried to run this code,

int *p;
float q;
q = 6.6;
p = &q;

Though it will be a warning, but i think &q and p

相关标签:
3条回答
  • 2021-01-02 09:31

    You're getting undefined behaviour, because you're passing the wrong types to printf. When you tell it to expect a float, it actually expects a double - but you pass an int.

    As a result it prints the wrong information, because printf relies entirely on the format string to access the arguments you pass it.

    0 讨论(0)
  • 2021-01-02 09:32

    In addition to what is said by teppic,

    Consider,

    int a = 5;
    int *p = &a;
    

    In this case we indicate to the compiler that p is going to point to an integer. So it is known that when we do something like *p , at runtime, the no. of bytes equal to size of an int would be read.

    If you assign address of a datatype occupying x number of bytes to a pointer of which is declared to hold the address of datatypes of fewer bytes than x, you read the wrong number of bytes when using the indirection operator.

    0 讨论(0)
  • 2021-01-02 09:38

    You need to take compiler warnings more seriously.

    C doesn't require compilers to reject invalid programs, it merely requires "diagnostics" for rule violations. A diagnostic can be either a fatal error message or a warning.

    Unfortunately, it's common for compilers to issue warnings for assignments of incompatible pointer types.

    void main()
    

    This is wrong; it should be int main(void). Your compiler may let you get away with it, and it may not cause any visible problems, but there's no point in not writing it correctly. (It's not quite that simple, but that's close enough.)

    int *p;
    float q;
    q = 6.6;
    

    That's ok.

    p = &q;
    

    p is of type int*; &q is of type float*. Assigning one to the other (without a cast) is a constraint violation. The simplest way to look at it is that it's simply illegal.

    If you really want to do this assignment, you can use a cast:

    p = (int*)&q; /* legal, but ugly */
    

    but there's rarely a good reason to do so. p is a pointer to int; it should point to an int object unless you have a very good reason to make it point to something else. In some circumstances, the conversion itself can have undefined behavior.

    printf("*p =  %f \n q = %f, p = %p, &q = %p \n",*p,q,p,&q);
    

    The %f format requires a double argument (a float argument is promoted to double in this context so float would be ok). But *p is of type int. Calling printf with an argument of the wrong type causes your program's behavior to be undefined.

    %p requires an argument of type void*, not just of any pointer type. If you want to print a pointer value, you should cast it to void*:

    printf("&q = %p\n", (void*)&q);
    

    It's likely to work without the cast, but again, the behavior is undefined.

    If you get any warnings when you compile a program, don't even bother running it. Fix the warnings first.

    As for the question in your title, pointers of type int* and float* are of different types. An int* should point to an int object; a float* should point to a float object. Your compiler may let you mix them, but the result of doing so is either implementation-defined or undefined. The C language, and particularly many C compilers, will let you get away with a lot of things that don't make much sense.

    The reason that they're distinct types is to (try to) prevent, or at least detect, errors in their use. If you declare an object of type int*, you're saying that you intend for it to point to an int object (if it's not a null pointer). Storing the address of a float object in your int* object is almost certainly a mistake. Enforcing type safety allows such mistakes to be detected as early as possible (when your compiler prints a warning rather than when your program crashes during a demo for an important client).

    It's likely (but not guaranteed) that int* and float* are the same size and have the same internal representation. But the meaning of an int* object is not "a collection of 32 (or 64) bits containing a virtual address", but "something that points to an int object".

    0 讨论(0)
提交回复
热议问题