【C语言】深入理解数组和指针——初识指针

简介: 哈喽大家好,我是保护小周ღ,C语言,接下来给大家带来的是深入理解数组和指针的初识指针,这篇主要讲的是基础指针的相关知识,是博主的所见所闻,细节上的知识后面会这里面没有提,会放在后期的文章中与数组相结合讲,多多包含~

    image.gif编辑

哈喽大家好,我是保护小周ღ,C语言,接下来给大家带来的是深入理解数组和指针的初识指针,这篇主要讲的是基础指针的相关知识,是博主的所见所闻,细节上的知识后面会这里面没有提,会放在后期的文章中与数组相结合讲,多多包含~

image.gif编辑

目录

一、指针

1.1 初识指针

1.2  指针的类型

1.2.1  指针加减整数

1.3 指针的解引用

1.3.1 数据的存储


一、指针

1.1 初识指针

我们怎么理解指针呢,博主刚开始学习指针的时候天真的以为指针会指向,我们也常常说指针指向了某一块空间,这样说其实是为了方便理解指针,接下来博主带你来好好感受一下指针的奥妙~

如果大家对计算机的存储有一定的了解就知道,我们的程序其实是加载到内存中运行的,那些定义的变量,指针,数组啥的实际上就是在内存上开辟的空间。那么地址的传输一般是根据地址总线来的,如果地址总线是32位,那么代表在一单位时内可以传输32个比特位的数据,也就是4个字节,这也是为什么在32位机 的环境下,指针是4个字节的部分原因,哪怕是读取一个char 类型的数据,也是一次性读取4个字节的空间,但是只会使用当前的有效一个字节的内容。同理在64位机的环境下理论上是CPU 有能力一次性访问 64个比特位 的数据 ,那么内存中的64 位如何理解呢 ,就是在32位的基础上翻了2倍,32位是4个字节,我们所说的64位就是8个字节,(实际上就是33个比特位描述) 所以64位的指针也是8个字节,因为此时的内存的编码翻了2倍,需要用8个字节来描述。我们电脑的内存其实是有限的。 32个比特位可以描述4G 的内存,33位就是8G ,34位就是16G , 64位那得多大,我们可没有那么大的内存。可千万不要说64位机,我的内存有 2^64 这么大,只能说在64 位机的环境下,我们的内存使用 8个字节来编码。我一次性可以读取8个字节的内容。

那么32根地址线产生的地址就会是:


00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001

...

11111111 11111111 11111111 11111111

这里就有2的32次方个地址。

每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB ==

2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB) 4G的空间进行编址。

1Byte (字节)= 8 bit (比特位)  ;

1KB =1024 Byte  ;

1MB=1024KB;

1GB=1024MB;


这个类型后面添加 * 号,就相当于 告诉编译器这是个某类型指针image.gif编辑

所以指针是什么?可不可以理解为是一块4字节的空间(我这里假设指针是四个字节),实质是就是一块地址,我们常常说定义一个指针,其实说的就是指针变量,指针自身就是一块地址,然后我给他取了一个名字,给他指定了类型,那么这一块空间就可以存储相同类型的地址,我们的内存上的存储空间都是有自己的编码的,数据处理最基本的单位就是字节,所以每个字节都有自己的编码,这个就叫地址。(每一块地址都有自己独一无二的编码)

image.gif编辑

我们来分析分析,假如我们定义了 int 类型的指针变量 pa,我们还定义了一个局部变量a , 我们使用&(取地址操作符)取出变量a 的地址,整型数据其实是4个字节, 那么这四个空间的地址以其中的那一个字节地址为准呢?其实是首地址,就是四个地址最低位的为首地址,存放数据的时候从低地址往高地址存放。 我们知道了a 的地址,然后把这块地址给到指针pa 存储,你看 一个整型数据占4个字节,需要32 比特位来描述他的地址,所以一个整型指针也是4个字节。

image.gif编辑

image.gif编辑

总结:

指针变量就是用来存地址的!存放在指针变量的值都会被当成地址。

指针就是内存中的地址,指针变量就是用来存地址的。


不知道大家有没有发现一个点,就是一个 char 型的指针在内存中占4个字节,但是一个char 类型的数据占一个字节的空间,为什么char 类型的指针也需要4个字节呢,我们上面也说了,32 机,一次可以访问32位的数据,所以指针在32位的环境下占4个字节有利于存、取, 另外,在32位机的环境下需要4个字节来描述地址。


1.2  指针的类型

上面说到,我们常用的指针类型基本都是4个字节,而且某类型指针所占的大小好像跟某类型所占的大小不一样啊,那么为什么要有指针类型呢?明明都是4个字节,我要他有何用?

image.gif编辑

上图也可以进一步理解指针为什么是4个字节,哪怕他是一个结构体类型又怎么样,还是4个字节, 我们的指针只需要记住给这个结构体变量的划分的那片空间的起始字节的地址即可,然后就有能力访问,有朋友就要问了, 我们定义的结构体里面的成员 两个整型 8个字节,一个字符型 占一个字节,加起来应该是 9个字节,怎么就是12字节了呢,不难理解,上面也有讲过,32 位机的环境下,CPU 一次性可以读取4个字节的内容,9个字节要怎么读?还是要读取 3次,12字节,那干脆就多给这个结构体变量3个字节,是吧,大度一点,这个是简单的理解一下(粗略的理解),这个叫内存对齐,在不同的操作系统下,和不同的位数环境下,会有不同的表现,一般是4个字节的整数倍。

到这里我们总结一下,指针实际上就是内存上的地址,也有自己的地址编号,指针会把存储的数据当成地址来存储,就是这么设计的,指针在32位的环境下占4个字节,在64位的环境下占8个字节。

我们在上面也提到过指针的定义,类型 + ‘ * ’ + 指针名

int a=0;
int* pa=&a;

image.gif

指针类型有什么用啊,整型指针也是4个字节,字符型指针也是4个字节,结构体指针也是4个字节,反正都是存地址的,地址又没有类型,要类型有何用?


1.2.1  指针加减整数

我们来举个例子:

image.gif编辑

总结:指针的类型决定了指针向前或者向后走一步可以跳过几个字节。

整型指针+1,以当前存储的地址为基准,向高地址走4个字节,但是不会改变原先存储的地址,+2就是走8个字节咯。-1,以原存储的地址为基准,向低地址走4个字节。


1.3 指针的解引用

上面说到,指针就是内存中的地址,指针变量就是用来存地址的,那我们存储地址就需要访问地址,我们能不能通过指针存储的地址,来操作那块地址中的数据呢?可以的!

先带大家了解一个操作符, ‘ * ’  在定义的时候代表定义的是一个指针,在配合指针使用的时候就叫“解引用操作符” ,解引用是什么意思呢?举个例子。

今天是情人节,张三和自己的女朋友玩至深夜,女朋友是在太困了,就先说自己去开一间房睡觉,张三女朋友来到某某酒店(内存) 跟服务员(操作系统)说自己要一间房间,服务员看看了电脑哪里还有空房间,然后说520 房间可以使用(定义指针划分空间),随后张三对象打电话告诉张三说自己在某某酒店 520房间(地址),没关门,让他早点来休息,张三马不停蹄的来到 520 房间,果然没关门,张三此时知道女朋友在这间房间,推门而入,结果发现空无一人,张三直接糊涂了,明明女朋友给的地址是这里啊,发现床上有一个纸条,上面写的, 要想找到我,来 250 房间(对象的准确地址),去前台拿钥匙(解引用符号 ‘ * ’),别吵醒我,然后张三去前台拿到了要是然后 打开了250 房间的门,找到了女朋友。

以上故事 张三通过 520 房间(指针) 知道了女朋友的地址, 然后去前台拿钥匙 (解引用操作符   ‘ * ’  )打开了女朋友的房间。

所以 解引用操作符可以理解为,通过指针变量中存储的地址,找到该地址中存储的数据。既然找到了,那就可以修改。

image.gif编辑


image.gif编辑

总结:

指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

另外大家一定对,使用char 类型的指针一个字节一个字节打印的数据是反着来的有疑惑,在vs 2019 的环境下数据是倒着存储的, 11 22 33 44 ,实际上存储的是 44 33 22 11 ,那我们的指针可不从 44 的那个位置访问吗? 至于为什么倒着存储,且听我慢慢道来:


1.3.1 数据的存储

image.gif编辑

根据上图,我们发现,我们的值以字节为单位(我们的存储单元最基本的单位就是字节),在内存中是倒着存贮的,嘶~,好奇怪啊。

一个数值超过1个字节,要在内存中存储,那就有了存储顺序的问题。

image.gif编辑

所以大小端存储更像是一种标准。不同的编译器有着不同得存储顺序,但是一般都是大端或者是小端存储。

image.gif编辑

博主用的是VS 2019 ,所以这个编译器是小端字节序存储。


至此C语言初识指针博主已经分享完了,相信大家对指针有了不一样的理解,尽请期待数组 &&指针。

image.gif编辑

本期收录于博主的专栏——C语言,适用于编程初学者,感兴趣的朋友们可以订阅,查看其它“C语言基础知识”。C语言_保护小周ღ的博客-CSDN博客

感谢每一个观看本篇文章的朋友,更多精彩敬请期待:保护小周ღ  *★,°*:.☆( ̄▽ ̄)/$:*.°★*  

文章多处存在借鉴,如有侵权请联系修改删除!image.gif编辑

相关文章
|
7天前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
19 3
|
19天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
44 0
|
6天前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
13 2
|
15天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
23 1
|
21天前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
35 6
|
18天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
13 2
|
18天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
18天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
24天前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
24天前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。