[英]Obtaining address of pointer in C with and without ampersand, what's the difference?
我很难理解本指南中有关C指针的代码 。 我以为您需要一个&符来引用一个指针的地址,但是指南的代码设法在没有一个的情况下获得了它。 我修改了他们的代码,做了一次更改,我将其注释为“我的添加的行”。 该线与上方的线相同,但带有“&”号。 这些行的评估会产生非常相似的值,但不会产生相同的值。 我的逻辑往哪里去?
谢谢Nakul
#include <stdio.h>
int main () {
int var = 20; /* actual variable declaration */
int *ip; /* pointer variable declaration */
ip = &var; /* store address of var in pointer variable*/
printf("Address of var variable: %x\n", &var );
/* address stored in pointer variable */
printf("Address stored in ip variable: %x\n", ip );
/* MY ADDED LINE: address stored in pointer variable */
printf("Address stored in ip variable: %x\n", &ip );
/* access the value using the pointer */
printf("Value of *ip variable: %d\n", *ip );
return 0;
指针只是一个普通变量,将其他地址作为其值。 换句话说,一个指针指向可以找到其他内容的地址。 通常您会想到一个包含立即数的变量,例如int a = 5;
,指针将仅保存内存中存储5
的地址,例如int *b = &a;
。
作为普通变量,指针本身具有地址。 它的地址是变量本身的地址,而不是变量存储的地址。 例如, char buf[] = "foo", *p = buf;
创建一个数组buf
和用于在第一个字符分配地址buf
如由保持的地址 p
(例如p
指向的第一个字符在buf
)。 但是p
本身在内存中有一个地址。 它是p
的地址, buf
第一个字符的地址保存在内存中。 一个简短的示例可能会有所帮助:
#include <stdio.h>
int main (void) {
char buf[] = "foo",
*p = buf;
printf ("address for buf : %p\n"
"address of 1st char : %p\n"
"address held by p : %p\n"
"address for p itself : %p\n",
(void*)buf, (void*)&buf[0], (void*)p, (void*)&p);
}
使用/输出示例
$ ./bin/pointeraddr
address for buf : 0x7fffbfd0e530
address of 1st char : 0x7fffbfd0e530
address held by p : 0x7fffbfd0e530
address for p itself : 0x7fffbfd0e540
现在,让我们仔细看看指针的内容和指针地址(指针的内容保存在内存中)。为简单起见,我们仅使用地址中的最后三个数字。
char buf
数组存储在内存中的什么位置?
+---+---+---+---+
| f | o | o | \0| buf - array of char
+---+---+---+---+
5 5 5 5
3 3 3 3
0 1 2 3
访问数组时,该数组将转换为指向第一个元素的指针,但要遵循以下条件:
(p3)除非它是
sizeof
运算符,_Alignof
运算符或一元'&'
运算符的操作数,或者是用于初始化数组的字符串文字 ,否则类型为“ array of type”的表达式将转换为类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素,而不是左值。
C11标准-6.3.2.1其他操作数-左值,数组和函数指示符(p3)
buf
数组中的第一个字符是什么? (答案: buf[0]
)第一个字符的地址是什么(使用一元'&'
运算符)? 它与buf的地址相同,但具有指向char的类型指针 (与buf
并置,后者在访问时是指向 char[4]
数组的指针 )
那p
呢? 它有自己的地址,用于存储buf
第一个字符的地址,例如
+---+ p - pointer to char
| 5 |
| 3 | holds the address 0x7fffbfd0e530
| 0 |
+---+
5
4 stored at 0x7fffbfd0e540
0
如何获得p
持有的地址中的值(字符)? 您使用一元解引用运算符*p
。 您如何获得p
持有的地址? p
已经是一个指针,因此简单地评估p
本身就可以得到p
持有的地址,例如
char *q = p;
q
现在保存由p
存储的地址,该地址存储在内存中创建q
的新地址处。
或者,非常简单地,要打印现在也由q
持有的p
的地址,只需将p
(或q
)转换为(void*)
并使用"%p"
转换说明符进行打印,例如
printf ("address held by p & q : %p\n", (void*)p);
没魔术 指针只是一个变量,将其他内容的地址作为其值。 与任何变量一样,它具有自己的地址。 如果您以这种方式考虑,则始终可以弄清楚所拥有的东西以及需要做什么才能获取存储在该地址的值。
仔细检查一下,如果您还有其他问题,请告诉我。
逻辑向南,因为“&”为您提供了一个指针(在您的情况下为指向该指针的指针)。 让我用正确的术语来调整您的代码,然后它应该变得清楚:
printf("Address stored in ip variable, pointing to
the memory location of var: %x\n", ip );
printf("Address pointing to the (memory location / address)
of pointer ip which itself contains the (memory location /
address) of var: %x\n", &ip );
你用过
int var = 20;
int *ip;
ip = &var;
并且您打印了&var, ip, &ip *ip
在这里, &var
和ip
将指示保存20的内存地址。 *ip
将指示值20。最重要的是&ip
。 调用int *ip
,将创建此变量的存储区。 所以ip
占用一些内存区域。 当您打印&ip
,这将指示ip(contains the address of var)
保存在的内存地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.