一、基本概念

1、指针是什么?

指针就是地址。

2、地址又是什么?

地址是内存单元的编号。

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

  • 内存分为了很多单元或者很多小格子,每个格子一个编号。相当于我们的房子,一个房子一个编号,内存是一个格子一个编号,每个格子只能存放8个0或者8个1。
  • 内存条中分为了很多小单元。一个单元有8位,可以存放8个0或者8个1,内存单位 ,而是 字节,也就是不是一个0或者一个1为一个编号,而是8个0或者8个1组合在一起是一个编号。一个字节等于8位。
  • 8个0或者8个1是一个编号,接着又是8个0或者8个1是一个编号。这个编号就是地址。

4、小结

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

二、特点

其实并不难,无非就是要多想一会。特点如下:

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

三、Demo

 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

四、指针分类

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