0 学习目标

  • 理解指针
  • 理解内存单元编号
  • 理解指针类型变量

1 基本概念

1、指针是什么?

指针就是地址。

2、地址又是什么?

地址是内存单元的编号。

3、内存单元的编号又是什么?

  • 内存分为了很多单元或者很多小格子,每个格子一个编号。相当于我们的房子,一个房子一个编号,内存是一个格子一个编号,每个格子只能存放8个0或者8个1,就像每个房子有固定的房间“三室一厅”。
  • 内存条中分为了很多小单元。一个单元有8位,可以存放8个0或者8个1,内存单位不是 位(Bit),而是 字节(Byte),也就是不是一个0或者一个1为一个编号,而是8个0或者8个1组合在一起是一个编号。一个字节等于8位。就像内存这套房屋的布局是“8个房间为一套房”。
  • 8个0或者8个1是一个编号,接着又是8个0或者8个1是一个编号,这个编号就是地址。

4、小结

指针就是地址,指针和地址是一个概念。

2 特点及作用

其实并不难,无非就是要多想一会。

作用

  • 可以表示一些复杂的数据结构。
  • 可以快速传递数据。
  • 可以使函数返回一个以上的值。
  • 可以直接访问硬件。
  • 能方便处理字符串。
  • 是理解面向对象语言中引用的基础。

3 分析与理解

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include "stdio.h"

int main(void) {
  int * p;
  int i = 3;
  int j;

  // p = i;  // ERROR, 类型不一致,p 只能存放 int 类型变量的地址,不能存放int类型变量的值
  // p = 66; // ERROR,原因同上
  p = &i;    // OK

  j = *p;    // 等价于 j = i;
  printf("i = %d, j = %d, *p = %d\n", i, j, *p); // i = 3, j = 3, *p = 3

  return 0;
}

解释

p是变量的名字,int *表示p变量存放的是int类型变量地址。变量意味着在内存中一块空间,这个空间一定是有编号的,这个编号就是变量的地址。

int * p;不是定义了一个名字叫做 *p 的变量;

int * p;应该这样理解,p是变量名,p变量的数据类型是int *int *类型就是存放int类型变量地址的类型。

p = &i; 表示的含义:字面上理解是将i的地址发送给了p,但是不能只这样理解,还要思考更深层的潜在的含义。

  1. p 保存了 i 的地址,因此 p 指向 i;为什么呢?因为 p 里面是 i 的地址,通过 p 就能找到 i,所以 p 指向 i。比如我知道你的家庭地址,我就可以找到你。

  2. p 不是 i,i 也不是 p,修改 p 的值不会影响 i 的值,修改 i 的值也不会影响 p 的值;为什么呢?因为 p 和 i 是两个不同的变量。 我和你都是人嘛,我和你都是有家庭地址的,我家装修了会影响到你家吗?不会,你家装修了会影响到我家吗?也不会。

  3. 如果一个指针变量指向了某个普通变量,则 *指针变量就完全等同于这个普通变量(取地址的逆运算) 例子:如果 p 是个指针变量,并且 p 存放了普通变量 i 的地址,则 p 指向了普通变量 i,*p 就完全等同于 i, 或者所有出现 *p 的地方都可以替换成 i,所有出现 i 的地方都可以替换成 *p

  4. *p 表示的是以 p 的内容为地址的变量,p 的内容就是 i 的地址,以 i 的地址为地址的变量就是 i

4 指针分类

  1. 基本类型指针
  2. 指针和数组
  3. 指针和函数
  4. 指针和结构体
  5. 多级指针