4、指针与数组

数组与指针

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

指针是一种保存变量地址的变量。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.hqwc.cn/news/338429.html

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

相关文章

金融帝国实验室(Capitalism Lab)V10版本游戏平衡性优化与改进

即将推出的V10版本中的各种游戏平衡性优化与改进&#xff1a; ————————————— 一、当玩家被提议收购一家即将破产的公司时&#xff0c;显示商业秘密。 当一家公司濒临破产&#xff0c;玩家被提议收购该公司时&#xff0c;如果玩家有兴趣评估该公司&#xff0c;则无…

element plus el-form双列布局及拓展任意布局

1 场景 一般表单我们直接默认布局&#xff0c;也就是单列布局&#xff0c;突然有个人员信息表单&#xff0c;需要双列布局的需求&#xff0c;简单实现并拓展下 2 思路 直接无脑divflex布局实现 3 代码 <template><el-form ref"formRef" :model"fo…

【DNS】

服务程序 1.如果有默认配置&#xff0c;请先备份在进行修改 2.修改完配置文件&#xff0c;请重启服务或重新加载配置文件&#xff0c;否则不生效 dhcp 动态主机配置协议&#xff08;自动分配ip地址&#xff09; 只要插上网线就可以获得ip地址 dhcp的分配方式&#xff1a;1…

概述:利用大模型 (LLMs) 解决信息抽取任务

论文标题&#xff1a;Large Language Models for Generative Information Extraction: A Survey 论文链接&#xff1a;https://arxiv.org/pdf/2312.17617.pdf 论文主要探讨了大型语言模型&#xff08;LLMs&#xff09;在生成式信息抽取&#xff08;IE&#xff09;任务中的应用…

PYTHON通过跳板机巡检CENTOS的简单实现

实现的细节和引用的文件和以前博客记录的基本一致 https://shaka.blog.csdn.net/article/details/106927633 差别在于,这次是通过跳板机登陆获取的主机信息,只记录差异的部份 1.需要在跳板机相应的路径放置PYTHON的脚本resc.py resc.py这个脚本中有引用的文件(pm.sh,diskpn…

东方通中间件使用IDEA进行远程打debug

修改startserver.sh JAVA_OPTS"${JAVA_OPTS} -Xdebug -Xrunjdwp:transportdt_socket,servery,suspendn,address5005"idea配置请参考我的其他篇博客&#xff08;idea 对远程服务器打debug&#xff09;

CSS3背景样式详解(图像大小,图像位置等)

背景样式 在CSS3中&#xff0c;新增了3个背景属性 属性说明background-size背景大小background-origin背景位置background-clip背景剪切 background-size属性 概念&#xff1a;在CSS3之前&#xff0c;我们是不能用CSS来控制背景图片大小的&#xff0c;背景图片的大小都是由…

1 快速前端开发

1 前端开发 目的&#xff1a;开发一个平台&#xff08;网站&#xff09;- 前端开发&#xff1a;HTML、CSS、JavaScript- Web框架&#xff1a;接收请求并处理- MySQL数据库&#xff1a;存储数据地方快速上手&#xff1a;基于Flask Web框架让你快速搭建一个网站出来。1.快速开发…

【python基础】一文搞懂:Python 中轻量型数据库 SQLite3 的用法

一文搞懂&#xff1a;Python 中轻量型数据库 SQLite3 的用法 文章目录 一文搞懂&#xff1a;Python 中轻量型数据库 SQLite3 的用法1 引言2 SQLite3 简介3 基本步骤4 示例代码4.1 连接数据库4.2 创建表4.3 插入数据4.4 查询数据4.5 更新/删除数据4.6 关闭数据库连接 5 实例演示…

虚拟机安装intel架构的银河麒麟V10(SP1)

一 背景 银河麒麟是国产操作系统之一&#xff0c;是基于Linux内核的桌面操作系统&#xff0c;有自己的应用中心&#xff0c;具有一定的生态系统。今从官网下载了V10&#xff08;SP1&#xff09;镜像文件&#xff0c;在Windowns的VMware虚拟机上安装试用。 官网&#xff1a;http…

web缓存之nginx缓存

一、nginx缓存知识 网络缓存位于客户端和 "源服务器 "之间&#xff0c;保存着所有可见内容的副本。当客户端请求缓存中存储的内容时&#xff0c;它可以直接从缓存中检索内容&#xff0c;而无需与服务器通信。这样&#xff0c;网络缓存就 "接近 "了客户端&a…

idea git回滚之前提交记录

提交代码时&#xff0c;如果不小心提交了不需要提交的内容&#xff0c;在本地仓库中&#xff0c;此时需要回滚版本&#xff0c;如何回滚 1.打开git控制台&#xff0c;左下角git,选择要处理的分支&#xff0c;选择刷新获取最新git提交记录 2&#xff09;选中自己commit需要回滚…