我很难理解本指南关于 C 语言指针的代码。我认为您需要一个&符号来引用指针的地址,但指南的代码设法在没有&符号的情况下获取它。我修改了他们的代码,进行了一项更改,我将其注释为“我添加的行”。该行与上面的行相同,但包含一个 & 符号。这些线的评估产生非常相似的值,但不相同的值。我的逻辑哪里不对了?
#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
运算符,或一元'&'
运算符,或者是字符串 literal 用于初始化一个数组,一个具有类型的表达式 “类型数组” 转换为类型为 “指向类型的指针” 的表达式,该表达式指向数组对象的初始元素,并且是 不是左值。
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
的新地址。或者,非常简单,要打印
p
现在也由
q
持有的地址,只需将 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)
的内存地址。