尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

C语言-指针1(基础,原理,详细)

C语言-指针1(基础,原理,详细)
📅 发布时间:2026/7/22 23:22:47

目录

一,了解内存和地址

二,指针变量

1,指针变量的表示和大小

1,指针变量的创建和使用

2,指针变量的大小:

2,解引用操作符(*)

3,不同指针变量的意义

1,指针解引用

2,指针加减整数

4,特殊指针:void*

5,const修饰指针

1,const修饰的常变量

2,const修饰的指针变量

三,指针运算

1,指针+-整数

2,指针-指针

3,指针的关系运算

四,野指针

1,指针未初始化

2,指针越界访问

3,指针指向的空间释放

4,规避野指针

五,assert断言

六,指针的使用和传址调用

1,模拟实现strlen函数

2,传值调用和传址调用

补充:进制转化

1,任意进制转化为十进制

2,十进制转化为2进制

3,二进制转化为 8进制和16进制


一,了解内存和地址

再引出指针前,我们要先了解一下计算机的内存和地址。

在计算机中内存有8GB/16GB/32GB等等,这些内存被分为一个个的内存单元。(一个内存的大小为:1字节),一个字节就是8个比特位。其中每个内存单元都有一个编号,这个编号就是内存的地址,也是指针。

编号=地址=指针

在VS编译器中有两中环境:一种是X64,表示64位的环境,另一种是X86,表示的是32位的环境。
以X86(32位)的环境为例子:在32位的环境中,内存都为32位的二进制,只不过为了方便表示,转化为16进制进行表示。
细节分析:在电脑中有32根地址线,每根地址线有两种状态,分别是有无电信号脉冲(1/0),这32根地址线就可以产生2^32中情况,对应着二进制地址中每一位。于是就可以产生2^32种地址存储内容(与int的可能取值相同),类似在64位环境下,地址有2^64种取值可能。
补充:在栈上开辟空间是由高地址向低地址开辟,在数组上开辟空间是由低地址向高地址处开辟。

二,指针变量

1,指针变量的表示和大小

1,指针变量的创建和使用

int a = 10;
int* p = &a; //p为指针变量

补充:若a为char类型,则p前面的类型为char*,其他同理

分析://&为取地址操作符 &a就是a在内存中分配的地址,传给了指针变量p.注意:由于使用 int创建了4个字节的空间,而每个字节都用对应的内存编码,这里&a表示四个地址中最小的地址。

//int*为p的类型 *表示p为一个指针变量,int表示p所存地址的对象为一个整型。

2,指针变量的大小:

指针的大小取决于地址的大小

32位平台下地址是32个bit位 (即4个字节 )

64位平台下 地址是64个bit位(即8个字节)

2,解引用操作符(*)

int a = 10;

int* p = &a;

*p =5;

printf("%d\n",a);

执行结果:5

分析:说明*p就是a变量。*p表示p指向的对象。

3,不同指针变量的意义

1,指针解引用

x86(32位)环境下:

在计算机的存储当中有大小端存储模式:

小端:低位字节存放低地址,高位字节存放高地址

大端:高位字节存放低地址,低位字节存放高地址

而VS下的不论是x86还是x64环境都使用的是小端存储模式

11位于高位字节,地址就比较高

由上图可知:

*ps将n的内容全部转化为0,而*pi只将最后一位转化为0,本质上是ps是int*类型的指针变量可以访问4个字节,而pi是char*类型的指针变量,只可以访问1个字节。

2,指针加减整数

由上图可知:由于int类型占4个字节,int*类型+1后直接跳过了4个字节,而char只占1个字节char*类型+1只跳过了 1个字节。

这就是不同指针变量类型带来的差异。指针的类型决定了走一步的大小。

4,特殊指针:void*

void*指针为无具体类型的指针(或者叫做泛用指针),这种地址可以用来接收任意类型的地址。但是也有局限性:void*指针不能进行解引用和指针加减整数。

原因:void没有指定类型,导致在解引用时,无法确定访问的字节数,同理:在进行加减整数时,无法确定跳过的字节数。

作用:void*指针一般使用在函数参数部分,用来接收不同类型数据的地址。

5,const修饰指针

1,const修饰的常变量

上述操作只锁住了a变量,但是没有锁住a变量的地址,要想让a的值彻底不能修改,需要即使让p拿到了地址,也不能修改a的值。如何才能实现此操作呢?

由此我们引入const修饰的指针变量

2,const修饰的指针变量

3种形式:

1,int* const p=&a;

2,int const *p = &a;

3,int const * const p = &a;

注意:p的三个内容

1,p表示a的地址 2,*p表示a的值 3,p还有自己的地址&p

这三种形式表示不同的含义:

总结:在const后面的内容不可改变。

三,指针运算

指针运算有三种分别是:

1,指针+-整数

2,指针-指针

3,指针的关系运算

1,指针+-整数

int a = 10;

int* p = &a;

(type)*p:跳过的sizeof(type)取决于*p前的类型;

p+1:p+1*sizeof(type)

p+n:p+n*sizeof(type)

指针+-整数的运用:

打印数组中的每一个元素:

2,指针-指针

指针+整数= 指针

故:指针-指针=整数

整数为两个指针之间的元素个数,可以为正,也可以为负。

展示:

2,利用指针-指针得到字符串的长度

注意:没有指针+指针的形式:这是一种没有意义的形式

3,指针的关系运算

指针的关系运算就是:比较指针的大小即比较地址的大小

运用:

当p的地址小于arr+sz时,就一直执行。

四,野指针

野指针就是指针指向的位置是不可知的(随机的,不确定的,没有明确限制的)

造成野指针的三种情况:

1,指针未初始化

2,指针越界访问

3,指针指向的空间释放

4,规避野指针

1,指针初始化:如果知道指针明确指向哪里就赋值,如果不知道指针指向哪里就给指针初始化为NULL。

NULL是C语言规定的一个标识符常量,值为0,也就是说地址为零,不可以进行使用。

2,小心数组越界

不能超出数组的访问范围

3,避免返回局部变量的地址

五,assert断言

语法:assert(表达式 )

若表达式的执行结果为1,则继续往下执行,若表达式的 执行结果为0,则终止报错,并显示错误信息:断言失败:表达式,以及在哪个文件下哪一行。

注意:assert断言使用时必须包含头文件#include <assert.h>

使用assert的好处:使用assert不仅可以在出错误时显示出错误的信息,还可以随时对assert断言进行开启和关闭。如果不需要断言时,在#include <assert.h>的前面输入#define NDBUG

运用:

1,判断是否为空指针

2,表达式判断

assert断言失效,如果想要重新开启assert对#define NDEBUG进行注释或删除即可。

assert的唯一缺点是由于引入了assert,会增加程序的运行时间。

注意:assert断言只能在Debug中使用,不能在Release中使用,在Release中会直接失效。

六,指针的使用和传址调用

1,模拟实现strlen函数

分析:strlen的返回值类型是:size_t,表示无符号的整型。(使用int也可以)

通过使用const和assert断言使得代码的健壮性得到了提高。

2,传值调用和传址调用

利用函数实现对两个整数的交换

1,传值调用:

分析:函数执行前后a,b的值并未交换,原因:a和b向函数传入的只是两个数值,x和y接收的也仅仅是两个数。x和y在函数内进行了交换。出函数时销毁(无意义)。a和b并未和x,y建立真正的联系。这种情况称为传值调用。

2,传址调用:

分析:通过传地址的形式,使得a,b和x,y建立了真正的联系。通过对地址内值的修改,实现了交换。

总结:实参传给形参时,形参时实参的一份临时拷贝,对形参的修改不会改变实参。

补充:进制转化

1,任意进制转化为十进制

公式:每一位的数字*该进制^(位数-1次幂) 对此求和

例如:十六进制:ee 转化为10进制数:

15*16^(2-1)+15*16^(1-1)=255

2,十进制转化为2进制

例如:125

3,二进制转化为 8进制和16进制

由于8进制的每一位的范围为0~7,而二进制三位000到111的范围刚好是0~7,于是一个八进制为和三个二进制位进行匹配。

步骤:将二进制从后往前每三个一组进行划分,将每一组的数字按照十进制转化并填写到8进制内

转化为16进制的原理和步骤与上述转化为8进制的步骤异曲同工:

相关新闻

  • AI 模型水印与溯源技术深度解析:从 Kirchenbauer 绿名单到 SynthID 的内容可信认证与知识产权保护体系
  • 【高速缓存】RedisVL管理 LLM 对话消息历史指南
  • OpenSCAD:程序员如何用代码实现3D参数化建模

最新新闻

  • 2026年福州本地西高地选购靠谱线下门店参考汇总指南 - 热点品牌推荐
  • 【上海市】防水补漏五星商家推荐|一级资质**认证 协会推荐质保无忧.doc - 资讯报道
  • 2026 年现阶段,金堂正规的商用虾饼机源头厂家选型指南,别再靠手做!这台设备如何颠覆你的虾饼生产效率? - 行业严选官
  • 2026年青岛门窗市场观察:从艺德派克到德朗驰,两大本土品牌的差异化产品力解析 - Gsydold
  • 非升即走扎心真相:大部分青椒三年没成果直接走人
  • 会计专业学生想转数据分析,可以准备哪些内容?

日新闻

  • 亨得利盐城维修点在哪里?手表维修保养地址指南**公示(2026年7月最新) - 亨得利官方
  • 提升.NET API安全性:Boxed.AspNetCore.Swagger认证授权最佳实践
  • 帝舵佛山**网点地址更新:2026年7月售后热线电话与服务客户指南 - 帝舵中国官方服务中心

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号