【C语言】指针和数组的深入理解(第一期)(上)

简介: 在开启这个章节之前,我看过很多书上都是先讲数组,后续又说数组名就是是地址,如果没有前期知识的铺垫,大多数都会想,地址是个啥玩意?到底什么是数组?什么是指针?他们之间又有什么样的关系?本章节我们将深入学习。

在开启这个章节之前,我看过很多书上都是先讲数组,后续又说数组名就是是地址,如果没有前期知识的铺垫,大多数都会想,地址是个啥玩意?到底什么是数组?什么是指针?他们之间又有什么样的关系?本章节我们将深入学习。

1、指针是什么?

在看这个问题之前,我们先引入一段简单的代码做铺垫:

int main()
{
  int a = 10; //定义a变量开辟了一块空间并且初始化
  a = 20; //使用的是a的空间:左值
  int b = a; //使用的是a的内容:右值,此时a等价于20
  return 0;
}

同过上面代码及注释,我们可以看出,同样一个 a 变量,在不同的应用场景中,a 的本身含义是不同的!

那么这个代码跟指针又有什么关系呢?

指针就是地址!就好比你 &a,取出变量 a 的地址,而这个就可以称作是指针!地址的本质上是数据!数据是可以被保存在变量空间里面的!

这里可能有人会说,你在胡说,那我之前就知道指针是存放地址的,你现在又告诉我指针就是地址?这直接把我搞糊涂了。这里你就不够严谨了!我们口头上说的指针,指的是指针变量!什么是指针变量?就是保存指针的变量,也可以说是保存地址的变量,这个变量就叫做指针变量!

从严格意义上,指针和指针变量是不同的,指针就是地址,而指针变量是C语言中的变量!要在特定区域开辟空间,用来保存地址数据,也可以被取出地址。

但是我们在口语化表达的时候,经常将这两个概念混合,是以前的书不够严谨?还是教学的人学的不够通透,或者是翻译外国资料的时候没翻译清楚?具体原因无从考证,在以后,我们分开理解,和别人讨论时,要明确概念,指针就是指针,指针变量就是指针变量!

有了上面的认识,我们再来看一段代码:

int main()
{
  int a = 10;
  int* p = &a; //取出变量a的地址放到指针变量p中
  p = (int*)0x11223344; //使用p变量的空间,左值
  int* q = p; //使用p变量的内容:右值,此时的p等价于0x11223344
  return 0;
}

我们再次总结一下:指针就是地址!指针变量本质是变量,里面保存的是地址(指针)值!

2、为什么要有指针?

这里我们举个例子来说明,张三在寝室打游戏,到了中午肚子饿了,于是拿起手机点了份外卖,外卖小哥送到寝室楼下,一头雾水(假设没有门牌号的情况下),打电话问张三:“你在哪里啊?”,张三:“我在宿舍里啊”,“你在哪个宿舍啊?”,“我不知道该怎么表达,你一间间找吧”,外卖小哥很无奈,只能一间间的找,好不容易找到对应的房间,菜都凉了,外卖小哥成功获得了一个差评。

通过上述案例,证明了门牌号的重要性,显然而知没有门牌号是多么麻烦的一件事,门牌号归根到底就是为了提高查找效率!

那么我们类比到计算机中,CPU 在内存中寻址的基本单位是字节,在32位机器下,最多能识别 4G 的物理内存,既然 CPU 寻址是按照字节,但是内存又很大,所以可以看作众多字节的集合:

其实我们门牌号就可以等价于每个字节空间对应的地址,也就是该空间对应的指针

存在指针的意义就是为了提高CPU寻址效率。

那么如何理解编址呢?

我们得了解一个概念,计算机内部是有很多硬件单元的,而硬件单元是需要互相协同工作,最基本的他们之间要互相进行信息传递,而我们一个个硬件之间是相互独立的,总得想个办法把他们相关联起来,就举例CPU和内存之间要传递大量的数据,那么他们之间就会用“线”给连起来,今天我们只关心地址总线。

在CPU需要访问内存的某一个空间的时候,必须知道这个字节空间在内存的什么位置上,因为内存中字节很多,所以就如我们上面所说引入了地址,也就是给内存进行编址,在计算机中的编址,并不是把每个字节的地址信息保存下来,而是通过各硬件厂商出厂前就设计完成了。

硬件编址也是如此,32 位机器有 32 根地址总线,每根线可以表示两种形态 0,1【高电压低电压】,也就是说 1 根线能表示 2 种含义,2 根线表示 4 种含义,以此类推,32根线能表示 2^32 种含义,而每种含义则代表着一个地址,在地址信息被下达给内存,在内存的内部就可以找到该地址对应的数据,将数据在通过数据总线传入CPU内寄存器。(点到即可)

指针的大小?

有了上面的认识就理解指针的大小就很简单了,如果是 32 位机器我们要存一个地址数据是不是应该用 4 个字节,那如果是 64 位的环境就应该用 8 个字节大小空间来存放一个地址,那么我们的结论正不正确呢?

结论:指针变量是用来存地址的,地址的大小表示是根据操作环境变化的,所以要想放得下地址的数据大小,指针的变量大小也会随着系统环境而变化。

3、指针的内存布局

在很多教材上都会说某某指针指向了某某变量,是真的指向吗?既然指针变量是用来存地址的,那一个 int 占四个字节,他存的又是哪个字节的地址呢?下面我们来一一讨论。

先看一段代码:

int main()
{
  int a = 10;
  int* p = &a;
  return 0;
}

这里我们先来分析一下,创建了一个整型 a 变量,同时初始化为 10,接着我们创建了一个整型指针变量 p ,并取出变量 a 的地址赋值给指针变量 p,那么他们的内存布局是这样的:

所以我们常说的指针变量 p 指向变量 a 实质上是指针变量 p 中存放着 a 变量的起始地址,也是最小的地址。也能明白,取地址本质是取出变量的起始地址。如果有的老师画图把指向图画在变量中间的话,那么他显然画图画的很不严谨!

相关文章
|
2月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
46 3
|
1月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
104 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
1月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
85 9
|
1月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
52 7
|
2月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
218 13
|
2月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
77 11
|
2月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
180 3
|
2月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
2月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
57 1

热门文章

最新文章