一、指针是什么

在计算机内存中,每一个内存单元都有其对应的地址,用以标识该单元。就如同小区的楼号、门牌号具体定位到每个户主一样,计算机通过这个地址来标识每一个内存单元。一个内存单元的大小是1个字节,里面可以存储数据,就如同房间里面住人一样。

而指针实际上就是一个内存单元的地址,但在大多数情况下,所说的指针指的是指针变量,指针变量存储指针(也就是内存单元的地址),这方面如同整形变量存储整数一样。

(下文的指针均指代指针变量)

&这一操作符可以取得某一变量的地址,由此可以将其存放到指针变量里,指针变量存储的是变量的起始地址

int main()
{int a = 0;     //在内存中开辟一个4字节大小的空间,存放数据0int* p = &a;   //取出变量a的地址,将其所占4字节的第一个字节存放至p中
}

二、指针的大小

不同机器上的指针大小不同,在32位机器上,指针大小为4字节;在64位机器上,指针大小为8字节。

前文中提到每个内存单元都有其对应的地址,对于32位机器来说,可以假设有32根地址线,在寻找内存单元的地址时,每根地址线产生高电压或低电压(对应二进制中1或0)

那么这32根地址线总计可以产生2^32个地址(全0到全1),以此对内存单元进行访问,而由于每个内存单元是1字节大小,所以其理论上其可访问4G的内存(实际是不可能的),这就是为什么32位系统至多支持4G内存的原因。

也就是说,在32位机器,地址是由32个0或1组成的二进制序列,1bit存储1个二进制数,所以需要32bit也就是4字节的空间来存放某一地址,因此32位机器上的指针大小为4字节。

同理,也就能说明64位机器上的指针是8字节。

三、指针类型

1、指针的类型

不同变量有不同的类型,如浮点型,整型,字符型等,与之相对,指针也具有不同的类型,但是无论何种类型的指针大小都是4或8字节

指针的定义方式是 type+*,(其中*的位置与type相邻还是与变量名相邻取决于个人喜好)

如以下三种,其中NULL是空指针,表示 "未分配" 或者 "尚未指向任何地方" 的指针

char* pc = NULL;

int* pi = NULL;

double* pd = NULL;

一般来说,type*与其所对应的变量类型相同,整型变量就是int*,浮点型变量就是float*或double*

2、不同指针类型的作用

步长

指针可以加或减一个整数,表示从其标识的地址向高地址或低地址移动多少步长,步长的大小取决于指针类型,如

//以下代码仅为说明指针步长,没有实际意义
int a = 0;
char ch = 'm';
int* pi = &a;
char* pc = &ch;
pi += 1;     //此时pi会从a的起始地址向高地址走4字节
pc += 1;     //此时pc会从ch的起始地址向高地址走1字节

整形指针一个步长是4字节,字符型指针一个步长是1字节,指针的步长与其所对应变量占内存空间大小一致。

解引用

指针的类型决定指针解引用时可以操作几个字节,字节数仍与其所对应变量所占内存空间大小一致,如char*的指针解引用可以操作1个字节,int*的指针解引用可以操作4个字节。可以通过调试观察,如下图

也就是说,当对一个指针解引用时,指针会对其标识的起始地址开始,一个步长的字节数中的内容进行修改。

三、野指针

野指针

野指针是说,指针的指向不可知,不知道其标识的地址或指向地址不正确

野指针成因

一般情况下会因为指针未初始化、指针越界访问、指针指向的空间释放,三种原因导致出现野指针

1、指针未初始化

这一点不同于一般变量,编译器不会为局部变量的指针赋值(指针作全局变量时一般会被赋值为空,即NULL),所以用户必须对局部变量指针初始化,在用户也不确定其指向时,可以赋值为NULL,即空指针

2、指针越界访问

#include <stdio.h>
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0; }

3、指针指向内存空间释放

free函数不会将指针置空,若此时仍以此指针进行操作,就是非法行为(空指针也不可以进行解引用操作,只是一般对空指针解引用会直接报错,但是非法访问不一定报错)

#include<stdlib.h>int main()
{//开辟一个可容纳4个整形大小的空间int* p = (int*)malloc(sizeof(int)*4);free(p); //系统收回用户开辟的空间*p = 0;  //非法行为,空间不属于用户,原则上不可修改
}

还有一种是函数返回局部变量的地址,由于局部变量已经销毁,指针就会成为野指针

#include<stdio.h>int* function()
{int a = 0;int* p = &a;return p;
}int main()
{int* ptr = function();*ptr = 0; //此时a变量已经销毁,系统收回其空间,原则上不可修改}

如何规避野指针

1、指针初始化

2、处理好边界条件,防止指针越界

3、free之后将指针置空

4、不能返回局部变量的地址

5、指针使用前检查有效性(是否为空,指向内存是否有效)

四、指针运算

1、指针+-整数,这一点在前文已经提及

2、指针-指针

这一运算必须保证二者是同一类型的指针,得到的结果是二者间相差的字节数除以步长,这个数字可正可负,也可能是0(指向同一地址),一般用于获取两个指针间的元素个数

//如求字符串长度时可用如下方法
int my_strlen(char *s)
{char *p = s;while(*p != '\0' )p++;return p-s;
}

3、指针的关系运算

这一点与一般变量的关系运算相同,地址也有高地址和低地址,可以判断相等,比较大小等

C语言指针详解(初级)相关推荐

  1. C语言指针详解(全解)—— 前篇

    关于指针的基本概念及相关运算写在了上一篇博客 C语言指针详解(初级)_Seinrich的博客-CSDN博客 本篇博客来详细的解说一下指针,深入探讨指针 一.指针与const const修饰的变量为常变 ...

  2. c语言的指针详解ppt,最全的C语言指针详解.ppt

    最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...

  3. C语言指针详解——入门C语言指针,初级指针使用。

    原文地址:我的个人博客点击查看 C语言教程第二弹--指针详解 所有学过C语言的人都知道,C语言难在它的指针的使用和理解,今天,我带给大家C语言的指针的教程,供大家学习交流,如果有讲的不对的地方,请给作 ...

  4. c语言 指针函数 详解,[NOTE-C]C语言指针详解(一)

    C语言指针让一切想法变成可能,强转和指针可以看做一项呼风唤雨的利器,但是C语言中指针应用又需要格外的小心,其更灵活的利用内存,因为不当的应用可能引起各种异常,这篇文章就是让我们一起来认识C指针,更好的 ...

  5. c语言 指针_C 语言指针详解

    (给CPP开发者加星标,提升C/C++技能) 作者:C语言与CPP编程 / 自成一派123(本文来自作者投稿) 1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直 ...

  6. c语言高低位拷贝_C语言指针详解

    1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直接调用变量 a ,还可以定义 char *p=&a ,调用 a 的地址,即指向 a 的指针 p ,变量 ...

  7. 导航编程用c语言还是c加加,C语言/C加加大神程序员老司机带你玩转C语言指针详解...

    很多初学编程的小伙伴都会选择C语言作为第一门学习的编程语言,因为C语言作为一门底层基础语言相对于其他的高层语言来说更加容易学习.可以来帮助正在学习编程的小伙伴更加快速的了解计算机原理. 但是初学C语言 ...

  8. C语言指针详解(新手入门推荐)

    目录 指针的理解 字符指针:char * 无类型指针void * 指针数组 数组指针 函数指针 回调函数 函数指针数组 练习 指针和数组笔试题解析 指针的理解 关于指针,我先讲一个故事:一个侦探在案发 ...

  9. C语言指针详解——后篇

    目录 一.指针与数组 ​编辑 二.数组传参 2.1一维数组传参 2.2二维数组传参 三.函数指针及应用 四.函数指针数组 一.指针与数组 先来看以下代码及运行的结果 #include <stdi ...

最新文章

  1. android button 添加事件_2019最新Android常用开源库总结
  2. 单例模式——创建型模式
  3. 每个即将成为或想成为网络工程师最想看的文章
  4. 操作系统习题7—文件系统
  5. 华容道游戏开发--android小组
  6. javascript立即调用的函数表达式
  7. JS-for的衍生对象
  8. linux内核端口绑定,linux 多网卡bonding 绑定 端口聚合
  9. python组合和继承_Python基础系列讲解——继承派生和组合的概念剖析
  10. python_day24_class_类_继承
  11. linux 三维数据绘图软件,Linux下开发基于.NET的三维绘图程序
  12. 不读取nan行_一个参数一个Excel表,让你玩转Pandas中read_excel()表格读取!
  13. 解析几何 直线与平面 直线与平面(1.2)
  14. 债券属性「久期」的本质是什么?
  15. WiFi精灵:开启手机免费上网时代
  16. CodeWarrior IDE烧写介绍
  17. 《数字图像处理》题库3:判断题
  18. 零售航母沃尔玛公布业绩:喜忧参半
  19. 按键精灵---插件关于窗口的各种操作
  20. 小志志和小峰峰的日常(SG函数)

热门文章

  1. Android9.0检测摄像头是否存在源码完整案例
  2. java读取文件夹下所有文件并替换文件每一行中指定的字符串
  3. SQL SERVER 连乘写法
  4. 案例21:Java农产品供求信息系统设计与实现开题报告
  5. 028. 考古学家[200 分]
  6. 正则看这三个网站就够了
  7. WIX插件安装包的生成(三) 批量导入文件
  8. 关于声卡驱动安装问题 ghost版本的危害
  9. C语言之找数组中重复的数
  10. 互联网产业中“外行领到内行”和软件工程