取消引用和将变量的地址分配给 C 中的指针变量有什么区别?
What is the difference between derefencing and assigning the address of a variable to pointer variable in C?
看下面两个代码!
int main() {
int a = 12;
int *p;
*p = a;
}
和这段代码,
int main() {
int a = 12;
int *p;
p = &a;
}
在第一段代码中将指针解引用为this *p = a
,在第二段代码中,变量a
的地址被设置为指针变量。
我的问题是这两段代码有什么区别?
在你的第一段代码中:
int main() {
int a = 12;
int *p;
*p = a;
}
你有一个严重的 未定义行为 的情况,因为你试图做的是将 a
的值分配给 int
变量p
目前指向。但是,p
尚未分配 'address',因此它将具有任意 - 和 invalid - 值! 一些 编译器可能会将 p
初始化为零(或 NULL
),但这仍然是一个无效地址(在 大多数 系统上).
您的第二个代码片段是 'sound',但就目前而言,实际上 没有实现任何目标:
int main() {
int a = 12;
int *p;
p = &a;
}
在这里,您正在为您的指针变量 p
分配一个值(即 地址 );在这种情况下,p
现在 指向 a
变量(也就是说,它的值是 地址 a
).
因此,如果您将这样的代码附加到(到第二个代码段的末尾):
*p = 42;
然后打印出a
的值,你会看到它的值已经从最初给定的12
变成了42
.
随时要求进一步澄清and/or解释。
第一个不好:
int main() {
int a = 12;
int *p;
*p = a;
}
表示:将变量a
的值放入指针p
指向的位置。但是 p
点是什么?可能什么都没有(NULL)或任何随机地址。在最好的情况下,它可能会导致执行错误,例如访问冲突或分段错误。在最坏的情况下,它可能会覆盖完全未知变量的任何现有值,从而导致难以调查的问题。
第二个可以。
int main() {
int a = 12;
int *p;
p = &a;
}
意思是:获取指向(现有)变量a
的指针并将其赋值给指针p
。所以,这可以正常工作。
当你初始化一个指针时,你可以使用 *p 来访问指向变量的指针的值,而不是指向变量的地址,但是不可能像那样影响值(*p=a) .因为你试图影响一个没有变量地址的值。
第二个代码正确使用 p = &a
声明 *p
和 a
在内存中保留一些 space,第一种情况下是指针,第二种情况下 a
是什么(int
).
在这两种情况下,如果您不在其中放置任何内容,它们的值将不会被初始化。这并不意味着里面没有 nothing,因为那是不可能的。这意味着它们的值尚未确定,有点像 "random" ;加载程序在请求时只是将 code/data 放入内存中,而 p
占用的 space 和 a
占用的 a
都是当时内存中的任何内容加载(也可能在编译时,但无论如何,未确定)。
因此,在第 1st 种情况下,您在执行 *p = a
时冒了很大的风险,因为您要求处理器将字节 "inside" a
并将它们存储在 p
指向的任何地方。可能在数据段的范围内,在堆栈中,某处它不会导致 立即 problem/crash,但很有可能 非常 可能不行!
这就是为什么这个问题据说会导致 "Undefined Behavior" (UB)。
What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?
后者是前者的前提。它们是实现指针取消引用的好处的独立步骤。
为了解释它们之间的区别在哪里,我们必须分别看看这些家伙是什么:
- 什么是取消引用指针?
首先我们需要看看什么是引用。引用是 f.e。对象的标识符。我们可以说 "Variable a
stands for the value of 12
." - 因此,a
是对 12
.
值的引用
对象的标识符是对存储在其中的值的引用。
指针也是如此。指针就像普通的对象一样,它们在内部存储一个值,因此它们引用其中存储的值。
"Dereferencing"是当我们"disable"这个连接到通常的值内并且使用p
的标识符到access/refer到一个不同于存储的值的值p
.
"Dereferencing a pointer" 的意思很简单,您使用指针访问存储在另一个对象 f.e 中的值。 12
in a
而不是通过它自己的标识符 a
.
要取消引用指针,*
取消引用运算符需要在指针变量之前,如 *p
.
- 什么是将变量的地址分配给指针?
我们正在实现 "What is dereferencing a pointer?" 中所述的事情,方法是为指针提供另一个对象的地址作为其值,类似于我们为普通变量赋值。
但是与通常的对象 initializations/assignments 不同,为此我们需要使用 &
符号运算符,在变量之前,指针指向的值和 *
必须省略指针之前的取消引用运算符,例如:
p = &a;
之后,指针 "points" 指向存储所需值的地址。
正确取消引用指针的步骤:
首先要做的是声明一个指针,如:
int *p;
在本例中,我们声明了一个p
的指针变量,它指向一个int
.
类型的对象
第二步是用int
类型对象的地址值初始化指针:
int a = 12;
p = &a; //Here we assign the address of `a` to p, not the value of 12.
注意:如果你想要一个对象的地址值,就像一个普通的变量,你需要在对象之前使用&
的一元运算符。
如果您完成了这些步骤,您最终可以通过使用 *
运算符访问指针指向的对象的值,在指针对象之前:
*p = a;
My question is what is the difference between both pieces of codes?
区别就这么简单,第一段代码:
int main() {
int a = 12;
int *p;
*p = a;
}
对于通过取消引用指针来寻址对象无效。如果在指针确实引用之前没有进行引用,则不能为指针的取消引用赋值。
因此,您的假设:
In the first piece of code I dereferenced the pointer as this *p = a...
不正确。
在这种情况下,您根本无法使用 *p = a
以正确的方式解除对指针的引用,因为指针 p
没有任何引用,您将能够正确取消对指针的引用。
事实上,你正在将 a
的值与 *p = a
的语句赋值到你记忆中的涅盘中。
通常,编译器应该 永远不会在没有错误的情况下通过它。
如果他这样做了,而你稍后想使用你认为你通过使用指针正确分配的值,比如 printf("%d",*p)
你应该得到一个 Segmentation fault (core dumped)
.
看下面两个代码!
int main() {
int a = 12;
int *p;
*p = a;
}
和这段代码,
int main() {
int a = 12;
int *p;
p = &a;
}
在第一段代码中将指针解引用为this *p = a
,在第二段代码中,变量a
的地址被设置为指针变量。
我的问题是这两段代码有什么区别?
在你的第一段代码中:
int main() {
int a = 12;
int *p;
*p = a;
}
你有一个严重的 未定义行为 的情况,因为你试图做的是将 a
的值分配给 int
变量p
目前指向。但是,p
尚未分配 'address',因此它将具有任意 - 和 invalid - 值! 一些 编译器可能会将 p
初始化为零(或 NULL
),但这仍然是一个无效地址(在 大多数 系统上).
您的第二个代码片段是 'sound',但就目前而言,实际上 没有实现任何目标:
int main() {
int a = 12;
int *p;
p = &a;
}
在这里,您正在为您的指针变量 p
分配一个值(即 地址 );在这种情况下,p
现在 指向 a
变量(也就是说,它的值是 地址 a
).
因此,如果您将这样的代码附加到(到第二个代码段的末尾):
*p = 42;
然后打印出a
的值,你会看到它的值已经从最初给定的12
变成了42
.
随时要求进一步澄清and/or解释。
第一个不好:
int main() {
int a = 12;
int *p;
*p = a;
}
表示:将变量a
的值放入指针p
指向的位置。但是 p
点是什么?可能什么都没有(NULL)或任何随机地址。在最好的情况下,它可能会导致执行错误,例如访问冲突或分段错误。在最坏的情况下,它可能会覆盖完全未知变量的任何现有值,从而导致难以调查的问题。
第二个可以。
int main() {
int a = 12;
int *p;
p = &a;
}
意思是:获取指向(现有)变量a
的指针并将其赋值给指针p
。所以,这可以正常工作。
当你初始化一个指针时,你可以使用 *p 来访问指向变量的指针的值,而不是指向变量的地址,但是不可能像那样影响值(*p=a) .因为你试图影响一个没有变量地址的值。
第二个代码正确使用 p = &a
声明 *p
和 a
在内存中保留一些 space,第一种情况下是指针,第二种情况下 a
是什么(int
).
在这两种情况下,如果您不在其中放置任何内容,它们的值将不会被初始化。这并不意味着里面没有 nothing,因为那是不可能的。这意味着它们的值尚未确定,有点像 "random" ;加载程序在请求时只是将 code/data 放入内存中,而 p
占用的 space 和 a
占用的 a
都是当时内存中的任何内容加载(也可能在编译时,但无论如何,未确定)。
因此,在第 1st 种情况下,您在执行 *p = a
时冒了很大的风险,因为您要求处理器将字节 "inside" a
并将它们存储在 p
指向的任何地方。可能在数据段的范围内,在堆栈中,某处它不会导致 立即 problem/crash,但很有可能 非常 可能不行!
这就是为什么这个问题据说会导致 "Undefined Behavior" (UB)。
What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?
后者是前者的前提。它们是实现指针取消引用的好处的独立步骤。
为了解释它们之间的区别在哪里,我们必须分别看看这些家伙是什么:
- 什么是取消引用指针?
首先我们需要看看什么是引用。引用是 f.e。对象的标识符。我们可以说 "Variable a
stands for the value of 12
." - 因此,a
是对 12
.
对象的标识符是对存储在其中的值的引用。
指针也是如此。指针就像普通的对象一样,它们在内部存储一个值,因此它们引用其中存储的值。
"Dereferencing"是当我们"disable"这个连接到通常的值内并且使用p
的标识符到access/refer到一个不同于存储的值的值p
.
"Dereferencing a pointer" 的意思很简单,您使用指针访问存储在另一个对象 f.e 中的值。 12
in a
而不是通过它自己的标识符 a
.
要取消引用指针,*
取消引用运算符需要在指针变量之前,如 *p
.
- 什么是将变量的地址分配给指针?
我们正在实现 "What is dereferencing a pointer?" 中所述的事情,方法是为指针提供另一个对象的地址作为其值,类似于我们为普通变量赋值。
但是与通常的对象 initializations/assignments 不同,为此我们需要使用 &
符号运算符,在变量之前,指针指向的值和 *
必须省略指针之前的取消引用运算符,例如:
p = &a;
之后,指针 "points" 指向存储所需值的地址。
正确取消引用指针的步骤:
首先要做的是声明一个指针,如:
int *p;
在本例中,我们声明了一个p
的指针变量,它指向一个int
.
第二步是用int
类型对象的地址值初始化指针:
int a = 12;
p = &a; //Here we assign the address of `a` to p, not the value of 12.
注意:如果你想要一个对象的地址值,就像一个普通的变量,你需要在对象之前使用&
的一元运算符。
如果您完成了这些步骤,您最终可以通过使用 *
运算符访问指针指向的对象的值,在指针对象之前:
*p = a;
My question is what is the difference between both pieces of codes?
区别就这么简单,第一段代码:
int main() {
int a = 12;
int *p;
*p = a;
}
对于通过取消引用指针来寻址对象无效。如果在指针确实引用之前没有进行引用,则不能为指针的取消引用赋值。
因此,您的假设:
In the first piece of code I dereferenced the pointer as this *p = a...
不正确。
在这种情况下,您根本无法使用 *p = a
以正确的方式解除对指针的引用,因为指针 p
没有任何引用,您将能够正确取消对指针的引用。
事实上,你正在将 a
的值与 *p = a
的语句赋值到你记忆中的涅盘中。
通常,编译器应该 永远不会在没有错误的情况下通过它。
如果他这样做了,而你稍后想使用你认为你通过使用指针正确分配的值,比如 printf("%d",*p)
你应该得到一个 Segmentation fault (core dumped)
.