C语言中的指针:掌握内存的钥匙

C语言中的指针:掌握内存的钥匙

引言

       C语言是一种结构化编程语言,它提供了对硬件底层的直接访问,其中最强大的特性之一就是指针。指针允许程序员直接操作内存地址,这对于理解程序的内部工作原理以及优化代码性能至关重要。本文将深入探讨C语言中指针的概念、使用方法以及一些高级技巧。

什么是指针

       指针就是内存地址,指针变量是用来存放内存地址的变量。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其声明。

声明形式:

type *pointName;

其中type是指针的基类型,它必须是一个有效的C数据类型,pointName是指针变量的名称。用来声明指针的星号*与乘法中使用的星号是相同的,但是在c语句中,星号是用来指定一个变量是指针。
C语言中的指针
例如:指针简单使用
C语言中的指针
输出结果
在这里插入图片描述

指针与变量

内存区的每一个字节都有一个编号,这就是"地址",如果在程序中定义了一个变量,在对程序进行编译运行时,系统就会给这个变量分配一个内存单元,并确定它的内存地址也就是一串这个地址独有的编号,指针是内存单元的编号,指针变量是存放地址的变量,通常我们会把指针变量称为指针,其实指针与指针变量含义式不一样的。

指针变量赋值

指针变量在使用之前, 一定要先赋值,也就是让指针变量指向一个地址。注意,给指针变量赋值只能式地址,通过"&"符号来获取普通变量的地址。“&” - 取地址运算符,“*” - 指针运算符,或称为间接访问运算符,取地址的值。
例子:
在这里插入图片描述
输出结果:上面代码演示了如何在C语言中使用指针,第一步定义一个整型变量i和一个指向整型变量的指针p。然后将i的值初始化为10,并将p指向i的地址,然后打印出i,和p的内存地址以及i的值和通过指针p访问到的值。
在这里插入图片描述
i = 0x7ffd55fc953c 变量i的存储地址, p = 0x7ffd55fc953c是指针变量p指向的地址,以为代码中把i的地址赋给了p,所以p指向i的存储地址。i=10i赋值10*p = 10 指针变量p指向地址里的值,p指向的是地址0x7ffd55fc953c,而这个地址里存储的值为10,所以*p=10

通过地址取值:*((unsigned char *)p))

在这里插入图片描述
输出结果:((unsigned char *)7c3d726c))代表把 0x7c3d726c 这个值,强制转换成一个无符号字符类型指针,相当于告诉编译器,这是一个地址,强制转换的类型和变量a的数据类型保持一致,因为要通过地址,把变量i的值读出来,最后通过*把这个地址的数据读出来,结果7c3d726c = 10
在这里插入图片描述

通过指针改变某个内存地址里的值

上面说了如何获取内存地址的值,那也可以通过指针改变某个内存地址里面的值。格式: *指针变量 = 数值; 【*p = 20】
在这里插入图片描述
输出结果:
在这里插入图片描述
案例2:输入a和b两个整数,然后按先大后小顺序输出a和b。不交换整型变量的值,而是交换两个指针变量的值。
在这里插入图片描述
分析:输入a=5,b=6,由于a<b,将p1和p2交换,注意的是,a和b的值并未交换,他们仍然保持原值,但是p1和p2的值改变了,p1的值原来为&a,后来变成了&b, p2的值原来为&b后来变成了&a,这样在输出p1和p2的时候,实际上是输出了变量b和a的值,所以先输出6后输出5。
在这里插入图片描述

指针变量作为函数参数

函数的参数不仅可以是整型,浮点型,字符型,还可以是指针类型,它的作用将一个变量的地址传送到另一个函数中。

案例:通过指针类型的数据作为函数的参数,对输入的两个整数按大小顺序输出。【通过指针实现交换两个变量的值】
在这里插入图片描述
案例:输入三个整数a,b,c,要求按由大到小的顺序输出。
在这里插入图片描述

指针与一维数组

一个变量有地址,一个数组包含若干个元素,每个数组元素都在内存中占有存储单元,它们都有相应的地址,指针变量既然可以指向变量,当然也可以指向数组元素,把某一元素的地址放到一个指针变量中,所谓的数组元素的指针就是数组元素的地址。c语言定义数组时,编译器会分配连续地址的内存,来存储数组里的元素,实际上数组本质上也是指针。

分别打印了arr&arr[0]的地址,发现地址是一样的,既然是个地址,那就可以使用指针的形式,去访问地址里存储的值,然后打印*arr的值,得到的结果为1,正好和arr[0]的值对应,最后得出数组也可以使用指针的形式去使用。

数组元素的引用

        引用数组元素可以使用下标法,也可以使用指针法,即通过指向数组元素的指针找到所需的元素。使用指针法能使程序质量高,占用内存少,运行速度快。

	p = &a; // p的值是a[0]的地址
	p = a; // p的值是数组a首元素即a[0]的地址

在这里插入图片描述
注意:程序中的数组名不代表整个数组,只代表数组首元素的地址。上面的p = a的作用是把a数组首元素的地址赋给指针变量p,而不是把数组a各元素的值赋给p,可以简写为 int *p = &a[0];也可以写成int *p = a; 也可以写成两行的形式int *p; p = &a[0];他们都有一个作用:将a数组首元素即a[0]的地址赋给指针变量p(而不是*p)。
在这里插入图片描述

  • 下标法 a[i]的形式
  • 指针法如*(a+i)*(p+i)。其中a是数组名,p是指向数组元素的指针变量。
    在这里插入图片描述
    或者用指针变量指向数组元素
    在这里插入图片描述
    注意:在使用指针变量指向数组元素的时候,可以通过改变指针变量的值指向不同的元素,例如上面代码中的方法是使用指针变量p来指向元素,用p++使p的值不断改变宠儿指向不同的元素。
    换一种想法,如果不用p变化的方法而用数组名a变化的方法如a++行不行呢。for(p=a;a<(p+10);a++) printf("%d",*a);答案是不行的,因为数组名a代表数组首个元素的地址,他是一个指针型常量,它的值在程序运行期间是固定不变的,既然a是常量,所以a++是无法实现的。
    例:通过指针变量输出整型数组a的10个元素。
    在这里插入图片描述
    很明显,输出的数值并不是a数组中各个元素的值,因为在执行第二个for循环读入数据后,p已指向a数组的末尾,因此在执行第二个for循环时候,p的起始值不是&a[0]了,而是a+10
    在这里插入图片描述
    解决上面问题只要在第二个for循环之前加一个赋值语句即可
    在这里插入图片描述

常用指针引用数组元素的情况

  • (1) p++; p; p++使p指向下一个元素a[i],然后再执行p,则得到下一个元素a[i]的值。
  • (2) p++; 由于++和同优先级,结合方向为自右而左,因此它等价于*(p++)。先引用p的值,实现*p的运算,然后再使p自增1。
  • (3) (p++)与(++p)作用,前者先取p值,然后使p加1。后者是先使p加1,再取p。若初始值为a即&a[0],若输出*(p++)得到a[0]的值,而输出*(++p)得到a[1]的值。
  • (4) ++(*p) 表示p所指向的元素值加1,如果p = a,则++(*p)相当于++a[0],若a[0]的值为3,则在执行++(*p)即++a[0]后的值为4。
  • (5) 如果p当前指向a数组中第i个元素a[i],则:
            *(p--) 相当于a[i--],先对p进行运算(求p所指向的元素的值),再使p自减。
            *(++p) 相当于a[++i],先使p自加,在进行
    运算。
            *(--p) 相当于a[–i],先使p自减,再进行*运算。
    将++和–运算符用于指针变量十分有效,可以使指针变量自动向前或向后移动,指向下一个或上一个数组元素。

持续更新中。。。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【linux】服务器ubuntu安装cuda11.0、cuDNN教程,简单易懂,包教包会

【linux】服务器ubuntu安装cuda11.0、cuDNN教程&#xff0c;简单易懂&#xff0c;包教包会 【创作不易&#xff0c;求点赞关注收藏】 文章目录 【linux】服务器ubuntu安装cuda11.0、cuDNN教程&#xff0c;简单易懂&#xff0c;包教包会一、版本情况介绍二、安装cuda1、到官网…

elasticsearch 查询超10000的解决方案

前言 默认情况下&#xff0c;Elasticsearch集群中每个分片的搜索结果数量限制为10000。这是为了避免潜在的性能问题。 但是我们 在实际工作过程中时常会遇到 需要深度分页&#xff0c;以及查询批量数据更新的情况 问题&#xff1a;当请求form size >10000 时&#xff0c…

基于多元数据融合的喜马拉雅淡色花岗岩识别

一.基于单一数据源的识别 1.基于物理数据 不同岩层&#xff0c;在密度、弹性、导电性、磁性、放射性等物理属性上有差异&#xff0c;因此能够识别 2.基于化学数据 不同岩体&#xff0c;形成于不同条件&#xff0c;元素组合因此不同&#xff0c;因此能够识别 3.基于遥感数据 …

第一节Linux常见指令

目录 1.Linux下基本指令 ls指令 pwd 命令 cd 指令 知识点:理解树形结构 touch 指令 mkdir指令(重要) rmdir指令 && rm指令(重要) 知识点:ls file* 可以找到当前目录下任何以file开头的文件​编辑 知识点:热键 man指令()重要 补充知识点:nano cp…

PyTorch垃圾分类任务与垃圾图片数据集

新书速览|PyTorch深度学习与企业级项目实战-CSDN博客 人工智能用于垃圾分类 人工智能用于垃圾分类&#xff0c;业界早有过相关的讨论&#xff0c;主要有三种方案&#xff1a;第一种方案&#xff0c;把垃圾的相关信息制成表格化数据&#xff0c;然后用传统的机器学习方法实现分…

C++ //练习 15.15 定义你自己的Disc_quote和Bulk_quote。

C Primer&#xff08;第5版&#xff09; 练习 15.15 练习 15.15 定义你自己的Disc_quote和Bulk_quote。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /******************************************************************…

JavaSE——集合框架二(5/6)-Map系列集合:HashMap、LinkHashMap、TreeMap原理

目录 HashMap集合的底层原理 LinkHashMap的底层原理 TreeMap的底层原理 HashMap集合的底层原理 HashMap的特点 HashMap&#xff08;由键决定特点&#xff09;&#xff1a;无序、不重复、无索引;&#xff08;用的最多&#xff09; HashMap的底层原理 HashMap跟HashSet的底…

如何搭建App自动化测试框架?

前言 Appium是一个开源的自动化测试框架&#xff0c;支持跨平台&#xff0c;支持多种编程语言&#xff0c;可用于原生&#xff0c;混合和移动web应用程序&#xff0c;使用webdriver驱动ios&#xff0c;android应用程序、那么为了学习app自动化测试首要任务肯定就是搭建测试开发…

scratch数学计算 2024年6月中国电子学会图形化编程 少儿编程 scratch编程等级考试三级真题和答案解析

目录 scratch数学计算 一、题目要求 1、准备工作 2、功能实现 二、案例分析 1、角色分析 2、背景分析 3、前期准备 三、解题思路 1、思路分析 2、详细过程 四、程序编写 五、考点分析 六、推荐资料 1、入门基础 2、蓝桥杯比赛 3、考级资料 4、视频课程 5、p…

shell脚本-linux如何在脚本中远程到一台linux机器并执行命令

需求&#xff1a;我们需要从11.0.1.17远程到11.0.1.16上执行命令 实现&#xff1a; 1.让11.0.1.17 可以免密登录到11.0.1.16 [rootlocalhost ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created d…

【密码学】密码学数学基础:剩余系

不得不啃的密码学数学基础之剩余系是个啥&#xff1f;数学里面有好多的定义都有前置的数学概念&#xff0c;要想弄懂剩余系还得先说说“同余”。 一、同余 那么“同余”有是个什么呢&#xff1f;在谈论“同余”之前&#xff0c;我们先圈定个讨论的范围。接下来讨论的都是整数集…

linux基本指令的学习

文章目录 ls指令pwd指令小知识 cd 指令小知识 touch 指令mkdir指令rm指令小知识 man指令cp指令mv指令cat&#xff0c;more&#xff0c;less指令小知识 (echo)head 和 tail指令小知识 &#xff08;管道&#xff09; date指令小知识 &#xff08;时间戳&#xff09; find指令小知…

STM32(五):STM32指南者-按键控制灯开关实验

说明&#xff1a;源代码和教程可从野火处下载&#xff0c;本博客为了记录学习过程STM32&#xff08;四&#xff09;&#xff1a;STM32指南者-跑马灯实验的基础上 一、采用轮询方式1、bsp_key.h2、bsp_key.c3、main.c 二、采用中断方式1、bsp_exti.h2、bsp_exti.c3、stm32f10x_i…

ARM架构(一)—— ARMV8V9基础概念

目录 1.ARMCore的时间线2.ARM术语小结2.1 A64和arrch642.2ARM架构现在的5个系列2.3 微架构2.4 PE2.5 Banked2.6 ARM文档术语2.7 IMPLEMENTATION DEFINFD 和 DEPRECATED2.8 EL1t和EL1h 3 ARMv7的软件架构4 安全状态切换模型4.1 Secure state和Non-secure state介绍 5 Interproce…

鸿蒙模拟器(HarmonyOS Emulator)Beta申请审核流程

文 | Promise Sun 一.背景&#xff1a; 鸿蒙项目开发需要使用模拟器进行开发测试&#xff0c;但目前想在DevEco Studio开发工具中使用模拟器就必须到华为官网进行报名申请&#xff0c;参加“鸿蒙模拟器&#xff08;HarmonyOS Emulator&#xff09;Beta活动申请”。 申请审核通…

cleanshot Mac 上的截图工具

笔者闲来无事&#xff0c;最近在找一些mac上好用的工具其中一款就是cleanShot。为什么不用原有的mac自带的呢。因为相对来说编辑功能不算全面&#xff0c;不支持长截图。那有没有一款软件支持关于截图的好用工具呢。 所以笔者找了这款。安装包是直接安装就可使用的。请大家点赞…

AI算法17-贝叶斯岭回归算法Bayesian Ridge Regression | BRR

贝叶斯岭回归算法简介 贝叶斯岭回归&#xff08;Bayesian Ridge Regression&#xff09;是一种回归分析方法&#xff0c;它结合了岭回归&#xff08;Ridge Regression&#xff09;的正则化特性和贝叶斯统计的推断能力。这种方法在处理具有大量特征的数据集时特别有用&#xff…

STM32第九课:STM32-基于标准库的42步进电机的简单I/O控制(附电机教程,看到即赚到)

一&#xff1a;步进电机简介 步进电机又称为脉冲电机&#xff0c;简而言之&#xff0c;就是一步一步前进的电机。基于最基本的电磁铁原理,它是一种可以自由回转的电磁铁,其动作原理是依靠气隙磁导的变化来产生电磁转矩&#xff0c;步进电机的角位移量与输入的脉冲个数严格成正比…

4000厂商默认账号密码、默认登录凭证汇总.pdf

获取方式&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1F8ho42HTQhebKURWWVW1BQ?pwdy2u5 提取码&#xff1a;y2u5