【C语言】第八期——指针

目录

1 初始指针

2 获取变量的地址

3 定义指针变量、取地址、取值

3.1 定义指针变量

3.2 取地址、取值

4 对指针变量进行读写操作

5 指针变量作为函数参数

6 数组与指针

6.1 指针元素指向数组

6.2 指针加减运算(了解)

6.2.1 指针加减具体数字 

6.2.2 指针加减指针

6.3 数组名与数组元素首地址的关系


1 初始指针

通过前面的教程我们知道变量是用来存储数据的,变量的本质是给存储数据的内存地址起了一个好记的别名

比如我们定义了一个变量 int a= 10 ,这个时候可以直接通过a这个变量来读取内存中保存的10 这个值,在计算机底层a这个变量其实对应了一个内存地址

指针也是一个变量,但它是一种特殊的变量,它存储的数据不是一个普通的值,而是另一个变量的内存地址

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表 示了在内存中的一个地址

刚开始学C语言的指针操作,我们只需要记住两个符号 :&(取地址) 和 *(根据地址取值 /定义指针变量)


2 获取变量的地址

每个变量在运行时都拥有一个地址,这个地址代表变量在内存中的位置。C语言中使用&字符放在变量 前面对变量进行取地址操作

#include <stdio.h>
int main(void)
{int a = 10;printf("a的地址是:%p\n", &a);return 0;
}

3 定义指针变量、取地址、取值

3.1 定义指针变量

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

type *var-name;

在这里,type 是指针的基类型,它必须是一个有效的 C 数据类型,var-name 是指针变量的名称。用 来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是 指针

以下是有效的指针声明:

int* ip;    //一个整型的指针
double* dp; //一个 double 型的指针
float* fp;  //一个浮点型的指针
char* ch    //一个字符型的指针

所有指针的值都是一个地址,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是 一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同


3.2 取地址、取值

#include <stdio.h>
int main(void)
{// 定义一个int变量aint a = 10;printf("a的地址是:%p\n", &a);// 定义int类型的指针变量pint* p_a = &a;printf("指针p_a的值:%p\n", p_a);printf("指针p_a的地址:%p\n", &p_a);printf("a的值:%d\n", a);printf("根据指针p_a的值去内存取值得到的结果为:%d", *p_a);return 0;
}

总结:

  • 取地址操作符&和取值操作符是一对互补操作符, & 取出地址, 根据地址取出地址指向的值
  • 对变量进行取地址(&)操作,可以获得这个变量的地址
  • 指针变量的值是地址
  • 对指针变量进行取值(*)操作,可以获得指针变量指向的原变量的值

4 对指针变量进行读写操作

#include <stdio.h>
int main(void)
{int a = 10;int b = 20;int* p1, * p2; // 定义指针变量 p1、 p2p1 = &a;// p1 指向变量 ap2 = p1;// p2 指向变量 aprintf("&a=%p p1=%p p2=%p\n", &a, p1, p2);*p1 = 20;printf("a的值%d,取指针得到的值%d", a, *p1);return 0;
}

运行结果:

&a=000000612A17FA74 p1=000000612A17FA74 p2=000000612A17FA74
a的值20,取指针得到的值20


5 指针变量作为函数参数

在C语言中,函数参数不仅可以是字符型、整型、浮点型等,还可以是指针类型,作用是将变量地址传递给函数形参

#include <stdio.h> 
void modify1(int *c) 
{*c = 20;
}
int main(void) {int a = 10;modify1(&a);printf("%d", a);return 0;
}

6 数组与指针

6.1 指针元素指向数组

数组本质上是一片连续的内存空间,每个数组元素都对应一块独立的内存空间,它们都有相应的地址。

因此,指针变量既然可以指向变量,也就可以指向数组元素

数组的元素本质上完全可以当做是单独的变量对待,只不过没有名称而已

int a[5]={1,2,3,4,5}; //定义长度为5的int数组
int *p_a=&a[0]; //定义指向int变量的指针变量p_a,把a数组第0个元素地址赋给指针变量p_a

注意:&a[0]等价于&(a[0]),由于[ ]运算符比取地址运算符&优先级高,因此&(a[0])中的小括号可以省略,简写为:&a[0]

在计算机中内存的最小单位是字节,每个字节都对应一个地址

如果一个变量占用多个字节,就会占用 多个内存地址

例如: char 类型变量占1字节就对应1个地址,short 类型变量占2字节对应2个地址,int 类型变量占4 字节对应4个地址.....·其他类型依次类推

同理,数组元素类型不同占用的内存地址也不同

下面通过例子来验证以上分析

#include<stdio.h>
int main(void)
{char c[5];short s[5];int i;for (i = 0; i < 5; i++){printf("&c[%d]=%p ", i, &c[i]);printf("&s[%d]=%p \n", i, &s[i]);}return 0;
}

运行结果:

&c[0]=000000000061FE17 &s[0]=000000000061FE0C

&c[1]=000000000061FE18 &s[1]=000000000061FE0E

&c[2]=000000000061FE19 &s[2]=000000000061FE10

&c[3]=000000000061FE1A &s[3]=000000000061FE12

&c[4]=000000000061FE1B &s[4]=000000000061FE14

说明:不同设备上面输出的地址可能不一样的,数组中每个元素地址都是连续的


6.2 指针加减运算(了解)

6.2.1 指针加减具体数字 

指针本质上就是内存地址,在32 位操作系统下,内存地址是 4 字节的整数。既然是整数就可以进行 加、减、乘、除等算术运算。不过需要注意的是,在 C 语言中一般只讨论指针加、减运算,乘、除等其 他算术运算都没有意义

在实际开发中,指针加、减运算多用于数组(或连续内存空间)。当指针变量p 指向数组元素时,p+1 表 示指向下一个数组元素,p-1 表示指向上一个数组元素

#include <stdio.h>
int main(void)
{int a[3] = { 1, 2, 3 };int* p = &a[0];// 指针 p 指向 a[0]printf("%p %d\n", p, *p); // 输出 a[0] 的地址 和 a[0] 的值p = p + 1;// p 加 1printf("%p %d\n", p, *p); // 输出 a[1] 的地址 和 a[1] 的值return 0;
}

运行结果:

000000811557F968 1
000000811557F96C 2

注意:实现指针加减的时候需要注意越界问题


6.2.2 指针加减指针

在C语言中,两个指针相加是没有意义的,而两个指针相减却有特殊的意义,不过只有当两个指针都指向同一数组中的元素时才有意义

一个数组中的元素时,对它们进行减法运算,得到的结果是这两个指针所指向元素之间相隔的元素个数 (不是之间有的个数,之间有的元素数要在此基础上减一),而不是它们地址差值的字节数。其计算方式是用两个指针的地址差值除以指针所指向数据类型的大小

用公式表示为:(指针2的地址 - 指针1的地址) / sizeof(指针所指向的数据类型)


6.3 数组名与数组元素首地址的关系

C语言中,数组名与数组首元素地址等价。也就是说,在程序中,输出数组名与输出数组首元素地址是相同的

#include <stdio.h>
int main(void)
{int num[5];printf("%p\n", num);     // 输出数组名printf("%p\n", &num[0]); // 输出数组首元素地址return 0;
}

输出结果:

000000000061FE00

000000000061FE00

我们就可以通过把数组名复制给指针变量,来把数组首地址给指针变量

#include <stdio.h>int main(void){int num[5] = {1, 2, 3, 4, 5};int *p_num = num; // 把num的首地址赋值给指针变量printf("p_num指针的值=%p \n p_num对应数组元素的值%d", p_num, *p_num);return 0;}

我们也可以通过p_num来访问数组里面的每个元素

 #include <stdio.h>int main(void){int num[5] = {1, 2, 3, 4, 5};int *p_num = num; // 把num的首地址赋值给指针变量printf("p_num指针的值=%p ,num的地址是=%p  p_num对应数组元素的值%d\n", p_num, num, 
*p_num);printf("p_num访问第一个元素=%d\n", p_num[0]);printf("p_num访问第二个元素=%d\n", p_num[1]);return 0;}

运行结果:

p_num指针的值=000000000061FE00 ,num的地址是=000000000061FE00  p_num对应数组元素的值1

p_num访问第一个元素=1 p_num访问第二个元素=2

持续更新中...

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

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

相关文章

为 Power Automate 注册 Adobe PDF Services

前言 最近&#xff0c;再测试如何将HTML转换成PDF&#xff0c;然后发现Adobe有一个免费的操作可以用&#xff0c;好开心&#xff0c;赶紧注册一下。 正文 1.先注册一个账号&#xff0c;然后登录到Adobe Developer 注册链接&#xff1a;https://www.adobe.com/go/getstarted_pow…

BY组态:工业自动化的未来,触手可及

1. BY组态软件的核心优势 简单易用&#xff1a;图形化界面&#xff0c;降低学习成本&#xff0c;快速上手。 高效灵活&#xff1a;支持多种设备协议&#xff0c;兼容性强&#xff0c;适用于多种行业。 实时监控&#xff1a;提供实时数据采集与可视化&#xff0c;助力高效决策…

有哪些开源大数据处理项目使用了大模型

以下是一些使用了大模型的开源大数据处理项目&#xff1a; 1. **RedPajama**&#xff1a;这是一个开源项目&#xff0c;使用了LLM大语言模型数据处理组件&#xff0c;对GitHub代码数据进行清洗和处理。具体流程包括数据清洗、过滤低质量样本、识别和删除重复样本等步骤。 2. …

网络安全之攻防笔记--通用安全漏洞SQL注入sqlmapOraclemongodbDB2

通用安全漏洞SQL注入&sqlmap&Oracle&mongodb&DB2 数据库类型 ACCESS 特性 没数据库用户 没数据库权限 没数据库查询参数 没有高权限注入说法 暴力猜解&#xff0c;借助字典得到数据 注入方式 联合注入 偏移注入 表名列名猜解不到 偏移注入 MySQL 低权限 常…

【信息系统项目管理师-案例真题】2022下半年案例分析答案和详解

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 试题一(24分)【问题1】(6分)【问题2】(10分)【问题3】(8分)试题二(26分)【问题1】(8分)【问题2】(8分)【问题3】(4分)【问题4】(6分)试题三(25分)【问题1】(12分)【问题2】(7分)【问题…

正点原子[第三期]Arm(iMX6U)Linux系统移植和根文件系统构建-5.3 xxx_defconfig过程

前言&#xff1a; 本文是根据哔哩哔哩网站上“arm(iMX6U)Linux系统移植和根文件系统构键篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。 引用&#xff1a; …

C++初阶——简单实现list

目录 1、前言 2、List.h 3、Test.cpp 1、前言 1. 简单实现std::list&#xff0c;重点&#xff1a;迭代器&#xff0c;模板类&#xff0c;运算符重载。 2. 并不是&#xff0c;所有的类&#xff0c;都需要深拷贝&#xff0c;像迭代器类模板&#xff0c;只是用别的类的资源&am…

conda环境中运行“python --version“所得的版本与环境中的python版本不一致----deepseek并非全能

conda环境中运行python —version所得python版本与conda环境中的python版本不一致------deepseek并非全能 问题 conda环境中运行python —version所得python版本与conda环境中的python版本不一致 我所做的探索 1 网页搜索 2 求助于DeepSeek 可以用四个字来形容deepseek给出…

HarmonyOS学习第5天: Hello World的诞生之旅

鸿蒙初印象&#xff1a;开启探索之门 在操作系统的广袤天地中&#xff0c;HarmonyOS&#xff08;鸿蒙系统&#xff09;宛如一颗冉冉升起的新星&#xff0c;自诞生起便备受瞩目。它由华为倾力打造&#xff0c;是一款基于微内核的全场景分布式操作系统&#xff0c;以其独特的技术…

centos9安装k8s集群

以下是基于CentOS Stream 9的Kubernetes 1.28.2完整安装流程&#xff08;containerd版&#xff09;&#xff1a; 一、系统初始化&#xff08;所有节点执行&#xff09; # 关闭防火墙 systemctl disable --now firewalld# 关闭SELinux sed -i "s/SELINUXenforcing/SELINU…

CIG容器重量级监控系统

1.介绍 CAdvisorinfluxDBGranfana docker 原生命令 监控docker容器状态 docker stats 2.CAdvicsor 3.InfluxDB 4.Granafana 5.搭建 volumes:grafana_data: services:influxdb:image: tutum/influxdbrestart: alwaysenvironment:- PRE_CREATE_DBcadvisorports:- "8083…

REACT学习DAY02(恨连接不上服务器)

受控表单绑定 概念&#xff1a;使用React组件的状态&#xff08;useState&#xff09;控制表单的状态 1. 准备一个React状态值 const [value,setValue] useState() 2. 通过value属性绑定状态&#xff0c;通过onChange属性绑定状态同步的函数 <input type"text&quo…

python——GUI图形用户界面编程

GUI简介 我们前面实现的都是基于控制台的程序&#xff0c;程序和用户的交互通过控制台来完成 本章&#xff0c;我们来学习GUI图形用户界面编程&#xff0c;我们可以通过python提供的丰富的组件&#xff0c;快速的视线使用图形界面和用户交互 GUI变成类似于“搭积木”&#x…

DeepSeek 助力 Vue 开发:打造丝滑的单选按钮(Radio Button)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

美颜相机1.0

项目开发步骤 1 界面开发 美颜相机界面构成&#xff1a; 标题 尺寸 关闭方式 位置 可视化 2 创建主函数调用界面方法 3 添加两个面板 一个是按钮面板一个是图片面板 用JPanel 4 添加按钮到按钮面吧【注意&#xff1a;此时要用初始化按钮面板的方法initBtnPanel 并且将按钮添…

openharmony中hdf框架的驱动消息机制的实现原理

openharmony中hdf框架的驱动消息机制的实现原理 在分析hdf框架时发现绕来绕去的&#xff0c;整体梳理画了一遍流程图&#xff0c;发现还是有点模糊甚至不清楚如何使用的&#xff0c;详细的每个点都去剖析细节又过于消耗时间&#xff0c;所以有时间便从功能应用的角度一块块的去…

leaflet实现历史轨迹播放效果

效果图如下&#xff1a; 效果实现&#xff1a; 1、添加完整轨迹线&#xff0c;蓝色的 this.echoLine L.polyline(points, { weight: 8 }).addTo(this.map) 2、添加实时轨迹线&#xff0c;初始状态置空 this.realEchoLine L.polyline([], { weight: 12, color: "#FF9…

JAVAEE一>Spring IoC和DI详解

目录 Spring容器说明&#xff1a;Ioc容器优势&#xff1a;DI介绍&#xff1a;从Spring获取对象&#xff1a;获取对象的方法&#xff1a;关于上下文的概念&#xff1a; Controller注解&#xff08;控制层&#xff1a;接收参数并响应&#xff09;&#xff1a;Service注解&#xf…

(四)趣学设计模式 之 原型模式!

目录 一、 啥是原型模式&#xff1f;二、 为什么要用原型模式&#xff1f;三、 原型模式怎么实现&#xff1f;四、 原型模式的应用场景五、 原型模式的优点和缺点六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xf…

完美解决:.vmx 配置文件是由 VMware 产品创建,但该产品与此版 VMware Workstation 不兼容

参考文章&#xff1a;该产品与此版 VMware Workstation 不兼容&#xff0c;因此无法使用 问题描述 当尝试使用 VMware Workstation 打开别人的虚拟机时&#xff0c;可能会遇到以下报错&#xff1a; 此问题常见于以下场景&#xff1a; 从其他 VMware 版本&#xff08;如 ESX…