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,一经查实,立即删除!

相关文章

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

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

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

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

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

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

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&…

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;这种区域也就是常说的“扣岛”。常见的有基…

垃圾收集器准则和提示

这些是我需要调整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…

移动前端—H5实现图片先压缩再上传

在做移动端图片上传的时候&#xff0c;用户传的都是手机本地图片&#xff0c;而本地图片一般都相对比较大&#xff0c;拿iphone6来说&#xff0c;平时拍很多图片都是一两M的&#xff0c;如果直接这样上传&#xff0c;那图片就太大了&#xff0c;如果用户用的是移动流量&#xf…

requests模块

python requests用法总结 本文全部来源于官方文档 http://docs.python-requests.org/en/master/ 1、安装 Requests 是一个第三方 Python 模块&#xff0c;其官网的介绍如下&#xff1a; Requests 唯一的一个非转基因的 Python HTTP 库&#xff0c;人类可以安全享用。 警告&…

linux子系统备份,使用LxRunOffline工具备份/还原Linux子系统(WSL)

安装WSL开启WSL组件首先需要打开WSL组件&#xff0c;可以使用以下命令&#xff1a;Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux也可以手动在【控制面板】-【程序】-【启用或关闭Windows功能】-【适用于Linux的Windows子系统】打勾&…

react打包后图片丢失_手搭一个 React,Typescript,Koa,GraphQL 环境

本文系原创&#xff0c;转载请附带作者信息&#xff1a;yhlben项目地址&#xff1a;https://github.com/yhlben/cdfang-spider前言在实际的开发过程中&#xff0c;从零开始初始化一个项目往往很麻烦&#xff0c;所以各种各样的脚手架工具应运而生。crea-react-app&#xff0c;v…

无需改动现有网络,企业高速远程访问内网Linux服务器

某企业为数据治理工具盒厂商&#xff0c;帮助客户摆脱数据问题困扰、轻松使用数据&#xff0c;使得客户可以把更多精力投入至数据应用及业务赋能&#xff0c;让数据充分发挥其作为生产要素的作用。 目前&#xff0c;该企业在北京、南京、西安、武汉等地均设有产研中心&#xff…

使用Hazelcast发布和订阅

几周前&#xff0c;我写了一篇有关Hazelcast入门的博客&#xff0c;描述了创建分布式地图&#xff0c;列表和队列是多么简单。 当时我提到Hazelcast还能做很多其他事情。 该博客快速浏览了Hazelcast的另一个功能&#xff1a;基于Publish / Subscribe模式的广播消息系统。 这采用…

接口自动化测试持续集成--Soapui接口功能测试参数化

按照自动化测试分层实现的原理&#xff0c;每一层的脚本实现都要进行参数化&#xff0c;自动化的目标就是要实现脚本代码与测试数据分离。当测试数据进行调整的时候不会对脚本的实现带来震荡&#xff0c;从而提高脚本的稳定性与灵活度&#xff0c;降低脚本的维护成本。Soapui最…

Codeforces 1027E Inverse Coloring 【DP】

Codeforces 1027E Inverse Coloring 题目链接 1 #include<bits/stdc.h>2 using namespace std;3 #define N 10104 #define LL long long5 #define Mod 9982443536 int n,k;7 LL dp[N][N],ans0;8 LL sum[N][N];9 int main(){ 10 cin>>n>>k; 11 dp[0][…

合并远程仓库到本地_git远程仓库创建和合并

上周发了一个张佳波小朋友关于git的文章&#xff0c;马上就更多小朋友的回馈。其中周玉涛同志发来了自己对于git之前问题的一些理解和解决方法&#xff0c;希望能帮助更多人解决问题。为了保证周玉涛同学提供材料的完整性&#xff0c;以下将他原文和图片发出&#xff0c;不做其…

swfobject.js视频播放插件

在网页中经常会用到视频播放的功能&#xff0c;下面介绍一下swfobject.js的视频播放应用&#xff1a;html代码结构&#xff1a; <div id"video_content"></div> css样式结构&#xff1a; body{background: #003368}#video_content{width:600px;height:40…

Spring REST:异常处理卷。 3

这是该系列中有关Spring REST异常处理的最后一篇文章。 最后&#xff0c;这次我将讨论在表单处理期间可能发生的REST异常的处理。 因此&#xff0c;在本教程中&#xff0c;您将看到与REST&#xff0c;表单和异常处理有关的所有内容。 客户端呢&#xff1f; jQuery将用于反映RES…