C语言之指针

声明: 以下内容可能会引起某些读者不适, 请小心阅读. 有些内容并没有详细介绍, 可能简单理解也是错误的, 但是这都是为了尽量简单。

前言: 我自己认为, 对想要学习编程的人而言, C语言是一门必须要学习的语言, 但是其实就现在这个时代的话, 你没有学习C语言的绝对必要。使用别的高级语言(比如python)站在巨人的肩膀上很好, 也很爽。

推荐书目

  • 《C语言程序设计》
  • 《C标准库》
  • 《C primer plus》
  • 《C缺陷和陷阱》
  • 《C专家编程》
  • 《linux程序设计》

C语言指针是C语言最重要的内容,很多人在初学C语言的时候有很多疑惑。在这里我希望自己能够给大家解释清楚C语言指针的内容。

指针是什么

指针就是一个变量。 它存储的是另一个变量的地址,当然指针也可以存储其他指针的地址。(指针应该也能存放自己本身的地址,你可以试一试. 但是可能需要一些小技巧)

声明一个指针变量

1
2
int a = 10; // 声明一个int类型变量为a, 并且赋值为10
int *pa; // 声明了一个指针变量.

第二行代码我们声明了一个指针变量,虽然这个*符号在靠近pa的地方,但是在这里我们声明的变量名是pa,它的类型是一个指针类型。它是一个指向int类型数据的指针。(你需要先接受这样的C语言表述)

给指针变量的赋值

1
2
pa = &a; // &a的结果是a的地址的数值(0xff000000)这样的。
// 将这个地址值赋值给pa这个指针变量。像之前说的那样,指针变量存储的是一个地址值。

可以在声明的时候,顺便赋值

1
int *pa = &a;

在这里我们声明了一个指针变量, 它的名字是pa,我们将它的值赋值为变量a的地址。

指针的使用

1
int *p = pa;

在这里我们将之前声明好的pa指针变量的值(也就是变量a的地址)赋值给了另一个叫p的int类型的指针变量。

类比的看:

1
int b = a;

在这里我们把a的值赋值给了b, 他们俩都是int类型。

所以指针变量其实很简单, 他就是一个变量,他有普通变量的特点。但是他作为指针变量,他有他的特点。 在声明的时候,需要之前教的那样去声明。(至于说单行声明多个指针变量和单行声明多个指针变量和普通变量的方法, 我不想说。 我觉得没什么好说的。)
但是你需要知道下面这一件事情:

1
int *pa, a;

这里的a并不是指针变量。
1
int* pa, a;

这里的a也不是指针变量。

解引用符 *

我们在声明指针变量的时候,用了这个符号,但是在声明的时候,并不是解引用的意思,只是表明我们要声明的是一个指针变量。而在其他地方的使用,就应该是解引用了(我也不敢说的非常绝对)。像这样:

1
printf("a is %d", *pa); // a is 10

在这里,将输出a的值。而如果我们也要输出pa的值,也就是a这个变量的地址。 你就可以这样做:
1
printf("a is %d", pa);

为什么用指针?

我们现在知道可以用解引用的方法来访问另一个变量。所以如果你想要访问一个变量,那你可以考虑用指针的方式。特别是你需要跨函数来访问变量的时候。

对,你只需要声明一个指针变量(int *pa = &a;),让它存储另一个变量的地址, 你就可以用间接访问的方式(*pa == a), 访问到那个变量。

举个例子,我们写一个交换两个变量的值的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
void swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
int main(void)
{
int a = 10;
int b = 20;
printf("a is %d, b is %d.", a, b);
swap(&a, &b); // 在这里会把a和b的地址分别交给函数参数表里面那两个指针
printf("交换之后\n");
printf("a is %d, b is %d.", a, b);
return 0;
}

结果:

指针的声明和相互赋值还有解引用就是这样。 指针是一种操纵变量的手段。 一般来说,在c语言里面,只要你拥有一个变量的地址,你就可以访问这个变量的值。而对于哪些变量可以取地址,指针在一些数据结构中的使用,比如链表、二叉树,这需要你慢慢去体会。

也许一开始会被不太懂指针是怎么回事,但你只需要细细琢磨就可以了。指针不是C语言的难点,事实上指针的内容其实很简单。