0
点赞
收藏
分享

微信扫一扫

初学者c指针(白话文版)

什么是指针,指针类型,指针变量,指针类型 内存 野指针

Part1:

内存,指针概念,小格子,编号,地址,如何编号,格子多大,电信号,数字信号,一字节,内存单元

什么是指针,在这之前要先了解内存,内存是计算机内用来存储的物质,为了方便,我们将其按一字节一字节分为许多个小格子,按照电信号转化为的数字信号对其进行编号,这些编号被称为地址。根据地址我们可以找到相应的小格子,也就是内存单元,地址由于该特性被称为指针,找格子的这个操作也被称为“指针的解引用”,也就是“*”这个符号。

Part2:

指针类型,存放编号,指针变量,地址处理,32位,寻址线,指针大小

我们将地址当成值来保存在一个变量中,这个变量就是指针变量,指针变量和其他变量并没有什么不同,都是用来保存值的一个空间,只不过它保存的是指针(地址),有一点要注意,指针变量所占据的空间是确定的。因为该空间用来存放地址,32位系统有32根寻址线,可分为2的32次方个内存单元,所以其所占空间为4字节,同理64位占8字节。

Part3:

区分类型,字节占用,进制占用,不同可存  

因为指针变量是一块长度固定的空间,那么只要是一个地址就都可以存放进去,那么指针分类型的意义是什么?在这之前先了解一下进制

进制占用,一个二进制占用一个bit,简称位,八位为一字节,十六进制占四位,地址就是用十六进制来表示的(因为二进制太长了),但指针变量又说存放地址绰绰有余,不应该是刚刚好可以存放吗,四个字节存放32位,刚刚好呀。

Part4:

类型意义 找格子 加减整数

指针类型不同在存放时没有任何区别,都是一个小格子的地址,但在根据地址找到格子(解引用)的时候区别就来了,不同类型的指针找到的格子数不一样,char*只能找到一个格子,int*可以找到四个格子(根据地址找到第一个,在往后找三个)(在定义char或者int变量的时候,系统本就会为其分配空间,这里令指针刚好找完该空间),如果要对格子里(内存单元)的数据修改,就要先找到它。同时指针加减整数的时候,并不是在十六进制上加减该整数,与指针变量类型有关,char*是往后找一个格子,int*是往后找四个(这里指第一个格子往后的四个,换个方式理解:就是四个四个往后找,跳过),PS:格子就是内存单元,大小为一个字节,可以自己尝试定义指针变量,对指针变量进行++,然后和原本指向的相减,得到的值就是格子数,内存单元数,字节数被处理后的元素个数(格子数除于元素占据的格子数)。

Part5:

 数组名,整型移动char,野指针,局部变量,初始化,越界访问,指针空间释放

数组名就是一个地址,可以直接赋给指针变量(放到那个空间里去),一个整型四个字节,在内存中用十六进制显示给我们看(两位十六进制是一字节),如果开始整型为

00 00 00 00 ,00 00 00 00.(包含两个int的数组){0,0}定义一个某类型指针指向该数组(p)并*++p=1,等价于p=p+1;*p=1;

00 00 00 00 ,01 00 00 00(int*)值为{0,1}

00 01 00 00, 00 00 00 00(char*)值为{16*16,0}

野指针就是指针变量里边的指针(地址)不确定,是指向任意一个位置的。

危害:由于其内的地址是不确定的,所以对其进行解引用,会出现很大的问题,也许你的系统被更改后就崩溃了。

可以产生野指针的操作:

  1. 未初始化,像定义一个局部变量未初始化一般,那个空间里放的是09 98 a3 4b(int)(之前遗留下的数),局部指针变量也是如此,如果那块空间内本就有一些数,就会默认是该变量的指针。
  2. 越界访问:定义了一个整型或者整形数组,这个时候系统会为其开辟一片空间给它使用,将空间地址放入一个指针变量,·对其做了整数加减,使得最后内存单元的地址并不是原来那块空间的,即超出了这块空间。
  3. 指针空间释放:比如在某个函数中,你在其中定义了一个局部变量,并返回其地址,函数返回后局部变量所在空间被释放,但其地址被存放在一指针变量中,野指针就产生了。还有动态内存那块,如果直接将获取的内存释放,其地址还是被我们获取的,野指针就产生了
  4. 总结:有一个指向不知道哪里的指针。

对应的方法:按照能产生野指针的步骤来

  1. 定义一个指针变量后就对其进行初始化。
  2. 对指针进行变换时,注意其是否越界。
  3. 返回地址时,注意该空间是否还是该程序的。
  4. 释放地址时,将指向该空间的指针指向NULL
  5. 访问地址时注意其是否有效。
举报

相关推荐

0 条评论