16. C语言 -- 指针

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dugudaibo/article/details/83277723

本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙

1. 内存是如何存放变量的?

  通过变量名对变量进行访问和存储是为了方便程序员而设计的,其实在内存中完全没有存储变量名的必要。因为编译器知道具体每一个变量名对应的存放地址,所以当你读取某个变量的时候,编译器就会找到变量名所在的地址,并根据变量的类型读取相应范围的数据。比如下面这张图

在这里插入图片描述

在上图中,左侧表示变量名与地址之间的关系,右边表示地址与存放的值之间的关系。我们可以看到,变量名 f 对应一个地址10005,123 占据了10005-10008 的 4 个地址(因为 C 语言中的 int 型变量占据 4 个字节)。所以可以根据地址和数据的类型,来确定具体存放的是什么。

2. 指针和指针变量

  通常我们所说的指针,就是地址的意思。C 语言中有专门的指针变量用于存放指针,跟普通变量不同,指针变量存储的是一个地址指针变量也有类型,它的类型就是存放的地址指向的数据类型。比如说下面的这张图

在这里插入图片描述

在上图中分为三个部分,最左边是变量名与地址之间的关系,a - g 很好理解,和之前一样,代表每一个变量的变量名都对应着一个地址,其中需要注意的是我们又定义了两个指针变量:pa 和 pb,因为它们是指针变量,所以它们在内存中也是存放于某个地址中。由上图左侧可知,指针变量被存放在地址 11000中;指针变量是占 4 个字节的空间,也就是说一个地址是占 4 个字节的空间,所以指针变量中存放的是 10000;又由于指针变量存放的是变量的地址,所以指针指向的是 ‘F’ 。同样可以知道,指针变量 pf 存放的是 123 的地址。

3. 定义指针变量

  定义指针变量跟普通变量十分相似,只是中间多了一个星号(*)。

char *pa;
int *pb;

左侧的数据类型表示指针变量中存放的地址指向的内存单元的数据类型。比如刚才的图中,指针变量 pa 中存放字符变量 a 的地址,所以 pa 应该定义为字符型指针;而指针变量 pb 中存放的是整型变量 f 的地址,所以 pb 就定义为整型指针。这点一定要注意,因为不同数据类型所占的内存空间不同,如果指定错误了,那么在访问指针变量指向的数据时就会出错。

4. 取地址运算符和取值运算符

  如果需要获取某个变量的地址,可以使用取地址运算符(&),下面是定义一个指针并进行初始化的过程

// 其中 a 和 f 时已经存在的变量
char *pa = &a;
int *pb = &f;

// 也可以写成如下的形式
char *pa;
pa = &a;

如果需要访问指针变量指向的数据,可以使用取值运算符(*)

printf("%c, %d\n", *pa, *pb);

这里要注意的是取值运算符跟定义指针用的都是星号(*),这属于符号的重用,在不同的地方有不同的意义:在定义时表示定义一个指针变量;在其他位置表示获取指针变量指向的变量的值。直接通过变量名来访问变量的值,我们称之为直接访问;通过指针变量这样的形式来访问变量的值,我们称之为间接访问,所以取值运算符有时候也叫间接运算符

  在这里其实可以看到,初始化指针和对指针取值可以看作是一个互为相反的过程。初始化是将一个地址赋值给指针变量(如 pa = &a;),而要修改指针所对应变量的值的操作,就需要取值操作(如 *pa=b)。

5. 避免访问未初始化的指针

#include <stdio.h>

int main()
{
    int *a;
    *a = 123;

    return 0;
}

  类似于上边这样的代码是很危险的,因为指针变量 a 到底指向哪里,我们没办法知道。这个道理就跟访问未初始化的变量一样,它的值是随机的。这在指针变量里会很危险,因为后边代码对一个未知地址进行赋值,那么你可能会覆盖到系统的一些关键代码。不过你也别高兴得太早,因为系统通常都不会允许你这么干,程序这时候会被终止并报错。更危险的是,偶尔这个指针变量里随机存放的是一个合法的地址,那么接下来的赋值就会导致那个位置的值莫名其妙地被修改。这种类型的 Bug 是非常难以排查的。所以,在对指针进行间接访问时,必须确保它们已经被正确地初始化

6. 本节内容概要

  本节的主要内容如下,指针就是内存中的地址;指针变量适用于存放指针的变量,即存放地址的变量;指针变量的类型是变量中存放的地址对应的数据的类型;指针变量作为一个变量,本身有一个地址,它的地址中存储的是另一个变量的地址。

参考

[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P21

欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dugudaibo/article/details/83277723