C语言内存中的地图,方向盘,初始指针详解(1)

简介: C语言内存中的地图,方向盘,初始指针详解(1)

各位少年,大家好,我是博主那一脸阳光,今天给大家分享C语言中的指针的基本概念,由于指针的类型比较多,所以我们采取多篇博客来解释。

前言

在探索C语言的广袤世界中,指针无疑是最具魔力与深邃的元素之一。它就像一把神秘的钥匙,解锁了数据在内存中的秘密花园;又如同一位技艺高超的向导,引领我们在复杂的数据迷宫中自由穿行。

想象一下,你置身于一个巨大的图书馆,每一本书都代表着一块内存空间,存储着特定的信息。而“指针”,便是一张写有书架编号和位置的地图,指向那些珍贵的知识宝藏。当你手握指针,就拥有了瞬间抵达任意书籍的能力,可以阅读、修改或移动这些信息。在这个类比中,改变指针所指向的位置,就好比更换了书架上的书籍;通过指针来操作内存中的数据,则类似于翻阅书本并记录新的篇章。

因此,在C语言的舞台上,掌握指针的艺术就是掌握了高效操控内存和数据的秘诀。这不仅能帮助我们更深入地理解程序运行机制,更能使代码变得更加简洁且强大。让我们一起揭开指针的神秘面纱,以全新的视角去解读这个编程世界中不可或缺的角色。

内存和地址

假设有⼀栋宿舍楼,把你放在楼⾥,楼上有100个房间,但是房间没有编号,你的⼀个朋友来找你玩,

如果想找到你,就得挨个房⼦去找,这样效率很低,但是我们如果根据楼层和楼层的房间的情况,给

每个房间编上号,如:

⼀楼:101,102,103…

⼆楼:201,202,203…

有了房间号,如果你的朋友得到房间号,就可以快速的找房间,找到你。

bit - ⽐特位
byte - 字节
KB
MB
GB
TB
PB

我们知道计算上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数

据也会放回内存中,那我们买电脑的时候,电脑上内存是8GB/16GB/32GB等,那这些内存空间如何⾼ 效的管理呢?

其实也是把内存划分为⼀个个的内存单元,每个内存单元的⼤⼩取1个字节。 计算机中常⻅的单位(补充): ⼀个⽐特位可以存储⼀个2进制的位1或者0

⽣活中我们把⻔牌号也叫地址,在计算机中我们 把内存单元的编号也称为地址。C语⾔中给地址起 了新的名字叫:指针

所以我们可以理解为:

内存单元的编号 == 地址 == 指针

CPU访问内存中的某个字节空间,必须知道这个 字节空间在内存的什么位置,⽽因为内存中字节 很多,所以需要给内存进⾏编址(就如同宿舍很

多,需要给宿舍编号⼀样)。 计算机中的编址,并不是把每个字节的地址记录 下来,⽽是通过硬件设计完成的。 钢琴、吉他

上⾯没有写上“都瑞咪发嗦啦”这样 的信息,但演奏者照样能够准确找到每⼀个琴弦 的每⼀个位置,这是为何?因为制造商已经在乐

器硬件层⾯上设计好了,并且所有的演奏者都知 道。本质是⼀种约定出来的共识! 硬件编址也是如此。 ⾸先,必须理解,计算机内是有很多的硬件单

元,⽽硬件单元是要互相协同⼯作的。所谓的协 同,⾄少相互之间要能够进⾏数据传递。 但是硬件与硬件之间是互相独⽴的,那么如何通

信呢?答案很简单,⽤"线"连起来。 ⽽CPU和内存之间也是有⼤量的数据交互的,所 以,两者必须也⽤线连起来。

不过,我们今天关⼼⼀组线,叫做地址总线。 我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表⽰0,1【电脉冲有⽆】,那么

⼀根线,就能表⽰2种含义,2根线就能表⽰4种含 义,依次类推。32根地址线,就能表⽰2^32种含 义,每⼀种含义都代表⼀个地址。

地址信息被下达给内存,在内存上,就可以找到 该地址对应的数据,将数据在通过数据总线传⼊ CPU内寄存器。

总结

内存被划分为一个个的单元,一个内存单元的大小就是一个字节。
每个内存单元都给一个编号,这个编号就是地址,C语言中把地址又称为:指针
编号==地址==指针

指针变量和地址

取地址操作符(&)

理解了内存和地址的关系,我们再回到C语言,在C语言中创建变量其实就是向内存申请空间,比如:

#include <stdio.h>
int main()
{
 int a = 10;//向内存中申请四个字节
 return 0;
}

如何获得a的地址?

很显然用取地址操作符就可以了。

#include <stdio.h>
int main()
{
 int a = 10;
 &a;
 return 0;
}

这样我们就取到了a的地址,但是a的地址是什么呢?那不是我们得打印出来看看喽,看下面例子。

#include <stdio.h>
int main()
{
 int a = 10;
printf("%p\n",&a);//%p打印地址操作符
 return 0;
}

输入的结果是16进制的输出方式,一个16进制位就是4个二进制。把上面每个代码转换为二进制以后,就是在计算机内存储的地址(计算机存储的是二进制,打印的是16进制地址)。

指针变量和解引⽤操作符(*)

那我们通过取地址操作符(&)拿到的地址是⼀个数值,⽐如:0x006FFD70,这个数值有时候也是需要

存储起来,⽅便后期再使⽤的,那我们把这样的地址值存放在哪⾥呢?答案是:指针变量中。

```c
#include <stdio.h>
int main()
{
 int a = 10;
 int* pa = &a;//取出a的地址并存储到指针变量pa中
 
 return 0;
 }
```指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址

我们看到pa的类型是 int* ,我们该如何理解指针的类型呢?

int a = 10;

int * pa = &a;

这⾥pa左边写的是 int* * 是在说明pa是指针变量,⽽前⾯的 int 是在说明pa指向的是整型(int)

类型的对象。

例子

那如果有⼀个char类型的变量ch,ch的地址,要放在什么类型的指针变量中呢?

char ch = 'w';
pc = &ch;//pc 的类型怎么写呢?

解引⽤操作符

我们将地址保存起来,未来是要使⽤的,那怎么使⽤呢?

在现实⽣活中,我们使⽤地址要找到⼀个房间,在房间⾥可以拿去或者存放物品。

C语⾔中其实也是⼀样的,我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)

指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符(*)。

#include <stdio.h>
int main()
{
 int a = 100;
 int* pa = &a;
 *pa = 0;
 return 0;
}

上⾯代码中第7⾏就使⽤了解引⽤操作符, *pa 的意思就是通过pa中存放的地址,找到指向的空间,

pa其实就是a变量了;所以pa = 0,这个操作符是把a改成了0.

有同学肯定在想,这⾥如果⽬的就是把a改成0的话,写成 a = 0; 不就完了,为啥⾮要使⽤指针呢?

其实这⾥是把a的修改交给了pa来操作,这样对a的修改,就多了⼀种的途径,写代码就会更加灵活,

后期慢慢就能理解了。

指针变量的⼤⼩

前⾯的内容我们了解到,32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后

是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4

个字节才能存储。

如果指针变量是⽤来存放地址的,那么指针变的⼤⼩就得是4个字节的空间才可以。

同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要

8个字节的空间,指针变的⼤⼩就是8个字节

#include <stdio.h>
//指针变量的⼤⼩取决于地址的⼤⼩
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)
int main()
{
 printf("%zd\n", sizeof(char *));
 printf("%zd\n", sizeof(short *));
 printf("%zd\n", sizeof(int *));
 printf("%zd\n", sizeof(double *));
 return 0;
}
总结

在C语言的奇幻旅程中,掌握指针运用的艺术就好比掌握了驾驭编程世界的魔法。它使我们能够以更直接、更灵活的方式触及程序运行的核心,赋予代码生命与活力。指针,这一强大的工具,不仅提升了我们对计算机底层运作机制的认知深度,也极大地拓宽了问题解决的可能性空间。

犹如那神秘的地图指引着我们在信息的海洋里游刃有余,善用指针,就如同手持一把解开内存迷局的万能钥匙,于无形之中驾驭数据流转的脉络。因此,在这场探索之旅的终点,每一位深入钻研C语言的勇者都将领略到指针所带来的无穷魅力和无尽潜力。让我们携手揭开更多未知的秘密,共同驾驭这把开启高效编程之门的“金钥匙”,在C语言的世界里书写属于我们的精彩篇章。

相关文章
|
1月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
49 0
|
7天前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
50 12
|
4天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
15天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
43 4
|
28天前
|
C语言
【c语言】动态内存管理
本文介绍了C语言中的动态内存管理,包括其必要性及相关的四个函数:`malloc`、``calloc``、`realloc`和`free`。`malloc`用于申请内存,`calloc`申请并初始化内存,`realloc`调整内存大小,`free`释放内存。文章还列举了常见的动态内存管理错误,如空指针解引用、越界访问、错误释放等,并提供了示例代码帮助理解。
39 3
|
30天前
|
存储 Rust C#
内存指针解引用
【10月更文挑战第14天】
32 1
|
1月前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
18 2
|
1月前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
1月前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
1月前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
下一篇
无影云桌面