指针是 C 和 C++ 编程中强大的功能。在学习指针之前,让我们先了解 C 语言中的地址。
C 语言中的地址
如果你的程序中有一个变量 var,&var
将会给出它的内存地址。
我们在使用 scanf()
函数时已经多次使用过地址。
scanf("%d", &var);
这里,用户输入的值被存储在 var 变量的地址中。让我们看一个实际的例子。
#include <stdio.h>
int main()
{
int var = 5;
printf("var: %d\n", var);
// Notice the use of & before var
printf("address of var: %p", &var);
return 0;
}
输出
var: 5 address of var: 2686778
注意: 当你运行上面的代码时,你可能会得到一个不同的地址。
C 语言指针
指针(指针变量)是特殊的变量,它们用于存储地址而不是值。
指针语法
我们可以这样声明指针。
int* p;
这里,我们声明了一个 int
类型的指针 p。
你也可以这样声明指针。
int *p1;
int * p2;
让我们再举一个声明指针的例子。
int* p1, p2;
这里,我们声明了一个指针 p1 和一个普通变量 p2。
将地址分配给指针
让我们举个例子。
int* pc, c;
c = 5;
pc = &c;
这里,5 被分配给了 c 变量。然后,c 的地址被分配给了 pc 指针。
获取指针所指的内容的值
要获取指针所指向的内容的值,我们使用 *
运算符。例如:
int* pc, c;
c = 5;
pc = &c;
printf("%d", *pc); // Output: 5
这里,c
的地址被分配给了 pc 指针。要获取该地址中存储的值,我们使用了 *pc。
注意: 在上面的例子中,pc 是指针,而 *pc
不是。你不能也不会这样做 *pc = &c
;
顺便说一下,当与指针一起使用时,*
被称为解引用运算符。它作用于一个指针并给出该指针中存储的值。
更改指针所指向的值
让我们举个例子。
int* pc, c;
c = 5;
pc = &c;
c = 1;
printf("%d", c); // Output: 1
printf("%d", *pc); // Ouptut: 1
我们将 c 的地址分配给了 pc 指针。
然后,我们将 c 的值更改为 1。由于 pc 和 c 的地址相同,*pc
的值为 1。
让我们再举一个例子。
int* pc, c;
c = 5;
pc = &c;
*pc = 1;
printf("%d", *pc); // Ouptut: 1
printf("%d", c); // Output: 1
我们将 c 的地址分配给了 pc 指针。
然后,我们使用 *pc = 1;
将 *pc
更改为 1。由于 pc 和 c 的地址相同,c 的值将变为 1。
让我们再举一个例子。
int* pc, c, d;
c = 5;
d = -15;
pc = &c; printf("%d", *pc); // Output: 5
pc = &d; printf("%d", *pc); // Ouptut: -15
最初,使用 pc = &c;
将 c 的地址分配给 pc 指针。由于 c 是 5,*pc
的值为 5。
然后,使用 pc = &d;
将 d 的地址分配给 pc 指针。由于 d 是 -15,*pc
的值为 -15。
示例:指针的工作原理
让我们看一个实际的例子。
#include <stdio.h>
int main()
{
int* pc, c;
c = 22;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c); // 22
pc = &c;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc); // 22
c = 11;
printf("Address of pointer pc: %p\n", pc);
printf("Content of pointer pc: %d\n\n", *pc); // 11
*pc = 2;
printf("Address of c: %p\n", &c);
printf("Value of c: %d\n\n", c); // 2
return 0;
}
输出
Address of c: 2686784 Value of c: 22 Address of pointer pc: 2686784 Content of pointer pc: 22 Address of pointer pc: 2686784 Content of pointer pc: 11 Address of c: 2686784 Value of c: 2
程序说明
int* pc, c;
这里,创建了一个类型均为int
的指针 pc 和一个普通变量 c。
由于 pc 和 c 最初未初始化,指针 pc 指向无地址或随机地址。而变量 c 有一个地址,但包含随机的垃圾值。
c = 22;
这会将 22 分配给变量 c。也就是说,22 被存储在变量 c 的内存位置中。
pc = &c;
这会将变量 c 的地址分配给指针 pc。
c = 11;
这会将 11 分配给变量 c。
*pc = 2;
这会将指针 pc 所指向的内存位置的值更改为 2。
使用指针时的常见错误
假设你想让指针 pc 指向 c 的地址。那么,
int c, *pc;
// pc is address but c is not
pc = c; // Error
// &c is address but *pc is not
*pc = &c; // Error
// both &c and pc are addresses
pc = &c; // Not an error
// both c and *pc are values
*pc = c; // Not an error
这是一个初学者经常觉得难以理解的指针语法示例。
#include <stdio.h>
int main() {
int c = 5;
int *p = &c;
printf("%d", *p); // 5
return 0;
}
为什么我们在使用 int *p = &c;
时没有收到错误?
这是因为
int *p = &c;
等同于
int *p;
p = &c;
在这两种情况下,我们都在创建指针 p
(而不是 *p
)并将 &c
分配给它。
为了避免这种混淆,我们可以使用如下语句
int* p = &c;
现在你已经知道了什么是指针,在下一个教程中你将学习指针与数组的关系。