如何深入掌握C语言指针(详解)
目录
前言
指针是什么
概念
单元大小与编址
指针和指针类型
指针类型
指针+-整数
指针的解引用
野指针
指针未初始化
指针越界访问
指针指向的空间释放
如何规避野指针
指针运算
指针+-整数
指针-指针
指针的关系运算
对于指针比较
指针和数组
二级指针
使用及运算
指针数组
前言
本文主要讲解点
- 指针是什么
- 指针和指针类型
- 野指针
- 指针运算
- 指针和数组
- 二级指针
- 指针数组
指针是什么
概念
- 专业地说:
指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向 (points to)存在电脑存储器中另一个地方的值
由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元
因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址 的内存单元
- 简单地说:
变量在内存中储存时,内存空间是一块一块的,每一块都有独定的编号(就像是门牌号)
而指针是个变量,存放内存单元(指向的对象)的地址(编号/门牌号)
#include <stdio.h>
int main()
{int a = 10; //在内存中开辟一块空间int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。//将a的地址存放在p变量中,p就是一个之指针变量。//int*说明p是一个指针,而p是指针变量,一个指向int型数据的指针return 0;
}
- 总结:
指针就是变量,用来存放地址的变量。(存放在指针中的值都被当成地址处理)
严格区分的话:指针就是地址,而指针变量用来存放地址的变量
单元大小与编址
结论:一个字节给一个对应的地址(计算和权衡后最适合的大小)
- 以32位的电脑为例:
每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0)
- 其所产生的地址:
00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
...
11111111 11111111 11111111 11111111 //共有2的32次方个地址
每个地址标识一个字节
则2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB
那么能够4G的空间进行编址;对于64位也是同理
- 从上述可知:
在32位中,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节
在64位中,64个地址线,则一个指针变量的大小是8个字节(以存放一个地址)
- 总结:
指针是用来存放地址的,地址是唯一标示一块地址空间的
指针的大小在32位平台是4个字节,在64位平台是8个字节
指针和指针类型
指针的定义方式是: type + *
指针类型
char *pc = NULL; //存放char型变量的地址
int *pi = NULL; //存放int型变量的地址
short *ps = NULL; //....
long *pl = NULL; //..
float *pf = NULL; //.
double *pd = NULL;
指针+-整数
int main()
{int n = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc+1);printf("%p\n", pi);printf("%p\n", pi+1);return 0;
}
指针的类型决定了指针向前或者向后走一步有多大(距离)
指针的解引用
int main()
{int n = 0x11223344;char *pc = (char *)&n;int *pi = &n;*pc = 0; //重点在调试的过程中观察内存的变化。*pi = 0; //重点在调试的过程中观察内存的变化。return 0;
}
指针的类型决定对指针解引用有多大的权限(能操作几个字节)
如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节
野指针
野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
指针未初始化
int main()
{int *p;//局部变量指针未初始化,默认为随机值*p = 20;return 0;
}
指针越界访问
int main()
{int arr[10] = {0};int *p = arr;int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;//先使用指针p,使用时进行解引用,对内容进行赋值,再进行++}return 0;
}
指针指向的空间释放
int* test()
{int n=10;int *p=&n;//进入test函数开辟空间return p;//离开时空间释放,n的空间没有了
}int main()
{int *i=p;//即便有地址也找不到对象,便成了野指针printf("%d",*i);//errreturn 0;
}
如何规避野指针
- 指针初始化
- 小心指针越界
- 指针指向空间释放即使置NULL
- 避免返回局部变量的地址
- 指针使用之前检查有效性
指针运算
指针+-整数
上文已经提及,不再赘述
指针-指针
两个指针指向同一个数组中的(可能不同)元素,它们的差就是两个元素之间的元素个数+1
int a[5];
int* p;
int* q;
p = &a[1]; // 第二个元素
q = &a[3]; // 第四个元素
这里 q - p 等于 2 (从 p 指向的元素往后数两个,就是 q 指向的元素)
如果两个指针不是指向同一个数组中的元素,结果是未定义的(the behavior is undefined)
指针的关系运算
- px > py 表示 px 指向的存储地址是否大于 py 指向的地址
- px == py 表示 px 和 py 是否指向同一个存储单元
- px == 0 和 px != 0 表示 px 是否为空指针
对于指针比较
for(vp = &values[N_VALUES]; vp > &values[0];)//用指针从后初始化数组
{*--vp = 0;
}
//优化
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{*vp = 0;
}
- 标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较
但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
指针和数组
之前我们可以通过下标访问数组元素
学习了指针之后,我们可以通过指针访问数组的元素
在数组中,数组名即为该数组的首地址,结合上面指针和整数的加减,可以实现指针访问数组元素
int arr[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = arr;//p存放的是数组首元素的地址
p+i 其实计算的是数组 arr 下标为i的地址
int main()
{int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };int *p = arr; //指针存放数组首元素的地址int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i<sz; i++){printf("%d ", *(p + i));}return 0;
}
二级指针
指针变量也是变量,是变量就有地址
而指针变量的地址存放在二级指针里(指向指针的指针)
int a =100;
int *p1 = &a;
int **p2 = &p1;
C语言不限制指针的级数,每增加一级指针,在定义指针变量时就得增加一个星号
*
使用及运算
- *ppa 通过对ppa中的地址进行解引用,这样找到的是 pa , *ppa 其实访问的就是 pa
int b = 20;
*ppa = &b;//等价于 pa = &b;
- **ppa 先通过 *ppa 找到 pa ,然后对 pa 进行解引用操作: *pa ,那找到的是 a
**ppa = 30;
//等价于*pa = 30;
//等价于a = 30;
指针数组
指针数组是存放指针的数组
int arr1[5];
char arr2[6];
int* arr3[5];
如何深入掌握C语言指针(详解)相关推荐
- c语言的指针详解ppt,最全的C语言指针详解.ppt
最全的C语言指针详解.ppt 第6章 指针,6.1 指针定义与使用 6.2 指针与函数 6.3 指针与数组 6.4 指针与字符串 6.5 指针数组与多级指针 6.6 指针与动态内存分配 6.7 指针的 ...
- C语言指针详解(全解)—— 前篇
关于指针的基本概念及相关运算写在了上一篇博客 C语言指针详解(初级)_Seinrich的博客-CSDN博客 本篇博客来详细的解说一下指针,深入探讨指针 一.指针与const const修饰的变量为常变 ...
- C语言指针详解——入门C语言指针,初级指针使用。
原文地址:我的个人博客点击查看 C语言教程第二弹--指针详解 所有学过C语言的人都知道,C语言难在它的指针的使用和理解,今天,我带给大家C语言的指针的教程,供大家学习交流,如果有讲的不对的地方,请给作 ...
- c语言 指针函数 详解,[NOTE-C]C语言指针详解(一)
C语言指针让一切想法变成可能,强转和指针可以看做一项呼风唤雨的利器,但是C语言中指针应用又需要格外的小心,其更灵活的利用内存,因为不当的应用可能引起各种异常,这篇文章就是让我们一起来认识C指针,更好的 ...
- c语言 指针_C 语言指针详解
(给CPP开发者加星标,提升C/C++技能) 作者:C语言与CPP编程 / 自成一派123(本文来自作者投稿) 1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直 ...
- c语言高低位拷贝_C语言指针详解
1为什么使用指针 假如我们定义了 char a='A' ,当需要使用 'A' 时,除了直接调用变量 a ,还可以定义 char *p=&a ,调用 a 的地址,即指向 a 的指针 p ,变量 ...
- 导航编程用c语言还是c加加,C语言/C加加大神程序员老司机带你玩转C语言指针详解...
很多初学编程的小伙伴都会选择C语言作为第一门学习的编程语言,因为C语言作为一门底层基础语言相对于其他的高层语言来说更加容易学习.可以来帮助正在学习编程的小伙伴更加快速的了解计算机原理. 但是初学C语言 ...
- C语言指针详解(新手入门推荐)
目录 指针的理解 字符指针:char * 无类型指针void * 指针数组 数组指针 函数指针 回调函数 函数指针数组 练习 指针和数组笔试题解析 指针的理解 关于指针,我先讲一个故事:一个侦探在案发 ...
- C语言指针详解——后篇
目录 一.指针与数组 编辑 二.数组传参 2.1一维数组传参 2.2二维数组传参 三.函数指针及应用 四.函数指针数组 一.指针与数组 先来看以下代码及运行的结果 #include <stdi ...
- C语言指针详解----指针声明定义赋值
C语言的指针是让新手很头疼的事情,但是由于其太过于灵活,以至于可以很好得的解决一些复杂的问题,因此不得不掌握.我最近正在学习指针相关的内容,因此在这里做一个小的总结.本篇是不涉及到函数以及结构体等复杂 ...
最新文章
- 如何识别真正的程序员
- 怎样在wp7中检测“主题背景”
- body 没有被撑开_body没有高度设置背景色为什么可以全屏显示?
- html编程入门指南,给萌新HTML5 入门指南
- 大数——大数阶乘(hdu1042)
- 教你如何使用FusionInsight SqoopShell
- JavaScript在HTML中的基础用法总结
- Verilog实现UART串口收发器数字电路
- linux cc脚本,Linux运维知识之Linux简单处理CC攻击shell脚本
- 江民科技召开临时董事会 王江民之子接手管理
- Linux内核之队列操作
- 高数————思维导图(上岸必备)(向量代数与几何部分)
- Ubuntu将推桌面美化计划促市场份额提升
- PyWebIO 简单的Sanger截图应用
- 刷题记录:牛客NC23803DongDong认亲戚
- 世界树服务器bug位置,四叶草剧场世界树bug怎么获得 世界树bug神器获取位置图文详解...
- [工具]Snipaste 屏幕截图软件超级利器 - 花3年精心打造的极致截图贴图/编辑/标注工具
- 字节跳动测试岗位面试题
- 化工原理物性参数_化工原理课程设计全套(包括图纸)
- 艺术媒体效果画笔Ps笔刷
热门文章
- Python求两个或三个正整数的最大公约数和最小公倍数
- 做出正确选择 重设精彩人生
- 龙芯(Loongarch64),在Linux虚拟一个龙芯OS体验下
- 总裁导航v2.5.1修复版秒收录网站模板源码指定定时收录导航站
- Aspen Plus教程-孙兰义-例7.1-质量分数求解摩尔回收率
- 基于SpringBoot的分销商城的设计与实现(论文+源码)_kaic
- 计算机JAVA相关说课稿_面向对象程序设计-java说课稿
- 什么叫高内聚、低耦合?
- 利用公网IP访问部署在阿里云服务器的spring boot项目(一)
- 什么叫组网_小米科普:一文看懂路由器上的 Mesh 组网是什么