原创

C语言指针

温馨提示:
本文最后更新于 2022年06月17日,已超过 9 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

C语言指针学习笔记

要了解清楚指针的知识,首先要从数据的存储开始

数据在内存中的存储

在编写程序的时候,我们都会向内存申请空间,用来存储数据,申请多少呢,这就要看我们所定义的类型来判断,这里举以下几个例子

int //4个字节
char//一个字节
short//2个字节

这里我们定义一个整型来说明数据在内存中的存储形式

int a = 12345;

这里定义的a在内存中是怎么存储的呢?计算机组成原理中说到,计算机所能存储的都是01的这些数,所有的数字在内存中的存储都是以01的形式(二进制形式),那这个1234就会被计算机转化为二进制的数11 0000 0011 1001存储在内存里面又因为int是4个字节32个bit位所以在内存中是这样存储的(涉及到原码,补码,反码的问题,如果是负数的话就不是这样了):

0000 0000 0000 0000 0011 0000 0011 1001

那他在内存中是怎么存储的呢,我们来调试一下
在这里插入图片描述
可以看到这里面显示的是39 30 90这里我们可能会有好多的问题,为什么不同并且反向了呢!这里就涉及到了二进制和十六进制还有大端小端存储的问题,这里主要是指针,对这个问题不做过多赘述 。
从上面例子中可以看出,数据被计算机分配给了内存来存储,但是为什么要储存呢,如果是没有用的话,我们就没必要储存了,肯定后面是要操作这个数据,才会专门存储他的。但是用的时候又怎么找到这个数据呢,这里计算机就给每一个值取了一个名字,方便以后我们来使用的时候能找到这个值,这个名字是是什么呢,可以看到39 30 90 前面还有一个值这个值其实就是计算机给这几个数取的一个名字0x00CFFD50,我们可以这样来理解
在这里插入图片描述
每一个房间都会有一个自己对应的房间号,那么这里就得思考一个问题,当我们通过地址去寻找这个值
12345
的时候我们是怎么去寻找的呢,是不是全部的房间地址的和或者某一个值呢!

在访问数据的时候指针是怎么用的呢

其实很简单好,指针其实是指向了这组数据的第一个值得地址,不要问为什么,这里我也不太清楚为什么他要这样设计,涉及到知识点还是有很多的,需要我们长时间的去学习,现在只需要知道指针其实就是指向数据的第一个名字的一个东西
在这里插入图片描述
所以有的地方说指针其实就是地址,这个意思就是将我们这里所说的name和指针两个东西说成一样了,其实也是可以这么理解的,因为指针就是指向这个name的,其实指针也是有自己的地址的,这个是二级指针,这里可以先不用管,既然指针要操作数据那么指针是不是也有自己的规定呢,没错,使用指针的时候也必须遵循一定的规则。

指针的各项参数

  • 指针所指向的地址

指针所指向的是一组数据的第一个值得地址

  • 指针的类型

指针的类型有很多种,怎么分类呢,这里就要预定于我们些定义的数据类型,包括自定义类型和C语言本身就有的类型,这里就用例子来说明

int ,char,short,long,bool
//这些就是C语言本身已经给出来的类型,我们在使用的过程中只申明就好了
struct stu
{
};
//像这种结构体,或者枚举类型的就是自定义类型,类型是由我们自己来决定的,具体知识可以了解自定义类型

所以通过这几个例可以看出来指针其实是有很多种类型的,从上面也可以知道只要存在name那么就有唯一的一个指针与之对应,那么不难想到,指针的类型和我们定义的数据类型有一定的关联,没错,这个关联很大,这里先给几个例子来说明
int的指针类型就是int*char的类型就是char*,我们可以看出,其实指针类型就是在数据类型之后加一颗*同时把指针的名字去除,没错就是这样的这颗*就是指针的代表,那么现在我们是不是可以了解指针类型了

  • 指针所指向的类型

其实不难理解这里,假如定义了一个int a =10,那么这个数据类型是不是就是int,指针所指向的数据的类型是不是就是int,这时指针的类型是不是int*,那么指针所指向的类型是不是就是int。如果这样不好理解的话,那么就用一个更简单的方法来理解

指针的类型和指针所指向的类型

其实我们记住这样一个方法就好了,指针的类型就是在原类型之后加*,指针所指向的类型就是拿走原类型后面的一颗*,为什么说一颗呢,因为只要是一个数据都会有自己的内存,那么就会有自己的name,那么就会有自己的指针,这是二级指针,我们来看几个例子:

int* a = 10,指针类型为:int*,指针的名字:a,指针所指向的类型:int
int** a = 10,指针的类型为:int**,指针的名字:a,指针所指向的类型:int*
如果我们知道操作符的运算顺序,和数组的知识那么我们还可以来看一种
int* (*a)[10]= 10,指针类型:int*(*)[10],指针的名字:a,指针所指向的类型int*

每一种数据都有指针,但是都是类似的只要我们学习好一种就可以触类旁通了
那为什么会有指针类型,和指针所指向的类型这两种说法呢,其实他都是有意义的

  • 指针所指向的类型:其实就是这个数据的类型,他告诉我们这个指针所指向的内存里面究竟存储了什么样是数据
  • 指针的类型:这个就相对来说比较难和重要了,因为他决定了指针所能操作的数据的大小(宽度),为什么这样说呢,因为每一个指针他指向的就仅仅是第一个地址,那么我们所能操作的数据的大小就由这个指针的类型决定了,如果没有指针类型来决定的话,那么我们是不是就只能操作指针所指向的那个地址的那个值了

指针操作数据

C语言规定在32位机器上,指针所占的内存为4字节,64位上为8字节,如果指针的类型如果正常的话,那么我们可以操作一整个数据,如果不正常的话,我们可以来思考一下会发生什么情况,当然就是可以操作的数据会减少

  • 我们可以看这个
# include<stdio.h>
int main()
{
int a = 12345;
int* p = &a;
char* p1 = &a;
printf("p= %p\n",p);
printf("p1= %p\n",p1);
*p = 0;
printf("把a的值改为0得a到值为:%d",a);
return 0;
}

在这里插入图片描述
可以看到这里面整型指针和字符型指针都可以存储变量a的地址(name),而且通过*p可以把12345改为0,这是正常情况,就是说用整型指针来操作整型变量,那么来看看通过字符型指针来操作呢

# include<stdio.h>
int main()
{
int a = 12345;
int* p = &a;
char* p1 = &a;
printf("p= %p\n",p);
printf("p1= %p\n",p1);
*p1 = 0;
printf("把a的值改为0得a到值为:%d",a);
return 0;
}

在这里插入图片描述
可以看到用字符型的指针来操做整型数据的话并不能将其改为0,而是改为了12288
从这里我们可以看出,指针的大小是由我们的计算机来决定的,所以他可以存储任意类型的地址,但是却不能操作不相同的数据类型,其实我们通过转化为二进制的形式后可以发现,*p1仅仅只把一个字节的内容改为了0,那么就可以验证其实,指针的类型影响着我们能操作数据的宽度,虽然指针所能存储的数据大小都是相同的,但是指针的类型影响着我们对数据的操作,所以在定义指针之前要根据实际情况来确定指针的类型。

指针的其他知识

指针的知识还有很多,但是只要我们了解了指针究竟是什么东西的话,就大概可以了解指针的其他知识了,在指针这里,很多人都是不了解他的形成,导致不会应用指针,但只要我们理解了指针是个什么东西,那其他指针问题也将迎刃而解

正文到此结束