理解C语言指针

简介: 指针在c语言中就是一种变量用于存储地址的变量。与普通变量无异

指针

理解指针

指针在c语言中就是一种变量用于存储地址的变量。与普通变量无异。

(1)就像  int a;   这就是定义了一个整型变量a,a变量是用于存储整型数据的。

(2)指针的定义,取决于你是用于存储那种类型地址的,比如

         ①存储整型的地址这样定义int *p

         ②存储浮点型的地址这样定义float *q

(3)那么地址是个什么样子的呢?地址其实就是内存空间的编号,我们在代码中编写的变量字符是不会被放入内存的,比如:

         int a=20;

如上a=20,最后在内存中是没有a的,a只是在编译期间存在的,在内存中是这样存储的。

         ①在内存开辟(或找到)一个4字节(int是4字节)大小的空间,将20的二进制数放进去

         ②这个空间有个编号,也就是地址,这里的指针就是用于存储这个编号的(地址的)

2345_image_file_copy_400.jpg

        指针就是存储上图紫色编号的(也就是地址),这就是为什么指针是面向内存层面的,只要把它(指针)指向的空间中的东西一改,内存中的数据不就改了。

声明指针

     在上面也说过,存储什么类型的地址,就声明什么类型的变量(也就是指针)。只要在该变量前加个星号(*)就可以说明这个变量是存储该类型地址的指针了。

声明方式

     int *a;//存储整型内存空间地址的变量,它的名字叫a(记住是叫a,不是*a,*相当于和int是一个“类型”的)

      float *b;//存储浮点型内存空间地址的变量,它的名字叫b

其他类型就不用多bb了

取值

      既然是指向内存的编号(地址),那它咋样取出那块空间里的值呢?

2345_image_file_copy_401.jpg

      如上图指针中存储的是001,我们该如何取出20?

      只要给地址前面加*,就是存储空间中的值的,也就是*001,输出后就是20,如果001被存储在某个指针中如p,那么*p就是20了。

赋值

      前面说过指针可以取值,那么指针该如何赋值呢,指针是存储地址(也就是内存编号)的,所以只能将地址值赋给指针,可千万不能赋其他的东西。那么怎么将地址付给指针呢,&加变量名就是地址。

比如       int a=20;

             int *p;

      怎么将存储20的内存空间的地址给p呢,好的,p只能存储地址,那就给它地址,怎么给?&a就是,对应上图,a是20,&a就是001。再结合一下上面的取值,那么*p就又是20了。

&+变量名(数)=地址

*+指针变量(地址)=空间中的那个数

指针与数组

数组

      数组是什么?数组就是存储同一类型的数据的“集合”,如int a[3],那么a数组就可以存储3个整型的数据。那么它们在内存中是什么样子的呢?比如:a[0]=100;  a[1]=101;  a[2]=102;

2345_image_file_copy_402.jpg

      记住数组的所有元素都是连续的,必须是连续存放在内存中的。而且内存中只有编号(也就是地址)和存储空间的概念。a[0],a[1]这种东西只存在于编译期。

指针存储数组的地址

      int *p,由前面可知,p是一个用来存储整型数据存储空间编号(也就是地址)的变量。那p可不可以存储030呢?答案是可以。那p可以不可以存储031呢?答案也是可以,自然而然032也是可以的。为什么呢?因为他们都是整型存储空间的地址,而p又恰好是存储整型存储空间地址的变量。

结合前一节的

&+变量名(数)=地址

*+指针变量(地址)=空间中的那个数

进行演示

存储方法:&+变量名(数)=地址

存储地址030:p=&a[0];//在数组中a[x]就相当于一个变量

存储地址031:p=&a[1];//在数组中a[x]就相当于一个变量

存储地址032:p=&a[2];//在数组中a[x]就相当于一个变量

取值方法:*+指针变量(地址)=空间中的那个数

地址为030的存储空间中的数:*p

地址为030的存储空间中的数:*p

地址为030的存储空间中的数:*p

代码截图

2345_image_file_copy_403.jpg

指针存储数组地址的一点点不同

1、如上面的int a[3],在数组中可以直接用一个数组名a来表示a[0]的地址,那么我们在给p赋值的时候可以直接p=a就可以了。(代替了p=&a[0])

2345_image_file_copy_404.jpg

2、在数组中可以通过地址+[数字]的方式来访问该地址所指向的存储空间中的数据。比如:地址1[0]:就是访问地址1所代表的空间中的数据,那么地址1[1]:就是访问地址1所代表的空间的下一个空间中的数据。

2345_image_file_copy_405.jpg

2345_image_file_copy_406.jpg

      其实结合1、2可以看出数组的a就代表一个地址(地址存储在a中),那么a[x]可以访问到数据,凭什么我p[x]访问不到?当然可以访问到,毕竟我p中也存储了地址。

扩展

1、结合上面的分析看懂这个应该没问题。

2345_image_file_copy_407.jpg

2、其实地址也可以做加减运算,比如p中存储了一个地址,那么(p+1)就表示p的下一个地址,(p-1)就表示p的前一个地址。

2345_image_file_copy_408.jpg

      自然而然*(p-1),*(p+1)是什么意思也就知道了。*+指针变量(地址)=空间中的那个数也可以通过(p-1)[0],(p+1)[0]取出。

2345_image_file_copy_409.jpg

指针与malloc函数

在创建链表或树的时候我们经常会遇到如下这样形式的代码

2345_image_file_copy_410.jpg

要想知道上面这句是什么意思,那得知道:

(1)sizeof函数是什么意思

(2)malloc函数是什么意思

(3)p中存储的是什么

由于上面涉及到了自定义结构体D,所以下面以整型数据说明,整型的会了,其它的自然就触类旁通了。

(1)sizeof(类型),将某类型传入sizeof,则会返回该类型在内存中所占空间的大小(以字节为单位返回)

2345_image_file_copy_411.jpg

(2)malloc(字节),malloc函数会根据程序员的需求在内存中开辟相应大小的存储空间,只需要程序员将空间大小传入即可(传入字节)。当malloc开辟好空间后就会将这个空间的地址给我们返回,我们只需要用相应类型的指针变量进行接收就可以了。

比如:malloc(4),则会开辟下面那个绿框框,然后将001返回。

2345_image_file_copy_413.jpg

(3)由上述可知,p中自然而然存储的就是地址喽。

说明

      虽然malloc返回的是地址,但是它是什么类型的地址呢,该用什么类型的p接收呢?

      之前就说过什么样类型的p接收什么样的地址,你malloc只返回一个泛泛的地址,我哪知道用什么样类型的p接收,于是就将malloc返回的地址根据我们的需求转成相应的地址。

如:     (int *)malloc(字节)//将那个泛泛的地址转成整型的地址

           (char *)malloc(字节)//将那个泛泛的地址转成字符型的地址

可以这样理解

      malloc就是一个洗澡堂,里面出来一群光溜溜的人,你肯定不知道这些人是干什么的,但如果他们穿着衣服出来,你就会知道,哦原理这个是警察、那个是医生、他是农民工…

案例解释

2345_image_file_copy_414.jpg

第二行:因为malloc函数是在stdlib.h文件中的所以需要引入该文件

第三–六行:定义一个结构体,叫D,说白了就是自己创建了一种类型,类型的名称叫D,就像int、char一样。

第九行:声明存储D类型空间地址的变量。

第十一行:先用sizeof看看咱们自己定义的这个类型是几个字节,然后再给返回的地址穿个衣服(D*),最后用p接收这个地址。

2345_image_file_copy_415.jpg

指针获取结构体中的元素

     书接上文,既然p里存储里结构体中的地址,我们怎样获取结构体存储空间中的值呢?是(*p),p[0]呢?还是其它什么,如果仔细思考一下,就会发现之前的这两种方式不可以了,因为现在这个存储空间中不止一个数据元素,可能有多个,通过上面这两种方式到底是获取谁的值呢。所以(1)我们要指明是获取谁(2)再获取这个“谁”的值。反过来在赋值的时候也是同样的,先指明是谁,在给这个“谁”赋值。

      这里的指明是谁,这个“指明”用符号“->”表示

示例

2345_image_file_copy_417.jpg

图解

第十一行:

2345_image_file_copy_418.jpg

第十四—十八行:

2345_image_file_copy_419.jpg

完结(ง •_•)ง

相关文章
|
2月前
|
存储 C语言
【C语言篇】深入理解指针3(附转移表源码)
【C语言篇】深入理解指针3(附转移表源码)
42 1
|
2月前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
52 0
|
12天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
2月前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
20 2
|
2月前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
2月前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
2月前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
2月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
2月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
2月前
|
C语言
C语言指针(3)
C语言指针(3)
14 1