当前位置: 首页 > 文档资料 > C 语言程序设计 >

C语言指针初步

优质
小牛编辑
140浏览
2023-12-01

今天我们进入到嵌入式C语言高级部分的第三个内容-C内存空间的使用。

学习目的

在本章内容中,我们将给大家展示一下C语言对于内存空间指向和内存空间使用上的一些技巧。在我们上一个阶段中,我们只是明白了C语言给我们带来的关键字和运算符。但是C语言的核心-操作内存资源的方式方法,这些我们没有介绍。在本个学习阶段,我们将重点围绕C语言访问内存空间的方式,以及访问空间需要使用的一些技巧来展开。

指针介绍

之前我们曾经说过,C语言操作内存的方式非常简单。CPU通过地址找到我们的内存(内存可以是内存条,显卡,USB等等设备….),内存的资源怎么样被找到?我们需要寻找到我们需要的资源,这就是我们经常在硬件中看到的寻址。通过寻找他的地址,也就是内存的门牌号,我们就可以找到这一片资源,然后才能去使用这里的数据。

这里就有了一个新的概念-地址。在C里面,我们并没有取名一个关键字叫address,也没有这种类型。C里面采用的是指针,利用指针去描述地址的概念。我们访问内存空间就需要依靠指针,找到资源其实就是使用指针去指向它的地址。我们可以理解为指针就是内存类型资源地址、门牌号的代名词。

指针的存储

指针指向的是内存资源,但是它自己本身存储在哪?指针只是一个概念,我们要使用这个指针,就应该有一个指针变量。变量就是我们在内存中圈出一块地,然后我们在这块地上面去存储一些东西。变量在内存中实实在在的存在的。

指针变量 : 存放指针这个概念的盒子。

我们可以举一个例子。比如一个int类型的变量int a;这个红色方框就是我们圈出的一块大小为32bit的地,它存储int变量的值(int变量在各个编译器中有可能被理解为不同的大小)。那么我们该如何去定义指针变量?

为了显示出指针的存储地址的能力与其他变量是不同的,于是就有了一个新的符号*。*号如果后面是数值,我们都知道那是乘法的意思。一旦*号后面跟的是一个合法的标识符,比如*p(指针变量定义名称的时候都喜欢以P_开头,代表pointer),这就是一个变量名为p的指针变量。

C语言编译器对指针这个特殊的概念,有2个疑问?分配一个盒子,盒子要多大?

内存是一大片的空间,我们就用内存的地址,也就是它的门牌号来查找具体的一小块内存。现在我们的电脑的内存1个G还是很简单的。我们现在需要的是怎么访问这1个G里面的内存的每一个字节。我们应该用什么来描述这些内存呐?

1GB=2^10MB=2^20KB=2^30Byte。所以如果我们希望去描述内存的每一个字节(Byte),如果我们采用整型去依次为这些内存赋一个门牌号,从0开始编号,一个字节就是一个房间,那么1个G的内存需要2^30个数字。我们必须保证内存的所有地址通过指针都是可以访问得到的。在32位操作系统中:两个关于32位的概念。

1)数据的处理就是32位的,高于32位的数据就不能够处理了。

2)CPU操作内存的大小也就是32位的。它只能够操作2^32这么多的内存,2^32Byte=4GB,所以32位操作系统的内存条最大只能4G,再大也没用了。

指针变量也是一个存储地址的变量,存储这个地址需要多大的空间,在32bit系统中,指针就4个字节。

当我们理解了这个概念之后,我们就明白char *p或者是xxx *p,保存这个指针变量的地址都是4个字节。4个字节就是存放其它内存地址的门牌号,这是一个整型。指针变量将它解释为地址。

盒子里存放的地址 所指向 内存的读取方法是什么?

当我们看到指针的时候,就应该想到它存储的是地址,那么这个地址指向的内存又需要多大?编译器在看到有一个指针变量声明的时候,它就需要知道这个指针变量所指向的空间大小。难道指针指向的空间在我们读取的时候只是读取一个字节吗?那就和char类型一样了。所以指针的定义在于我们不仅要知道数据存储的首地址,还要知道这段内存应该读取多少个字节。

如果我们定义一个char *p,编译器首先看到我们声明了一个指针变量*p,然后就会发现前面的char类型的大小,就让编译器知道如果我们需要读取这个指针的值内存应该读取一个字节。前面的类型可以有很多,比如int,double,struct等等

我们需要对指针有这样的理解

1)指针就是一个地址;

2)指针变量有两个属性,其中第二个属性非常关键,关于内存的读取方法一定要心里有数,不同的内存读取方法还有不同的现象和结果。