简体   繁体   中英

Why can't I directly assign an int to an int pointer like this: int *p = 6;?

error: invalid conversion from 'int' to 'int*'
int *q = 8;

Works fine.
*q = 6;

Why can't I directly assign an int to an int pointer like this: int *q = 6 ; and I can assign it safely in the next line?

Because they're different things at all. The 1st one is definition of variable with initializer expression, ie an initialization (of the pointer itself):

int *         q                      = 8;
~~~~~         ~                      ~~~
type is int*; name of variable is q; initialized with 8

The 2nd one is assignment (of the object pointed by the pointer):

*q                              = 6;
~~                              ~~~
dereference on q via operator*; assign the resulting lvalue pointed by q to 6

And, int *p = 6; means define a variable named p with type int* and initialize it with 6 , which fails because 6 can't be used for initializing a pointer directly (ie the error "invalid conversion from 'int' to 'int*'").

* symbol is reused for two different purpuses in your snippet. First time it is used as a part of type declaration int * , declaring a pointer to int. Second time it is used to dereference a pointer *q , invoking indirection operator.

* can also be used to invoke multiplication operator *q = *q * *q; ;

To assign a value to an integer pointed by pointer you need to dereference it. And to assigning integral value other than 0 to a pointer itself (that is what int *q = 8; is doing) requires reinterpret_cast , hence you get this error.

Statement int *q defines a variable of type "pointer to integer", and an initialisation therefore needs to be a pointer value, not an integral value. So int *q = 8 is not the same as int *q; *q = 8 int *q; *q = 8 (which would be undefined behaviour because it dereferences an uninitialized pointer), but more like int *q; q = 8 int *q; q = 8 , which makes the misunderstanding more transparent.

This:

int *q = 8;

is an initialization. It initializes q (the pointer), not *q (what it points to). Writing this equivalently with an assignment instead of initialization would look like:

int *q;
q = 8;

So you see it doesn't make sense. (and, isn't allowed of course -- an int is not a pointer)

Just to be sure, if you write:

int *q;
*q = 8;

this is syntactically correct, but undefined behavior . Your pointer doesn't point to an object of type int , it is uninitialized and probably pointing to some invalid location. Writing there, anything could happen.

Because the types don't match.

The 6 itself is not a value of pointer type, it's an integer so it cannot be directly stored in a pointer.

When you do *q = 6 the * dereferences the pointer, so the type becomes int (or rather an lvalue int , ie something that can be assigned to).

Here, assign the value 8 to an object of type int* . It means q points on address 8 on memory.

 int *q = 8;

Is equivalent to:

int *q;
q = 8;

Is Not equivalent to:

int *q;
*q = 8;

is illegal , as it involves constraint violation .

Related stack overflow question: Is it possible to initialize a C pointer to NULL?

A pointer variable holds an address, or 'location' of something. Thus, the pointer holds a value that is a memory address. When you say:

int *q = 6;

you are creating a pointer variable that intends to point to an int, and telling it to point to the int value stored in the address 6, which is (probably) not what you really intended.

A pointer variable should point to some memory address that contains some actual data you want to access. For example:

int x = 5;
int *q = &x;

This creates a variable (x) that contains the value 5. the next line creates a pointer variable that contains the address of x. You have set the pointer variable 'q' to the address of the int variable 'x'.

Now you can see what is at 'x' by doing this:

int y;
y = *q;

This says "take what is pointed to by q, and store it in y". The end effect is that y will be set to 5.

int x = 5;     // create variable x and set it to 5
int *q = &x;   // create int pointer variable, set it to the address of x
int y;         // create variable y
y = *q;        // take the value pointed to by q, and store it in y

If, for example the variable x is at memory location 1234, and you looked at the value stored in 'q', it would be 1234, which is the address of x. When you say "y = *q", you are saying "take the value stored in the address 1234, and puts that value in y". Since the memory location 1234 is 'x', and 'x' was assigned the value 5, the value 5 will be what is stored at the address 1234.

y = *q;

will take the value stored in the address 1234 and assign y to that value, thus making y 5, which was the value stored in x, which is what q 'points' to.

This could be shortened to:

int x = 5;
int *q = &x;
int y = *q;

When you write
int *q = 8; it means you declared a pointer q and initialized a pointer with the integer 8. but q being a pointer expects a address value therefore you get error stating incompatibility.
Whereas when you write
*q=8 after declaring, it means you are dereferencing the addresses pointed by q and writing a value to that location. here q points to a int so you are writing 8 a integer value to the location pointed by q . that is right. This can also lead to error at runtime if q is not initialized to point to right location.

In your first statement you are declaring and initializing the pointer to some value of type int (on the same line). In your second statement you are changing the value pointed to by a pointer. Two different things. What you have there is initialization followed by an assignment. Don't let the * confuse you.

Because it is not valid C, simple as that. Specifically, it is a constraint violation of the assignment operator, since integer to pointer or pointer to integer is not valid forms of "simple assignment" (C11 6.5.16.1).

You can convert between integers and pointers by adding an explicit cast. The result is however not guaranteed to work: pointers and integers may have different representations and there might be alignment issues.

In case of *q = 6; you assign an int to an int, which is of course perfectly fine (given that the pointer points at allocated memory somewhere).

If you re-write it like this:

int* q = 8; 
    *q = 6;

Then you can see the * has two different purposes.

Try

int *q = new int(8);

But working with pointers here is not normally required. If you have to use pointer, use smart pointer shared_ptr<int> or uniqe_ptr<int> .

在这种情况下,您将为指针* q分配值8,并且在初始化期间将不起作用。当时的内存地址是唯一的,无法分配,但是可以为* q初始化后设置一次创建的内存块。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM