讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

AniShort
AniShort

AI短剧协同制作平台

Seko
Seko

AI短剧一键生成成片

updream

一键生成高质量推广成片

深入理解并打败C语言难关之一————指针(1)

冬晨同学_2039

冬晨同学_2039

发布时间:2025-04-26 14:42:34

|

333人浏览过

|

来源于php中文网

原创

前言:

已经好久没有写文章,最近的生活比较忙,我到现在为止已经学完了C语言的大部分内容了,所以我决定每天出一篇文章来复习我学过的知识,今天先来讲指针的相关知识,行了我也不多废话了,现在开始进入正文

深入理解并打败C语言难关之一————指针(1)

正文:

1.内存与地址

1.1内存

立即学习“C语言免费学习笔记(深入)”;

 我们可以引入一个案例来解释一下内存是什么:假如你有一个朋友叫做小明,有一天你住进了一个酒店,你想要邀请小明来酒店来找你玩耍,如果你不告诉小明你的房牌号的话,他只能从一楼开始一个房间一个房间的来找你,这样会显的很麻烦,如果你直接告诉他你的门牌号的话,他会直接找到你人在哪里。我们把这个故事的内容类比到计算机当中去,这个酒店我们称之为一个内存,酒店里有很多的房间,我们把一个房间称之为一个内存单元,每一个内粗单元都有一个相对应的编号,我们把内存单元的编号称之为地址,地址也叫做指针,所以,内存单元的编号 == 地址 == 指针,所以这就是指针的实际意义,他就是一个地址。

1.2.如何理解编址(这部分内容其实我也不太明白,所以我从网上找点资料来进行完善了)

深入理解并打败C语言难关之一————指针(1)

  将这个之前我先从这放一张图来更好的理解编址,CPU访问内存的某个字节空间的时候,必须要知道这个字节空间在内存的什么位置,并且因为内存中字节很多,所以需要给内存进行址(就比如酒店的房间很多,需要给房间编号一样),计算机中的编址,并不是把每一个字节的地址记录下来,而是通过硬件设计完成的。钢琴,吉他上面没有写到“剁、来、咪、发、唆、拉、西”这样的信息,但演奏者照常能够精确知道。本质上是一种约定出来的共识

⾸先,必须理解,计算机内是有很多的硬件单 元,而硬件单元是要互相协同⼯作的。所谓的协 同,至少相互之间要能够进行数据传递。但是硬件与硬件之间是互相独⽴的,那么如何通信呢?答案很简单,用"线"连起来。不过,我们这节课关心的线是地址总线:硬件编址也是如此 我们可以简单理解,32位机器有32根地址总线, 每根线只有两态,表示0,1【电脉冲有⽆】,那么 ⼀根线,就能表示2种含义,2根线就能表⽰4种含 义,依次类推。32根地址线,就能表⽰2^32种含义,每⼀种含义都代表⼀个地址。 地址信息被下达给内存,在内存上,就可以找到 该地址对应的数据,将数据在通过数据总线传传入 CPU内寄存器。

2.指针变量和地址以及指针变量类型的意义

2.1取地址操作符(&)

  对于如何知道内存,取地址操作符可以找到变量什么的所在的地址,下面直接进行演示,对于取到地址的演示  (对了地址的占位符是%p)

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>int main(){   int a = 12;   printf("%p",&a);   //注意地址的占位符是%p   return 0}
深入理解并打败C语言难关之一————指针(1)

  其实我们每次申请变量的时候就申请了一部分的内存空间,通过前面的了解可以知道 ,每个内存单元都有着编号,所以变量是有地址的,并且因为int是有四个字节空间的,所以每个字节空间对应着一个地址,而取出来的地址其实是最小的地址,不过我们已经知道最小的地址了,顺藤摸瓜就可以找到其余字节的地址了。

2.2指针变量和解引用操作符(*)

  2.2.1指针变量

  通过取地址操作符可以取到任意变量的地址,这些地址是需要存储起来的从而为了后期的使用,我们在初始化一个变量时,会把一个数存在这个变量里,由此可以类推,我们可以把存放指针的变量称之为指针变量,下面是如何进行创建:

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>int main(){    int a = 12;    int *p = &a;   //这就是指针变量如何进行创建}

对于指针变量,我们可以这样进行理解:以上面的式子举例,p是指针变量的名字,*指的是定义的是指针变量,int指的是地址所对应的类型,这个要记住,以后会有着很多指针类型等着我们去记。

2.2.2解引用操作符(*)

可能很多人会有疑问,我们把一个变量取出地址了并且放在了指针变量里面了,我们未来想要使用这个数的时候要怎么用呢,其实,在C语言中,我们是可以通过地址来改变变量的数的,具体的用法我写在了下面,毕竟取出了地址啥也不可以干那还不如不多废这功夫 

代码语言:javascript代码运行次数:0运行复制
#include<stdio.h>int main(){    int a = 12;    int * p = &a;    *p = 13;    return 0;}

  这样可以把a数值里面的值进行改正 ,* 变量名  =  你想要的值,这就是如何进行解引用操作,可能很多人会想,如果想要把变量的值进行改变,直接 a = 13 不就好了,理论上这么干是没有问题的,但是我们在这可以比喻一下子,我相信各位都接触过《狂飙》这一部胡=剧,在这里面,高启强每一次想杀人的时候都不是靠自己出手,我们可以把它比做成变量,他一般会对老默说:老默,我想吃鱼了,把这种肮脏活交给老莫去做,我们在这里可以把老莫比做成指针变量,很多事情不用老大(变量)去干,让小弟(指针变量)操作就好了。

2.3指针变量的大小

可能会多人会想指针变量的大小会和变量大小是相关联的,对于所以我们先卖个关子,先展示对各个变量地址的打印

深入理解并打败C语言难关之一————指针(1)
深入理解并打败C语言难关之一————指针(1)

  不难看出,这几个变量的地址居然是一样的,很多人对此疑惑了,为什么地址大小是一摸一样的,我也不卖关子了,我直接告诉原因,指针变量的地址和所在的运行环境有关,就比如我这个是x64的运行环境,所以有64个比特位,换算下来刚好是8个字节的长度,所以一共占8个字节,对于原因我也不解释了(这个其实是我直接记下来的,与上面的编址有关)。

2.4.指针的类型

AI舌诊面诊问诊医疗系统+诊疗商城系统源码
AI舌诊面诊问诊医疗系统+诊疗商城系统源码

AI 舌诊面诊问诊医疗系统 + 诊疗商城系统源码是一套结合 AI 辅助诊断与商品转化的健康类程序,基于浩创云、ThinkPHP(PHP)开发,支持微信服务号与 H5 端,适合做中医舌诊面诊问答、健康建议推送以及配套诊疗商品的运营。

下载

指针有很多的类型,他的类型和对于的常量是息息相关的,比如上面的int * ,除了这个,还有char * , float * , double *等等,这一些都是根据所对应地址的类型所决定的

2.5.void*指针

这个指针在后期会有重大的作用,在指针类型中有⼀种特殊的类型是 void * 类型的,可以理解为⽆具体类型的指针(或者叫泛型指 针),这种类型的指针可以⽤来接受任意类型地址。但是也有局限性, void* 类型的指针不能直接进行指针的+-整数和解引用的运算。对于它,后面模拟某类函数的时候会出现的

3.const来修饰指针

3.1const修饰常量

我直接明了了,被const修饰的常量,是不能在改变它的数值的,对于例子,可以看见下面的例子, 

深入理解并打败C语言难关之一————指针(1)

  这个红线代表着,a是不可以被修改的,因为它已经被const修饰,const是代表着语法进行了限制,简单来说就是不可以被修改,不过我们可以绕过它来进行修改,这时候指针的功能就来了,如下图所示

深入理解并打败C语言难关之一————指针(1)

  就拿我上面《狂飙》的例子一样,大哥不好动手,那么小弟动手就好了,这样的会造成一定的风险,就比如我们就是不想让变量的内容改变,但是这么做的话就会有风险,所以我们更是要对指针进行const的处理,那么现在进入下一节:

3.2.const修饰指针

3.2.1const在(类型)* 的左侧

对于指针使用const要分成两种情况进行讨论,先来讲述下左侧的情况,不废话直接说功能:const在(类型)*的左侧的话,会让解引用指针变量的时候,不能在解引用了(这是用大白话来讲),如果采用官方话来说:const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。 但是指针变量本⾝的内容可变,通过这一段的介绍可以看出,const在左边可以阻止改变内容去,但不能组织地址的改变,下面将会讲述如何限制地址的改变

3.2.2const在(类型) * 的右侧

const在(类型) * 的右侧的话,会让其在改变所指向地址的时候,无法进行改变(这是通过大白话进行讲述),如果用严肃的口气说的话:const如果放在*的右边,修饰的是指针变量本⾝,保证了指针变量的内容不能修改,但是指针指 向的内容,可以通过指针改变。所以从这里就可以看出二者的不同,所以如果合理使用const的话,可以避免很多意外情况的诞生

4.指针进行的运算

4.1 指针+-整数

这一个可以通过数组的案例进行解释,因为数组在内存中是连续存放的,所以只要知道一个元素的地址,就可以找到后面的,不过再说这个之前,先来讲一下这个的逻辑,对于指针+-整数,其实说白了就是类似+1的时候会多加一个类型(此类型指的是指针的类型)的地址,就比如int * 如果+1的话,会多加4个字节的地址,类似这样,下面我们直接进入对于数组如何通过地址打印对应元素:

深入理解并打败C语言难关之一————指针(1)
深入理解并打败C语言难关之一————指针(1)

  通过控制台的数据可以看出二者是完全一样的,对于上面式子的解释,可以这么认为 ,在上面的式子,p代表着数组第一个元素的地址(小小的剧透下,数组名也是数组中第一个元素的地址),在printf的引用中,p + i代表着arr[i]所在的地址,解引用后便就是arr[i]这个具体的数了,所以可以通过这个特性来对于数组进行打印(当然不能仅仅这么肤浅这个用法),对于更高级的请关注我后续的文章(不是我卖关子,很多内容后期学完了才可以听懂)

4.2指减指针

指针减指针的结果是指针与指针之间元素的个数,当然,这个计算是由前提的,它的前提是两个指针指向的是同一个空间,不然二者就没意义了,下面来展示它的用法,这里可以采用对于srlen函数的模拟来实现,我们知道,strlen函数统计的是\0之前的字符个数,通过它可以看出指针减指针的妙用:

深入理解并打败C语言难关之一————指针(1)
深入理解并打败C语言难关之一————指针(1)

  可以看出两者的数值是一样的,从这里可以看出指针减去指针的时候记录的数是两个指针相差的元素个数,因为p代表指针最后所在的位置,它减去刚开始的位置代表着二者相差的字节个数,所以从这里可以看出指针-指针带来的效果,以后这个也会多讲,对于很多函数的模拟会用到这个。

4.3指针之间的运算关系

他们之间的大小关系会是通过地址的大小来确定的,把它类比成变量之间比大小就好,指针和指针之间的运算关系和这个是一样的,可以通过例子来看看怎么比较(这部分没啥好讲的)

代码语言:javascript代码运行次数:0运行复制
#include <stdio.h>int main(){ int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &arr[0]; int sz = sizeof(arr)/sizeof(arr[0]); while(p<arr+sz) //指针的⼤⼩⽐较 { printf("%d ", *p); p++; } return 0; }

结尾:

今天本来想着写很多大,但是今天2晚上聚餐导致脑子有点昏,所以这篇文章就先写到这里了,预告一下,下一篇 将会讲到野指针,assert断言等重要知识,如果文章出现了错误,恳请您在评论区指出,希望大家多多点赞,我们下一篇见!                                                         

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

7667

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

904

2025.10.23

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6384

2023.10.24

printf用法大全
printf用法大全

php中文网为大家提供printf用法大全,以及其他printf函数的相关文章、相关下载资源以及各种相关课程,供大家免费下载体验。

948

2023.06.20

fprintf和printf的区别
fprintf和printf的区别

fprintf和printf的区别在于输出的目标不同,printf输出到标准输出流,而fprintf输出到指定的文件流。根据需要选择合适的函数来进行输出操作。更多关于fprintf和printf的相关文章详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1029

2023.11.28

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2458

2023.09.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

7479

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3545

2024.08.29

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Docker Compose使用手册
Docker Compose使用手册

共0课时 | 0人学习

Docker官方入门手册
Docker官方入门手册

共0课时 | 0人学习

Revel 官方开发手册
Revel 官方开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn