为什么我不能像这样直接将一个int赋值给一个int指针:int *p = 6;?
Why can't I directly assign an int to an int pointer like this: int *p = 6;?
错误:从 'int' 到 'int*'
的无效转换
int *q = 8;
工作正常。
*q = 6;
为什么我不能像这样直接将一个int赋值给一个int指针:int *q = 6
;我可以在下一行安全地分配它吗?
*
符号在您的代码段中被重复用于两个不同的用途。第一次它被用作类型声明的一部分 int *
,声明一个指向 int 的指针。第二次它用于取消引用指针 *q
,调用间接运算符。
*
也可用于调用乘法运算符 *q = *q * *q;
;
要为指针指向的整数赋值,您需要取消引用它。并且将 0 以外的整数值分配给指针本身(这就是 int *q = 8;
正在做的事情)需要 reinterpret_cast
,因此您会收到此错误。
语句int *q
定义了一个"pointer to integer"类型的变量,因此初始化需要是一个指针值,而不是一个整数值。
所以 int *q = 8
与 int *q; *q = 8
不同(这将是未定义的行为,因为它解引用了一个未初始化的指针),但更像 int *q; q = 8
,这使得误解更加明显。
因为类型不匹配。
6
本身不是指针类型的值,它是一个整数,不能直接存入指针
当您执行 *q = 6
时 *
取消引用 指针,因此类型变为 int
(或者更确切地说是左值 int
,即可以分配给的东西)。
如果你这样重写:
int* q = 8;
*q = 6;
然后你可以看到 *
有两个不同的用途。
因为它们完全不同。第一个是带有初始化表达式的变量定义,即 initialization(指针本身):
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
不能用于直接初始化指针(即错误"invalid conversion from 'int' to 'int*'")。
在您的第一条语句中,您声明并初始化了指向某个 int
类型值的指针(在同一行)。在您的第二条语句中,您正在更改指针指向的值。两种不同的东西。你所拥有的是初始化,然后是赋值。不要让 *
迷惑你。
这个:
int *q = 8;
是初始化。它初始化 q
(指针),而不是 *q
(它指向的内容)。用赋值而不是初始化等效地写这个看起来像:
int *q;
q = 8;
所以你看它没有意义。 (而且,当然是不允许的——int
不是指针)
只是为了确定,如果你写:
int *q;
*q = 8;
这语法 正确,但未定义的行为。您的指针未指向 int
类型的对象,它未初始化并且可能指向某个无效位置。写在那里,什么都有可能发生。
因为它不是有效的 C,就这么简单。具体来说,它违反了赋值运算符的约束,因为整数到指针或指针到整数不是 "simple assignment" (C11 6.5.16.1).
的有效形式
您可以通过添加显式强制转换在整数和指针之间进行转换。然而,结果不能保证有效:指针和整数可能有不同的表示,并且可能存在对齐问题。
在 *q = 6;
的情况下,您将一个 int 分配给一个 int,这当然很好(假设指针指向某处分配的内存)。
写的时候
int *q = 8;
这意味着你声明了一个指针 q
并用整数 8 初始化了一个指针。但是 q 作为一个指针需要一个 address value
因此你得到错误说明不兼容。
而当你写
*q=8
声明后,这意味着您正在取消引用 q
指向的地址并将值写入该位置。这里 q
指向 int
所以你写 8
一个整数值到 q
指向的位置。没错。如果 q
未初始化为指向正确的位置,这也可能导致运行时出错。
在这里,将值8
赋值给int*
类型的对象。这意味着 q
指向内存地址 8
。
int *q = 8;
等同于:
int *q;
q = 8;
不等同于:
int *q;
*q = 8;
是非法,因为它涉及违反约束。
相关堆栈溢出问题:
尝试
int *q = new int(8);
但通常不需要在此处使用指针。如果一定要用指针,就用智能指针shared_ptr<int>
或者uniqe_ptr<int>
.
在这种情况下,您将值 8 分配给指针 *q,它在初始化期间不起作用,内存地址当时是唯一的,无法分配,但您可以设置在初始化后为 *q 创建的内存块。
指针变量保存地址,或 'location' 某物。因此,指针保存的值是内存地址。当你说:
int *q = 6;
您正在创建一个指向 int 的指针变量,并告诉它指向存储在地址 6 中的 int 值,这(可能)不是您真正想要的。
指针变量应该指向一些内存地址,其中包含您要访问的一些实际数据。例如:
int x = 5;
int *q = &x;
这将创建一个包含值 5 的变量 (x)。
下一行创建一个指针变量,其中包含 x 的地址。您已将指针变量 'q' 设置为 int 变量的地址 'x'.
现在您可以通过执行以下操作查看 'x' 中的内容:
int y;
y = *q;
这表示 "take what is pointed to by q, and store it in y"。最终效果是y会被设置为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
例如,如果变量 x 位于内存位置 1234,并且您查看存储在 'q' 中的值,它将是 1234,这是 x 的地址。
当你说 "y = *q" 时,你说的是 "take the value stored in the address 1234, and puts that value in y"。由于内存位置 1234 是 'x',并且 'x' 被分配了值 5,因此值 5 将存储在地址 1234.
y = *q;
将获取存储在地址 1234 中的值并将 y 赋给该值,从而使 y 为 5,这是存储在 x 中的值,这就是 q 'points' 的值。
这可以缩短为:
int x = 5;
int *q = &x;
int y = *q;
错误:从 'int' 到 'int*'
的无效转换
int *q = 8;
工作正常。
*q = 6;
为什么我不能像这样直接将一个int赋值给一个int指针:int *q = 6
;我可以在下一行安全地分配它吗?
*
符号在您的代码段中被重复用于两个不同的用途。第一次它被用作类型声明的一部分 int *
,声明一个指向 int 的指针。第二次它用于取消引用指针 *q
,调用间接运算符。
*
也可用于调用乘法运算符 *q = *q * *q;
;
要为指针指向的整数赋值,您需要取消引用它。并且将 0 以外的整数值分配给指针本身(这就是 int *q = 8;
正在做的事情)需要 reinterpret_cast
,因此您会收到此错误。
语句int *q
定义了一个"pointer to integer"类型的变量,因此初始化需要是一个指针值,而不是一个整数值。
所以 int *q = 8
与 int *q; *q = 8
不同(这将是未定义的行为,因为它解引用了一个未初始化的指针),但更像 int *q; q = 8
,这使得误解更加明显。
因为类型不匹配。
6
本身不是指针类型的值,它是一个整数,不能直接存入指针
当您执行 *q = 6
时 *
取消引用 指针,因此类型变为 int
(或者更确切地说是左值 int
,即可以分配给的东西)。
如果你这样重写:
int* q = 8;
*q = 6;
然后你可以看到 *
有两个不同的用途。
因为它们完全不同。第一个是带有初始化表达式的变量定义,即 initialization(指针本身):
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
不能用于直接初始化指针(即错误"invalid conversion from 'int' to 'int*'")。
在您的第一条语句中,您声明并初始化了指向某个 int
类型值的指针(在同一行)。在您的第二条语句中,您正在更改指针指向的值。两种不同的东西。你所拥有的是初始化,然后是赋值。不要让 *
迷惑你。
这个:
int *q = 8;
是初始化。它初始化 q
(指针),而不是 *q
(它指向的内容)。用赋值而不是初始化等效地写这个看起来像:
int *q;
q = 8;
所以你看它没有意义。 (而且,当然是不允许的——int
不是指针)
只是为了确定,如果你写:
int *q;
*q = 8;
这语法 正确,但未定义的行为。您的指针未指向 int
类型的对象,它未初始化并且可能指向某个无效位置。写在那里,什么都有可能发生。
因为它不是有效的 C,就这么简单。具体来说,它违反了赋值运算符的约束,因为整数到指针或指针到整数不是 "simple assignment" (C11 6.5.16.1).
的有效形式您可以通过添加显式强制转换在整数和指针之间进行转换。然而,结果不能保证有效:指针和整数可能有不同的表示,并且可能存在对齐问题。
在 *q = 6;
的情况下,您将一个 int 分配给一个 int,这当然很好(假设指针指向某处分配的内存)。
写的时候
int *q = 8;
这意味着你声明了一个指针 q
并用整数 8 初始化了一个指针。但是 q 作为一个指针需要一个 address value
因此你得到错误说明不兼容。
而当你写
*q=8
声明后,这意味着您正在取消引用 q
指向的地址并将值写入该位置。这里 q
指向 int
所以你写 8
一个整数值到 q
指向的位置。没错。如果 q
未初始化为指向正确的位置,这也可能导致运行时出错。
在这里,将值8
赋值给int*
类型的对象。这意味着 q
指向内存地址 8
。
int *q = 8;
等同于:
int *q;
q = 8;
不等同于:
int *q;
*q = 8;
是非法,因为它涉及违反约束。
相关堆栈溢出问题:
尝试
int *q = new int(8);
但通常不需要在此处使用指针。如果一定要用指针,就用智能指针shared_ptr<int>
或者uniqe_ptr<int>
.
在这种情况下,您将值 8 分配给指针 *q,它在初始化期间不起作用,内存地址当时是唯一的,无法分配,但您可以设置在初始化后为 *q 创建的内存块。
指针变量保存地址,或 'location' 某物。因此,指针保存的值是内存地址。当你说:
int *q = 6;
您正在创建一个指向 int 的指针变量,并告诉它指向存储在地址 6 中的 int 值,这(可能)不是您真正想要的。
指针变量应该指向一些内存地址,其中包含您要访问的一些实际数据。例如:
int x = 5;
int *q = &x;
这将创建一个包含值 5 的变量 (x)。 下一行创建一个指针变量,其中包含 x 的地址。您已将指针变量 'q' 设置为 int 变量的地址 'x'.
现在您可以通过执行以下操作查看 'x' 中的内容:
int y;
y = *q;
这表示 "take what is pointed to by q, and store it in y"。最终效果是y会被设置为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
例如,如果变量 x 位于内存位置 1234,并且您查看存储在 'q' 中的值,它将是 1234,这是 x 的地址。 当你说 "y = *q" 时,你说的是 "take the value stored in the address 1234, and puts that value in y"。由于内存位置 1234 是 'x',并且 'x' 被分配了值 5,因此值 5 将存储在地址 1234.
y = *q;
将获取存储在地址 1234 中的值并将 y 赋给该值,从而使 y 为 5,这是存储在 x 中的值,这就是 q 'points' 的值。
这可以缩短为:
int x = 5;
int *q = &x;
int y = *q;