c语言 指针_C语言——指针

6203fdfcdfbda19327a4835a170db6b4.png

学习阶段:高中信竞、大学编程。

前置知识:二进制与十六进制,C语言基础,数组。

指针初学可能比较难理解,我这篇文章尽量用通俗易懂的方式来讲解。

1. 指针概述

为什么有指针这个东西?因为指针很贴近计算机内部的实际工作原理,与内存实际的寻址方式类似。C语言可以说是高级语言中最贴近机器的语言,而像Python、JavaScript这种更亲和于人类的语言与机器的关系则比较远了,甚至它们本身可能还是用C语言写出来的呢。

指针可以形象地比喻为在内存中定位的导航员。内存那么大,怎么知道我需要的东西存在哪里呢?可以让指针来记录与导航。我们先来了解一下内存。

2. 预备知识

2.1 内存

研究过组装机、电脑配件的话,一定知道内存条这个东西。现在这个时代,一台家用电脑的内存一般是2GB、4GB、8GB、16GB、32GB、64GB等等。

把CPU比作干活的人,则内存就相当于工作台。CPU在跑的程序以及很多相关数据都存在内存内,这就相当于人在干活时要把相关资料放在工作台上使用。

内存可以看成是一个巨大的数组,我这里记为

memory[0..n]

memory的每一个单元存1B=8bit,memory[0]就是内存的第一个单元。这个中括号里面的数,即数组下标,被称为内存地址,简称为地址。我确定了一个地址,也就相当于确定了内存中的一个单元。

通常,我们说的32位机器,意思就是地址是32bit的,最大支持的内存是

memory[0x00000000..0xFFFFFFFF]

最小地址是0,最大地址是0xFFFFFFFF=2^32-1,最大支持

也就是说32位机器理论上最大支持4GB的内存,这就是它逐渐被淘汰的原因。

而64位机器理论上最大支持的内存是

这个量级远大于目前的需求,因此128位机器在相当长的时间内不会出现。

2.2 变量与数据类型

C语言有很多数据类型,不同的数据类型在内存中的占用空间存储格式也不一样。不同数据类型的存储格式比较复杂,这里不详述。我只谈谈不同的占用空间。

一个变量在内存中占用都是连续空间,记T类型的变量在内存中占用sizeof(T)字节的空间。当我声明一个T类型的变量a时,内存会寻找连续且可用的sizeof(T)个单元,把它们分配给变量a,比如说是memory[100..103]这4B的空间。此后我对变量a进行读写,也就相当于对memory[100..103]这4B的空间进行读写。

某些数据类型的占用空间:short短整形占用2B,int整形占用4B;float浮点形占用4B,double双浮点型占用8B;char字符型占用1B.

3. 指针

指针是一种特殊的数据类型,指针类型的变量应存储的是内存地址。在32位机器上,任何一个内存地址都是32bit=4B,故任何一个指针型变量都占用4B.

现在问题来了,指针指向内存中的一个单元,我怎么知道这个单元里面存的是什么东西,是什么类型的数据?因此,在声明指针变量的时候,也要声明这个指针指向数据的类型,比如int型指针、char型指针等。

3.1 指针的声明

在语法上,声明指针类型使用*符号,例如

int *a, b, *c; //a和c是指针,b不是指针
char *ch;

这两句代码声明了int*型的变量acint型变量b以及char*型变量ch. 根据语法,我们习惯上称T型指针为T*型,含义就是T*型变量是指针,其所指的相关内存单元存的是T型数据。 (注意,这里的b变量不是指针,仅仅为普通的int整形。)

3.2 指针的使用

指针有很多种使用方式,包括动态申请内存、函数地址传参等等。我这里仅介绍最简单的使用方式。我提供一份例程,可直接从例程中学习指针的声明与使用。

例程:

int x=1, y=2; //声明x与y并赋初值
int *p=&x; //声明p且p指向x
*p=11; //p修改x
p=&y; //p指向y
*p=12; //p修改y
printf("x=%d, y=%d", x, y); //打印x与y

第一行,在内存中申请连续的4B区域存入int型数据1,记为变量x;再在内存中申请连续的4B区域存入int型数据2,记为变量y. 假设x对应内存区域memory[100..103]y对应内存区域memory[200..203]. 第一行执行完毕,内存如图1所示:

70914f530c286c08a31bb7d6600a69f4.png
图1 第一行执行完毕

第二行, 在内存中申请连续的4B区域存入int*型地址数据100,记为变量p. 这里&符号是取地址运算符,表示取变量x的首地址,在本例中就是100. 这一行代码是声明指针同时赋初值,相当于以下两行代码:

int *p;
p=&x;

第二行执行完毕,内存如图2所示(100的十六进制是0x64):

6e5903c2529a953edcf9be500a19dc74.png
图2 第二行执行完毕

第三行,将p所指的地址起4B空间内存入int型数据11. 这里*解地址运算符, 表示取得指针所指的内存空间。 第三行执行完毕,内存如图3所示:

a7da7fead77b593ebc235d6be6902541.png
图3 第三行执行完毕

如果第三行改为执行p=(int*)11;,则是先把int型数据11强制转换为int*型数据11,然后赋值给p,如图3.2所示:

3259a4327f33ce4a040c8093c4cf1b4c.png
图3.2 第三行改为执行p=(int*)11;

此时p所指的内存空间不一定是可用的。因此像这样直接给指针赋值一个常数的情况非常罕见。

第四行,py的首地址。第四行执行完毕,内存如图4所示:

146a2393887ff53e50e17f148bd537b4.png
图4 第四行执行完毕

第五行,把变量y的值改为12. 第五行执行完毕,内存如图5所示:

308089d9562ccf14c308f46ee9c3566f.png
图5 第五行执行完毕

第六行,打印xy的值,打印结果应为:

x=11, y=12

4. 多级指针

指针也可以指向指针,称为多级指针。

例程:

int x=1;
int *p=&x;
int **p2=&p;

这里p2就是一个二级指针,它的类型是int**,它也存了一个地址,但是这个地址是某个int*型变量的地址,在这里是存了int*型变量p的地址。

假设x的首地址是0x10,p的首地址是0x20,那么内存的情况如图6所示:

f0f1e1e6d9e5a8dc35614e92ad5af54f.png
图6 多级指针示例

三级、四级等等更多级的指针也是存在的,但是几乎不会用到。二级指针一般只在二维数组中会用到,其他情况也很少见。尽量不要使用多级指针,不然真的容易弄晕自己。

5. 答疑

5.1 星号*的不同作用

在指针声明、数据类型中,*表示是指针类型;在已声明变量前面的*是解地址运算符,比如说*p就是用p的内容求得其所指的区域;当然,*还有算数乘法等含义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/366082.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

将jOOQ与Spring结合使用:配置

我遇到了由ORM引起的性能问题。 尽管我不得不承认大多数这些问题确实是由您造成的,但是我开始认为在只读操作中使用ORM是不值得的。 我开始寻找实现这些操作的替代方法。 这就是我遇到jOOQ的方式 ,它指出: jOOQ从您的数据库生成Java代码&a…

FFT实现高精度乘法

你应该知道$FFT$是用来处理多项式乘法的吧。 那么高精度乘法和多项式乘法有什么关系呢? 观察这样一个$20$位高精度整数$11111111111111111111$ 我们可以把它处理成这样的形式:$\sum_{i0}^{19}1\times10^i$ 这样就变成了一个多项式了! 直接上代…

oracle精确匹配时间,Oracle时间精确到时、分、秒处理方法

Oracle时间精确到时、分、秒处理方法一般数据库中时间的格式为DATE类型,而我们从页面中获取的时间往往为String类型,这个就需要类型的转换。一般我们会通过调用 Java.text.SimpleDateFormat JAVA类来对其进行转换。这个JAVA类中我们经常用到的方法有两个…

BZOJ 2141 排队(分块+树状数组)

题意 第一行为一个正整数n,表示小朋友的数量;第二行包含n个由空格分隔的正整数h1,h2,…,hn,依次表示初始队列中小朋友的身高;第三行为一个正整数m,表示交换操作的次数;以下m行每行包含两个正整数ai和bi&…

骆驼路线的主/从故障转移

一种实现主/从故障转移模式的方法是拥有一个应用程序实例的集群,其中一个实例(主实例)当前处于活动状态,而其他实例(从属实例)处于待机状态,随时可以在主实例发生故障时接管。 一些项目提供了开…

vant input框禁止调用手机键盘_【案例分享】适应网银等密码键盘的解决方案

在各种技术不断进步的大趋势下,对业务造成了极大影响,从大数据到云计算,再到人工智能,众多企业都开始步入技术改革,从而实现企业的创新。但与此同时,更多技术的引用,意味着更多的业务系统上线&a…

JS无法获取display为none的隐藏元素的宽度和高度的解决方案

在实际开发中会遇到确实需要获取隐藏元素的宽高,这儿所说的隐藏元素是display为none的元素。 可使用jQuery Actual Plugin插件来完成,其源码如下: ;( function ( $ ){$.fn.addBack $.fn.addBack || $.fn.andSelf;$.fn.extend({actual : fun…

删除kafka topic

1、因为项目原因,kakfa通道中经常造成数据阻塞,导致kafka通道中数据量过大,因此我需要将kakfa通道中数据清除(个人项目原因,一直使用一个消费者,只要保证当前消费者不在消费之前很久的数据就可以。因数量过…

启动oracle数据库工具,Oracle数据库常用工具

SQL*Plus:SQL*Plus 是Oracle 数据库的一个基本工具,它允许用户使用SQL 命令交互式的访问数据库,也允许用户使用SQL*Plus 命令格式化输出参数。 通过SQL*Plus ,可以完成数据库的启动和停止、创建和运行查询、更新数据、格式化输出数据报表、运…

可持久化并查集小结

https://www.zybuluo.com/ysner/note/1253722 定义 允许恢复历史状态的并查集。 建立 建\(Q\)棵主席树,每个主席树上维护当前状态并查集各个节点的父亲。 (实际上就是并查集和主席树强行捆绑在一起) 操作 每次操作前自动继承上次操作后的状态…

Java 获取linux根目录下的文件夹_Windows支持直接访问Linux子系统文件:你的下一台Linux何必是Linux...

2020年第一波薅当当网羊毛的机会,别错过!晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI 微软,致力于做最好的Linux发行版。今天,安装Windows 10测试版本号19603的用户发现,系统里WSL (Windows中的Linux子系统…

HTML5效果:实现树叶飘落

实现如图所示的东西效果&#xff08;落叶下落&#xff09;&#xff1a; html代码&#xff1a; <!DOCTYPE html><html><head><title>HTML5树叶飘落动画</title><meta charset"utf-8"><meta name"viewport" content&…

Java 8 Friday Goodies:Lambda和XML

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个新的博客系列了…

洛谷2619/bzoj2654 Tree(凸优化+MST)

bzoj的数据是真的水。。 qwq 由于本人还有很多东西不是很理解 qwq 所以这里只写一个正确的做法。 首先&#xff0c;我们会发现&#xff0c;对于你选择白色边的数目&#xff0c;随着数目的上涨&#xff0c;斜率是单调升高的。 那么这时候我们就可以考虑凸优化&#xff0c;也就是…

oracle 创交表,创建交叉报表(oracle)_oracle

创建交叉报表create table t1(goodid number(10) not null,saledate date not null,salesum number(10));要求生成本年度每个月的产品销售状况表m1 m2 m3 ... m12g1g2...gn下面是生成报表的sqlSELECT goodid,SUM(decode(to_char(saledate,mm),01,salesum)) "01"…

cass方格网数据excel_讨论|CASS怎么计算回字型土方? 124

大家好,欢迎来到我的专栏。这是我原创的第124篇CASS应用技术干货文章。希望对你有所帮助&#xff0c;写文不易&#xff0c;请点赞哦!回字型土方工程&#xff0c;就是计算区域内部&#xff0c;有一个或多个不参加计算的区域&#xff0c;这种区域也就是常说的“扣岛”。常见的有基…

ATM购物车程序项目规范(更新到高级版)

ATM购物车程序&#xff08;高级版&#xff09; 之前的低级版本已经删除&#xff0c;现在的内容太多&#xff0c;没时间把内容上传&#xff0c;有时间我会把项目源码奉上&#xff01; 我已经把整个项目源码传到群文件里了&#xff0c;需要的可以加主页qq群号。同时群内也有免费的…

垃圾收集器准则和提示

这些是我需要调整GC时通常会看到的一些准则和技巧。 主要由以下两本书组成&#xff0c;而根据我的经验却很少&#xff1a; Java性能 JBoss AS 5性能调优 希望它们对那里的其他人有用&#xff01; 垃圾收集器 XX:AggressiveOpts将HotSpot内部布尔变量设置为true以启用其他性…

MD5加密处理

MD5 加密后的位数一般为两种&#xff0c;16 位与 32 位。16 位实际上是从 32 位字符串中&#xff0c;取中间的第 9 位到第 24 位的部分 using System; using System.Security.Cryptography; using System.Text;namespace _04MD5加密 {internal class Program{private static vo…

php tp 支付宝 支付,php实现的支付宝网页支付功能示例【基于TP5框架】

本文实例讲述了php实现的支付宝网页支付功能。分享给大家供大家参考&#xff0c;具体如下&#xff1a;1.提交支付请求require_once ./payment/zfb/pagepay/service/AlipayTradeService.php;require_once ./payment/zfb/pagepay/buildermodel/AlipayTradePagePayContentBuilder.…