简体   繁体   English

在 C 中取消引用和将变量的地址分配给指针变量有什么区别?

[英]What is the difference between derefencing and assigning the address of a variable to pointer variable in C?

See the two codes below!看下面两个代码!

int main() {
    int a = 12;
    int *p;
    *p = a;
}

and the this code,和这个代码,

int main() {
    int a = 12;
    int *p;
    p = &a;
}

In the first piece of code dereferenced the pointer as this *p = a , and in the second piece of code, the address of variabe a is set to the pointer variable.在第一段代码中将指针解引用为 this *p = a ,在第二段代码中,变量a的地址被设置为指针变量。

My question is what is the difference between both pieces of codes?我的问题是这两段代码有什么区别?

In your first piece of code:在你的第一段代码中:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

you have a serious case of undefined behaviour because, what you are trying to do is assign the value of a to the int variable that p currently points to.你有未定义行为严重的情况,因为你正在试图做的是价值分配aint变量p目前点。 However, p has not been assigned an 'address', so it will have an arbitrary - and invalid - value!但是, p尚未分配“地址”,因此它将具有任意且无效的值! Some compilers may initialise p to zero (or NULL ) but that is still an invalid address (on most systems).某些编译器可能会将p初始化为零(或NULL ),但这仍然是无效地址(在大多数系统上)。

Your second code snippet is 'sound' but, as it stands, doesn't actually achieve anything:您的第二个代码片段是“健全的”,但就目前而言,实际上并没有实现任何目标:

int main() {
    int a = 12;
    int *p;
    p = &a;
}

Here, you are assigning a value (ie an address ) to your pointer variable, p ;在这里,您正在为指针变量p分配一个值(即地址); in this case, p now points to the a variable (that is, it's value is the address of a ).在这种情况下, p现在指向a变量(即,它的值是地址a )。

So, if you appended code like this (to the end of your second snippet):因此,如果您附加这样的代码(在第二个代码段的末尾):

*p = 42;

and then printed out the value of a , you would see that its value has been changed from the initially-given 12 to 42 .然后打印出来的值a ,你会看到它的值已经从最初赋予改变1242

Feel free to ask for further clarification and/or explanation.随时要求进一步澄清和/或解释。

Declaring *p and a is reserving some space in memory, for a pointer in first case, for what a is in the 2nd case (an int ).声明*pa是在内存中保留一些空间,用于第一种情况下的指针,第二种情况下a是什么(一个int )。

In these both cases, their values are not initialized if you don't put anything in it.在这两种情况下,如果您不将任何内容放入其中,则不会初始化它们的值。 That doesn't mean there is nothing in it, as that is not possible.这并不意味着其中没有任何内容,因为这是不可能的。 It means their values are undetermined, kind of "random" ;这意味着它们的值是不确定的,有点“随机”; the loader just put the code/data in memory when requested, and the space occupied by p , and the one occupied by a , are both whatever the memory had at the time of loading (could be also at time of compilation, but anyway, undetermined).加载程序只是在请求时将代码/数据放入内存中,而p占用的空间和a占用的空间都是加载时内存的任何内容(也可能是编译时,但无论如何,未定)。

So you take a big risk in doing *p = a in the 1 st case, since you ask the processeur to take the bytes "inside" a and store them wherever p points at.所以,你需要做一个大的风险*p = a在1的情况下,既然你问了processeur采取字节“内部” a并将它们存储的地方p点处。 Could be within the bounds of your data segments, in the stack, somewhere it won't cause an immediate problem/crash, but the chances are, it's very likely that won't be ok!可能在您的数据段的范围内,在堆栈中,不会立即导致问题/崩溃的某个地方,但很有可能,这可能不行!

This is why this issue is said to cause "Undefined Behavior" (UB).这就是为什么说这个问题会导致“未定义行为”(UB)。

The first one is bad:第一个不好:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

It means: put the value of variable a into location, pointed by pointer p .这意味着:将变量a的值放入指针p指向的位置。 But what the p points?但是p点是什么? probably nothing (NULL) or any random address.可能什么都没有(NULL)或任何随机地址。 In best case, it can make execution error like access violation or segmentation fault.在最好的情况下,它可能会导致执行错误,如访问冲突或分段错误。 In worst case, it can overwrite any existing value of totally unknown variable, resulting in problems, which are very hard to investigate.在最坏的情况下,它可以覆盖完全未知变量的任何现有值,从而导致很难调查的问题。

The second one is OK.第二个没问题。

int main() {
    int a = 12;
    int *p;
    p = &a;
}

It means: get the pointer to (existing) variable a and assign it to pointer p .这意味着:获取指向(现有)变量a指针并将其分配给指针p So, this will work OK.所以,这将正常工作。

When you initialized a pointer you can use *p to access at the value of pointer of the pointed variable and not the address of the pointed variable but it's not possible to affect value like that (with *p=a).当您初始化一个指针时,您可以使用 *p 访问指向变量的指针值而不是指向变量的地址,但不可能影响这样的值(使用 *p=a)。 Because you try to affect a value without adress of variable.因为你试图影响一个没有变量地址的值。

The second code is right use p = &a第二个代码是正确使用 p = &a

What is the difference between dereferencing and assigning the address of a variable to pointer variable in C?在 C 中取消引用和将变量的地址分配给指针变量有什么区别?

The latter is the premise for the first.后者是前者的前提。 They are separate steps to achieve the benefit of pointer dereferencing.它们是实现指针取消引用的好处的单独步骤。


For the the explanation for where the difference between those are, we have to look what these guys are separately:为了解释它们之间的区别,我们必须分别看看这些家伙是什么:


  • What is dereferencing the pointer?什么是取消引用指针?

First we need to look what a reference is.首先我们需要看看引用是什么。 A reference is fe an identifier for an object.引用是对象的标识符。 We could say "Variable a stands for the value of 12 ."我们可以说“变量a代表12的值”。 - thus, a is a reference to the value of 12 . - 因此, a是对12值的引用。

The identifier of an object is a reference for the value stored within.对象的标识符是对存储在其中的值的引用。

The same goes for pointers.指针也是如此。 pointers are just like usual objects, they store a value inside, thus they refer to the stored values in them.指针就像通常的对象一样,它们在内部存储一个值,因此它们引用其中存储的值。

"Dereferencing" is when we "disable" this connection to the usual value within and use the identifier of p to access/refer to a different value than the value stored in p . “取消引用”是当我们“禁用”与其中的常用值的这种连接并使用p的标识符来访问/引用与p存储的值不同的值时。

"Dereferencing a pointer" means simply, you use the pointer to access the value stored in another object, fe 12 in a instead through its own identifier of a . “解引用的指针”是指简单地,可以使用指针来访问存储在另一个对象,FE的值12a通过它自己的标识符而不是a

To dereference the pointer the * dereference operator needs to precede the pointer variable, like *p .要取消引用指针, *取消引用运算符需要位于指针变量之前,例如*p


  • What is assigning the address of a variable to a pointer?什么是将变量的地址分配给指针?

We are achieving the things stated in "What is dereferencing a pointer?", by giving the pointer an address of another object as its value, in analogy like we assign a value to a usual variable.我们正在实现“什么是取消引用指针?”中所述的事情,通过给指针一个另一个对象的地址作为它的值,就像我们给一个普通变量赋值一样。

But as opposed to usual object initializations/assignments, for this we need to use the & ampersand operator, preceding the variable, whose value the pointer shall point to and the * dereference operator, preceding the pointer, has to be omitted, like:但与通常的对象初始化/赋值相反,为此我们需要使用&符号运算符,在变量之前,指针应指向其值,指针之前的*取消引用运算符必须省略,例如:

  p = &a;

Therafter, The pointer "points" to the address the desired value is stored at. Therafter,指针“指向”到存储所需值的地址。


Steps to dereferencing a pointer properly:正确解引用指针的步骤:

First thing to do is to declare a pointer, like:首先要做的是声明一个指针,例如:

 int *p;

In this case, we declare a pointer variable of p which points to an object of type int .在这种情况下,我们声明了一个p的指针变量,它指向一个int类型的对象。


Second step is to initialize the pointer with an address value of an object of type int :第二步是使用int类型对象的地址值初始化指针:

 int a = 12;
 p = &a;       //Here we assign the address of `a` to p, not the value of 12.

Note: If you want the address value of an object, like a usual variable, you need to use the unary operator of & , preceding the object.注意:如果你想要一个对象的地址值,就像一个普通的变量,你需要在对象之前使用&的一元运算符。


If you have done these steps, you are finally be able to access the value of the object the pointer points to, by using the * operator, preceding the pointer object:如果你已经完成了这些步骤,你最终能够通过使用*操作符,在指针对象之前访问指针指向的对象的值:

     *p = a;

My question is what is the difference between both pieces of codes?我的问题是这两段代码有什么区别?

The difference is simply as that, that the first piece of code:区别很简单,第一段代码:

int main() {
    int a = 12;
    int *p;
    *p = a;
}

is invalid for addressing an object by dereferencing a pointer.通过取消引用指针来寻址对象是无效的。 You cannot assign a value to the pointer´s dereference, if there isn´t made one reference before to which the pointer do refer to.如果之前没有进行过指针引用的引用,则不能为指针的解引用赋值。

Thus, your assumption of:因此,您的假设是:

In the first piece of code I dereferenced the pointer as this *p = a...在第一段代码中,我将指针取消引用为 *p = a...

is incorrect.是不正确的。

You do not be able to dereference the pointer at all in the proper way with *p = a in this case, because the pointer p doesn´t has any reference, to which you are be able to dereference the pointer correctly to.在这种情况下,您根本无法使用*p = a以正确的方式解除对指针的引用,因为指针p没有任何引用,您可以正确地解除对指针的引用。

In fact, you are assigning the value of a with the statement of *p = a somewhere into the Nirwana of your memory.实际上,您正在将带有*p = a语句的a值分配到您记忆中的必杀技中。

Normally, the compiler shall never pass this through without an error.通常,编译器永远不会通过没有错误传递此。

If he does and you later want to use the value, which you think you´d assigned properly by using the pointer, like printf("%d",*p) you should get a Segmentation fault (core dumped) .如果他这样做了,而您以后想要使用该值,您认为您已经通过使用指针正确分配了该值,例如printf("%d",*p)您应该得到Segmentation fault (core dumped)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 指针和指针变量之间有什么区别? - What's the difference between a pointer, and a pointer variable? 使用FILE变量的地址和C中的FILE *有什么区别? - What is the difference between using an address of a FILE variable and a FILE * in C? 在 C 中直接传递变量地址和传递指针(指向同一变量)的区别? - Difference between passing variable address directly and passing a pointer (to same variable) in C? 指针变量的值和普通变量地址之间有什么区别,C语言中的指针有什么特殊用途? - What are the differences between pointer variable's value & address of normal variable and what are the special purpose of pointers in C? c中的volatile和指针变量之间的区别 - Difference between a volatile and a pointer variable in c C语言中的变量和指针之间的区别(对于Java开发人员)? - Difference between a variable and a pointer in C (for java developer)? C中的“ * variable”和“ * variable []”之间有什么区别? - What's difference between “*variable” and “*variable[]” in C? 直接将左移操作的结果分配给变量和C中的左移分配操作有什么区别? - What is the difference between directly assigning the result of left shift operation to a variable and the left shift assignment operation in C? 将const变量的地址分配给非const指针 - assigning address of a const variable to non const pointer 使用指针而不为其分配变量存储地址 - Using a pointer without assigning a variable memory address to it
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM