4、C语言:指针与数组

news2025/2/25 12:17:32

数组与指针

  • 指针与地址
  • 指针与函数参数
  • 指针与数组
  • 地址算数运算
  • 字符指针与函数
  • 指针数组以及指向指针的指针
  • 多维数组
  • 命令行参数
  • 指向函数的指针
  • 复杂声明

指针是一种保存变量地址的变量。C语言中,指针的使用非常广泛,原因之一是,指针常常是表达某个计算的惟一途径,另一个原因是,同其它方法比较起来,使用指针通常可以生成更高效、更紧凑的代码。

指针与地址

  • 指针是能够存放一个地址的一组存储单元(通常是两个或4个字节)。如图c的类型是char,并且p是指向c的指针。
    在这里插入图片描述
  • 取地址符&
    地址运算符&只能应用于内存中的对象,即变量与数组元素。它不能作用于表达式、常量或register类型的变量。
p = &c;  //将把c的地址赋值给变量p,我们称p为“指向”c的指针
  • 间接寻址或间接引用运算符*
    当它作用于指针时,将访问指针所指向的对象。
int x = 1, y = 2, z[10];
int *ip;  //ip是指向int类型的指针
ip = &x;  //ip现在指向x
y = *ip;  //y值现在为1
*ip = 0;  //x值现在为0
ip = &z[0]; //ip现在指向z[0]

(*ip)++,中的圆括号是必需的,否则,该表达式将对ip进行加1 运算,而不是对ip指向的对象进行加1运算。
指针也是变量,所以在程序中可以直接使用,而不必通过间接引用的方法使用。

指针与函数参数

指针参数使得被调用函数能够访问和修改主调函数中对象的值。(针对变量名称,其为指针还是类型?)

void swap(int *px, int *py)
{
	int temp;
	temp = *px;
	*px = *py;
	*py = temp;
}

指针与数组

在 C 语言中,指针和数组之间的关系十分密切,因此,在接下来的部分中,我们将同时讨论指针与数组。通过数组下标所能完成的任何操作都可以通过指针来实现。一般来说,用指针编写的程序比用数组下标编写的程序执行速度快,但另一方面,用指针实现的程序理解起来稍微困难一些。
数组声明:

int a[10];

存储形式:
在这里插入图片描述

int *pa;
pa = &a[0];  //pa指向数组a的第0个元素,pa的值为a[0]的地址

在这里插入图片描述
在这里插入图片描述
数组名代表该数组最开始的一个元素的地址。

pa = &a[0];
pa = a;

a[i]等同于*(a+i),在计算数组元素a[i]的值时,C 语言实际上先将其转换为*(a+i)的形式,然后再进行求值。简而言之,一个通过数组和下标实现的表达式可等价地通过指针和偏移量实现。
数组名和指针之间有一个不同之处,指针是一个变量,因此,在C语言中,语句pa=a和pa++都是合法的。但数组名不是变量,因此,类似于a=pa和a++形式的语句是非法的。但是在函数参数中,相当于将数组的第一个地址赋予了函数的形参,并非是数组名的自增,所以是可以传递数组名的。

  • 函数定义中,形式参数char a[]和char *s是等价的。

地址算数运算

  • c语言中的地址算术运算方法是一致且有规律的,将指针、数组和地址的算术运算集成在
    一起是该语言的一大优点。
  • 指针与整数之间不能相互转换,但0是惟一的例外:常量0可以赋值给指针,指针也可以和常量0进行比较。程序中经常用符号常量NULL代替常量0,这样便于更清晰地说明常量0是指针的一个特殊值。。符号常量NULL定义在标准头文件<stddef.h>中。
  • 指针p和q指向同一个数组的成员,那么它们之间就可以进行类似于==、!=、<、>==的关系比较运算。
  • 地址计算时是以字节为基本单元来运算的,比如char数组计算时,下一个字符提取可以直接地址加1.但是如果是int型,则需要地址+4才能转换到下一个int整数。前提是定义该指针为char型。
  • 指针的算术运算具有一致性:如果处理的数据类型是比字符型占据更多存储空间的浮点类型,并且p是一个指向浮点类型的指针,那么在执行p++后,p将指向下一个浮点数的地址。
    有效的指针运算包括相同类型指针之间的赋值运算;指针同整数之间的加法或减法运算;
    指向相同数组中元素的两个指针间的减法或比较运算;将指针赋值为0或指针与0之间的比较运算

字符指针与函数

字符串常量是一个字符数组。

”I am a string“

字符串常量占据的存储单元数也因此比双引号内的字符数大1。

  • 字符串常量使用
printf("Hello, world\n");
char *pmessage;
pmessage = "now is the time";  //都是指针使用
  • 字符数组与字符指针
char amessage[] = "nw is the time"; /* 定义一个数组*/
char *pmessage = "now is the time"; /* 定义一个指针*/

在这里插入图片描述

  • 复制字符串程序
void strcpy(char *s, char *t)  //将t拷贝到s中
{
	while (*s++ = *t++)
;
}
  • 进栈和出栈操作
*p++ = val;  //将val压入栈
val = *--p;  //将栈顶元素弹出到val中

指针数组以及指向指针的指针

由于指针本身也是变量,所以它们也可以像其它变量一样存储在数组中。

char *lineptr[MAXLINES];
  • 初始化
    指针数组的初始化语法和前面所讲的其它类型对象的初始化语法类似。
static char *name[] = {
	"Illegal month",
	"January", "February", "March",
	"April", "May", "June",
	"July", "August", "September",
	"October", "November", "December"
};

多维数组

C语言提供了类似于矩阵的多维数组,但实际上它们并不像指针数组使用得那样广泛。

static char daytab[2][13] = {
	{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
	{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
  • 区别
	f(int (*daytab)[13]); //二维数组,表明参数是一个指针,它指向具有13个整型元素的一维数组
	int *daytab[13];   //一维指针数组
  • 指针与多维数组
	int a[10][20];
	int *b[10];

指针数组的一个重要优点在于,数组的每一行长度可以不同。而多维数组可以理解为每行固定长度的指针。

命令行参数

在支持C 语言的环境中,可以在程序开始执行时将命令行参数传递给程序。调用主函数main 时,它带有两个参数。第一个参数(习惯上称为argc,用于参数计数)的值表示运行程序时命令行中参数的数目;第二个参数(称为argv,用于参数向量)是一个指向字符串数组的指针,其中每个字符串对应一个参数。我们通常用多级指针处理这些字符串。
在这里插入图片描述
C语言程序有一个公共的约定:以负号开头的参数表示一个可选标志或参数。
在系统中调用运行的程序:

find -x -n
find -xn   // 组合使用

指向函数的指针

在 C 语言中,函数本身不是变量,但可以定义指向函数的指针。

int (*comp)(void *, void *);  //函数指针
int *comp(void *, void *); //返回指针的函数

复杂声明

int *f();  //f是一个函数,它返回一个指向int类型的指针
int (*pf)();   //pf:是一个指向函数的指针,该函数返回一个int类型的对象

如何创建复杂声明?

  1. 使用typedef通过简单的步骤合成;
  2. 采用函数将正确的C语言声明转换为文字描述。

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

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

相关文章

IaC基础设施即代码:使用Terraform 连接 alicloud阿里云

目录 一、实验 1.环境 2.alicloud阿里云创建用户 3.Linux使用Terraform 连接 alicloud 4.Windows使用Terraform 连接 alicloud 二、问题 1.Windows如何申明RAM 相关变量 2.Linux如何申明RAM 相关变量 3. Linux terraform 初始化失败 4.Linux terraform 计划与预览失败…

[ACM算法学习] 诱导排序与 SA-IS算法

学习自诱导排序与SA-IS算法 - riteme.site 为了简化一些操作&#xff0c;定义 # 是字典序最小的字符&#xff0c;其字典序小于字母集里任意字符&#xff0c;并且将其默认作为每个字符串的最后一个字符&#xff0c;即作 S[|S|] SA-IS 算法 SA-IS 算法是基于诱导排序这种思想。…

React入门 - 06(TodoList 列表数据的新增和删除)

本章内容 目录 一、实践一下 React 的列表渲染二、TodoList 新增功能三、列表循环的 key四、删除 上一节内容我们完成了输入框中可以自由输入内容&#xff0c;这一节我们继续 TodoList功能的完善&#xff1a;列表数据的新增和删除。 在开始之前&#xff0c;我们先介绍一下 Re…

java实现教务管理系统

git地址&#xff1a;https://gitee.com/myshort-term/school-management 1.系统简介 开发教务管理系统程序&#xff0c;设计了ems&#xff08;EMSApp&#xff09;、dao&#xff08;AssignmentDAO、CourseDAO、DeptDAO、ScoreDAO、UserDAO、EmailDAO&#xff09;、domain&#…

优雅草蜻蜓API大数据服务中心v1.0.4更新-加入蓝奏云直链解析·每日Bing·字数统计·今日油价·历史上的今天等接口

2024年1月13日优雅草蜻蜓API大数据服务中心v1.0.4更新-加入蓝奏云直链解析每日Bing字数统计今日油价历史上的今天等接口 优雅草api服务-大数据中心自12月29日推出以来截止2024年1月13日累计被调用次数为413次&#xff0c;共收录23个接口&#xff0c;截止前一日2024年1月12日当…

一元二次方程虚数解

对一元二次方程axbxc0 (a≠0)&#xff1b;若判别式△b-4ac<0,则方程无实根,虚数解为&#xff1a;x(-b i√(4ac-b))/(2a)。 只含有一个未知数&#xff08;一元&#xff09;&#xff0c;并且未知数项的最高次数是2&#xff08;二次&#xff09;的整式方程叫做一元二次方程[1] …

SpringCloud:微服务

文章目录 微服务服务架构演变单例架构&#xff08;集中式架构&#xff09;分布式架构 微服务SpringCloud 微服务 服务架构演变 单例架构&#xff08;集中式架构&#xff09; 单例架构&#xff1a; 将业务的所有功能集中在一个项目中开发&#xff0c;打成一个包部署 优点&…

CSS基础笔记-05layout

CSS基础笔记系列 《CSS基础笔记-01CSS概述》《CSS基础笔记-02动画》《CSS基础笔记-03选择器》《CSS基础笔记-04cascade-specificity-inheritance》 文章目录 CSS基础笔记系列什么是CSS布局布局方法normal flowflexboxgridfloats 总结 什么是CSS布局 CSS布局是指在页面中对元素…

信息质量要求

目录 \quad 会计信息质量要求 会计核算的信息质量要求是对会计核算提供信息的基本要求,是处理具体会计业务的基本依据&#xff0c;是在会计核算前提条件制约下进行会计核算的标准和质量要求。 \quad \quad 可靠性 也就是真实性, 要求会计记录以实际凭证为依据如实反映财务状况和…

Compileflow工作流引擎使用讲解

文章目录 1 Compileflow1.1 简介1.2 特点1.3 Compileflow插件下载1.4 main方法调用1.4.1 pom.xml1.4.2 新建bpm文件1.4.3 各个节点绑定方法1.4.4 测试方法 1.5 bpm各个标签说明1.5.1 BPM根节点1.5.2 全局变量1.5.3 开始节点: start1.5.4 结束节点: end1.5.5 自动节点: autoTask…

关于Quartz远程调用服务方法失败如何解决,@Inner详细介绍

1.单独在要调用服务的controller写上相关方法&#xff08;Inner(value true)要走aop&#xff0c;会检测是否有内部调用标识&#xff09;具体见下述 2. 编写Feign远程调用的接口&#xff0c;注意加上RequestHeader(SecurityConstants.FROM) String from。因为inner(value true…

带你拿捏SpringBoot自动装配的核心技术?模块装配(@EnableXXX注解+@Import)+ 条件装配(@ConditionalXXX)

文章目录 Profile激活指定配置文件主配置文件中指定激活的profile命令行激活设置虚拟机参数激活 profile控制不到的地方 Spring原生的条件装配注解ConditionalConditional接口讲解案例讲解 Spring Boot封装的条件装配注解ConditionalXXX自己实现ConditionalOnBeanSpringBoot 源…

【目标检测】评价指标:mAP概念及其计算方法(yolo源码/pycocotools)

本篇文章首先介绍目标检测任务中的关键评价指标mAP的概念&#xff1b;然后介绍其在yolo源码和pycocotools工具中的实现方法&#xff1b;最后比较两种mAP的计算方法的不同之处。 目标检测中的评价指标&#xff1a; mAP概念及其计算方法(yolo源码/pycocotools) 混淆矩阵概念及其…

6.2 声音编辑工具GoldWave5简介(7)

6.2.5其它常用功能 1&#xff0e;高低通 把录制的语音和背景音乐融合在一起时&#xff0c;可能会出现背景音乐音量过大&#xff0c;语音音量过小的现象&#xff0c;这时可以选择“低通”将背景音乐的音量降低一些。 (1)选择【效果】|【波波器】|【低通/高通】命令&#xff0…

开箱即用的企业级前后端分离【.NET Core6.0 Api + Vue 2.x + RBAC】权限框架-Blog.Core

前言 今天要给大家推荐一个开箱即用的企业级前后端分离【.NET Core6.0 Api Vue 2.x RBAC】权限框架&#xff08;提高生产效率&#xff0c;快速开发就选它&#xff09;&#xff1a;Blog.Core。 推荐原因 Blog.Core通过详细的文章和视频讲解&#xff0c;将知识点各个击破&…

2024-1-12 关于SVPWM的理解疑问

直流母线电压利用率是指逆变电路&#xff08;电机控制器&#xff09;所能输出的交流电压基波最大幅值U1m和直流母线电压之比。 电压利用率 SVPWM算法理解&#xff08;二&#xff09;——关于非零基本矢量幅值和线电压幅值的解释 因此我们在实际应用中提供的直流侧电压Udc&…

ssm基于Web的课堂管理系统设计与实现论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

【Linux】 系统目录结构

进入到根目录 cd /ls目录名具体作用/存放系统系统相关的目录文件/boot放置linux系统内核文件和启动时用到的一些引导文件/home包含linux系统上各用户的主目录&#xff0c;子目录名称默认以该用户名命名/root系统管理员root的家目录/bin包含常用的命令文件&#xff08;如ls 等&a…

STM32 CAN学习(一)

STM32 CAN CAN协议简介 CAN是控制器局域网络(Controller Area Network)的简称&#xff0c;它是由研发和生产汽车电子产品著称的德国BOSCH公司开发的&#xff0c;并最终成为国际标准&#xff08;ISO11519&#xff09;&#xff0c;是国际上应用最广泛的现场总线之一。CAN总线协…