错误:从'int'到'int *'的转换无效
int *q = 8;
这很好。
*q = 6;
为什么我不能直接像这样将int分配给int指针:int *q = 6
,而我可以在下一行安全地分配它?
错误:从'int'到'int *'的转换无效
int *q = 8;
这很好。
*q = 6;
为什么我不能直接像这样将int分配给int指针:int *q = 6
,而我可以在下一行安全地分配它?
因为它们完全是不同的东西。第一个是带有初始化表达式的变量定义,即指针本身的初始化:
int * q = 8;
~~~~~ ~ ~~~
type is int*; name of variable is q; initialized with 8
第二个是指针所指对象的赋值:
*q = 6;
~~ ~~~
dereference on q via operator*; assign the resulting lvalue pointed by q to 6
而且,int *p = 6;
的意思是定义一个名为p
、类型为int*
并用6
初始化的变量,但这会失败,因为6
不能直接用于初始化指针(即错误“从'int'到'int*'的转换无效”)。
*
符号在你的代码片段中被重复使用了两次,第一次用作类型声明 int *
,声明一个指向整数的指针。第二次用于解引用指针 *q
,调用间接运算符。
*
也可以用于调用乘法运算符 *q = *q * *q;
;
要给一个指向整数的指针赋值,需要先对其进行解引用。将非0整数值分配给指针本身(这就是 int *q = 8;
所做的)需要 reinterpret_cast
,因此你会得到这个错误。
int *p,*q;
如果 *
属于 int
,那么您将定义两个指针为 int* p,q /*错误*/;
这是 C 兼容性的不幸残留物,因为在其他上下文中,如 std::vector<int*>
中它是类型的一部分。 - MSalters语句int *q
定义了一个指向整数的指针变量,因此初始化必须是指针值而不是整数值。
因此,int *q = 8
与int *q; *q = 8
不同(后者是未定义的行为,因为它对未初始化的指针进行了解引用),但类似于int *q; q = 8
,这使误解更加明显。
This:
int *q = 8;
是一个初始化语句,它初始化了指针q
,而不是*q
(指针指向的内容)。如果使用赋值语句等效地替换初始化语句,将会如下所示:
int *q;
q = 8;
所以你可以看到这是没有意义的。(当然也不允许——一个 int
不是指针)
只是为了确保,如果你写:
int *q;
*q = 8;
这是语法上正确的,但是行为未定义。您的指针并没有指向一个int
类型的对象,它还没有被初始化,很可能指向一些无效的位置。在那里进行写入操作会导致任何事情发生。
6
本身不是指针类型的值,而是整数类型的,因此不能直接存储在指针中。*q = 6
时,*
将对指针进行解引用,所以类型变为 int
(或者更确切地说是一个左值 int
,即可被赋值的东西)。在这里,将值8
分配给类型为int*
的对象。它意味着q
指向内存中地址8
。
int *q = 8;
等价于:
int *q;
q = 8;
不等于:
int *q;
*q = 8;
这是违法的,因为它涉及限制违规。
相关的stackoverflow问题:是否可能将C指针初始化为NULL?
指针变量保存一个地址,或者说是某个东西的“位置”。因此,指针保存的是一个内存地址。当你说:
int *q = 6;
int x = 5;
int *q = &x;
这创建了一个变量(x),它包含值5。 下一行创建了一个指针变量,它包含x的地址。您已将指针变量“q”设置为整数变量“x”的地址。
现在,您可以通过执行以下操作来查看“x”中的内容:
int y;
y = *q;
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
y = *q;
将存储在地址1234中的值赋给y,因此使y成为5,这是存储在x中的值,也就是q“指向”的值。
可以缩写为:
int x = 5;
int *q = &x;
int y = *q;
int *q = 8;
时,意味着你声明了一个指针 q
并将其初始化为整数8。但是,由于 q
是一个指针,它需要一个地址值,因此您会收到不兼容的错误提示。*q=8
时,这意味着你正在解除 q
指向的地址并向该位置写入值。在这里,q
指向一个 int
,因此你将整数值 8
写入 q
指向的位置,这是正确的。如果未将 q
初始化为指向正确位置,则也可能在运行时导致错误。int
的某个值的指针(在同一行上)。在第二条语句中,你正在更改指针指向的值。两件不同的事情。你所拥有的是初始化后跟赋值。不要让*
困扰你。因为它不是有效的C语言,就这么简单。具体来说,这是赋值运算符的约束违规,因为整数到指针或指针到整数不是“简单赋值”的有效形式(C11 6.5.16.1)。
您可以通过添加显式转换来在整数和指针之间进行转换。但结果不能保证有效:指针和整数可能具有不同的表示形式,并且可能存在对齐问题。
在*q = 6;
的情况下,您将一个int赋给另一个int,这当然是完全可以的(前提是指针指向某个已分配的内存位置)。