C语言之指针和数组

news2025/1/20 19:12:20

指针和数组虽然是不同的东西,但却有着千丝万缕的关系,下面就让我们逐一了解吧!

指针和数组

数组名原则上会被解释为指向该数组起始元素的指针

也就是说。如果a是数组,那么表达式a的值就是a[0]的值,即与&a[0]一致;如果数组a的元素类型为Type型,那么不管有多少个元素,表达式a的类型都为Type*型。

将数组名视为指针,也催生出了数组与指针的密切关系,我们看下图:

这里声明了数组a和指针p,指针p的初始值是a,又因为数组名a会被解释为&a[0],所以存入p的值为&a[0],也就是说指针p会被初始化为指向数组起始元素的a[0],指针p指向的起始元素,不是数组中的全部元素。

围绕着指向数组元素的指针,有以下规则成立:

指针p指向数组的元素e时:

1.p+i为指向元素e后的第i个元素
2.p-i为指向元素e前的第i个元素

 数组名在什么情况下不会被视为指向起始元素的指针

█作为sizeof运算符的操作数出现时

sizeof(数组名)不会生成指向起始元素的指针的长度,而是生成数组的整体长度

█作为取地址运算符&的操作数出现时

&+数组名不是指向起始元素的指针的指针,而是指向数组整体得指针


也就是说,指向各元素的指针p+i和&a[i]是等价的,其中&a[i]是指向元素a[i]的指针,其值是a[i]的地址

我们用一个代码来显示出它们各自的值:

#include<stdio.h>

int main()
{
	int i = 0;
	int a[5] = {1,2,3,4,5};
	int *p = a;
	
	for(;i<5;i++)
		printf("&a[%d] = %p   p+%d = %p\n", i, &a[i], i, p + i);
	
	return 0;
}

指针运算符和下表运算符

如果在指向数组内元素的指针p+i前写上指针运算符*,会变成什么情况呢?

*(p+i)就是该元素的别名,因此如果p指向a[0],那么表达式*(p+i)就表示a[i]的本身

指针p指向数组的元素e时:

指向元素e后第i个元素*(p+i),可以写为p[i]

指向元素e前第i的元素*(p-i),可以写为p[-i]

 我们来看下它们之间的关系:

  • 因为p+2指向a[2],所以*(p+2)是a[2]的别名(组c)
  • 因为*(p+2)可以写为a[2],所以p[2]也是a[2]的别名(组B)

以下4个表达式都是访问各元素的表达式:

a[i]

*(a+i)

p[i]

*(p+i)

一下4个表达式都是指向各元素的指针:

&a[i]

a+i

&p[i]

p+i

注意

Type*型指针p指向Type型数组a的起始元素a[0]时,指针p的行为就和数组a本身一样

表达式a[i]和p+i中的i,表示位于指针a和p所指的元素后第几个元素的位置,所以数组起始元素的下标必须是0

数组和指针的不同点

int *p;
int y[5];
p = y;

p是指向int型变量的指针,被赋给p的是y,即&y[0],赋值后,指针p指向y[0]

int a[5];
int b[5];
a = b;

指向a=b时会出现编译错误,虽然说a会被解释为指向数组起始元素的指针,但不可以改写其值

如果可以这样赋值,那么数组的地址就会被改变,变为别的地址,因此,赋值表达式的左操作数不可是数组名。

下标运算符的操作数

我们看下指针p和整数i相加的式子前写上指针运算符的表达式*(p+i),括号内的进行的是加法运算,与算数类型的数值间的加法运算等同,也就是*(i+p)

这样一来,访问数组元素的表达式p[i]也可以写成i[p],下表运算符[ ],是具有两个操作数的双目运算符,其中一个操作数的类型是:

指向Type型对象的指针

另一个操作数的类型是:

整数类型数据类型

下标运算符[ ]的操作数的顺序是随意的,例如a[3]也可以写为3[a]

下表运算符[ ]所生成值的类型是:Type型

但是在进行书写时,这种格式虽然没有错误,但还是尽量不要这样写

数组的传递

#include<stdio.h>

/*将数组v开头的n个元素赋值给val*/
void ary_set(int v[], int n, int val)
{
	int i = 0;
	for(; i < n; i++)
		v[i] = val;
}
int main()
{
	int i = 0;
	int a[] = {1,2,3,4,5};
	
	ary_set(a, 5, 99);
	
	for(;i < 5; i++)
		printf("a[%d] = %d\n", i, a[i]);
	
	return 0;
}

对于ary_set函数中数组v的声明可以写为一下几种形式:

a和b都可以解释为c,也就是说形参v的类型不是数组而是指针,即使像b中那样声明元素的个数,也是无用的。

但是我们可以在传递数组时,将数组元素个数作为别的参数来处理。

在调用ary_set函数时,,int*型的形参v将使用实参a,即&a[0]进行初始化,由于指针v指向数组的起始元素a[0],因此在ary_set函数内指针v的行为就像数组本身一样

如果改写所接受的元素的值,结果就会反映到调用方的数组元素上。

注意

函数间数组的传递是以指向第一元素的指针的形式进行的,在被调用的函数中作为指针接收的数组,实际上就是调用方传递的数组。

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

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

相关文章

「Verilog学习笔记」序列检测器(Moore型)

专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点&#xff0c;刷题网站用的是牛客网 timescale 1ns/1nsmodule det_moore(input clk ,input rst_n ,input din ,output reg Y ); parameter S0 …

从物联网到 3D 打印:硬件相关的开源项目概览 | 开源专题 No.52

arendst/Tasmota Stars: 20.4k License: GPL-3.0 Tasmota 是一款为 ESP8266 和 ESP32 设备提供的替代固件&#xff0c;具有易于配置的 webUI、OTA 更新、定时器或规则驱动的自动化功能以及通过 MQTT、HTTP、串口或 KNX 进行完全本地控制。该项目主要特点包括&#xff1a; 支持…

143.【Nginx-02】

Nginx-02 (五)、Nginx负载均衡1.负载均衡概述2.负载均衡的原理及处理流程(1).负载均衡的作用 3.负载均衡常用的处理方式(1).用户手动选择(2).DNS轮询方式(3).四/七层负载均衡(4).Nginx七层负载均衡指令 ⭐(5).Nginx七层负载均衡的实现流程 ⭐ 4.负载均衡状态(1).down (停用)(2)…

【Git】Git的基本操作

前言 Git是当前最主流的版本管理器&#xff0c;它可以控制电脑上的所有格式的文件。 它对于开发人员&#xff0c;可以管理项目中的源代码文档。&#xff08;可以记录不同提交的修改细节&#xff0c;并且任意跳转版本&#xff09; 本篇博客基于最近对Git的学习&#xff0c;简单介…

docker学习笔记05-TCP远程连接与docker compose简介

1.配置docker客户端远程访问 A.在另一台机器上安装客户端 远程访问&#xff0c;再搭建一台测试机&#xff0c;先安装包dockercli 客户端 yum install -y yum-utils --或者用阿里源 快些 sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos…

Leetcode算法系列| 10. 正则表达式匹配

目录 1.题目2.题解C# 解法一&#xff1a;分段匹配法C# 解法二&#xff1a;回溯法C# 解法三&#xff1a;动态规划 1.题目 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 1.‘.’ 匹配任意单个字符 2.‘.’ 匹配任意单个字…

YOLOv8 上手体验

Yooooooo&#x1f387; &#x1f96a;环境搭建⚡注意&#x1f4a1;CUDAPyTorch&#x1f4a1;ultralytics &#x1f9aa;食用&#x1f4a1;cmd&#x1f4a1;Python &#x1f372;导出官方模型到本地 &#x1f96a;环境搭建 ⚡注意 Python>3.8 PyTorch>1.8 &#x1f4a1;C…

2023-12-30 AIGC-LangChain指南-打造LLM的垂域AI框架

摘要: 2023-12-30 AIGC-LangChain指南-打造LLM的垂域AI框架 LangChain指南-打造LLM的垂域AI框架 CHATGPT以来&#xff0c;Langchain 可能是目前在 AI 领域中最热门的事物之一&#xff0c;仅次于向量数据库。 它是一个框架&#xff0c;用于在大型语言模型上开发应用程序&#…

数据库原理与应用快速复习(期末急救)

文章目录 第一章数据库系统概述数据、数据库、数据库管理系统、数据定义、数据组织、存储和管理、数据操纵功能、数据库系统的构成数据管理功能、数据库管理的3个阶段以及特点数据库的特点、共享、独立、DBMS数据控制功能数据库的特点 数据模型两类数据模型、逻辑模型主要包括什…

每日一题——LeetCode961

方法一 排序法&#xff1a; 2*n长度的数组里面有一个元素重复了n次&#xff0c;那么将数组排序&#xff0c;求出排序后数组的中间值&#xff08;因为长度是偶数&#xff0c;没有刚好的中间值&#xff0c;默认求的中间值是偏左边的那个&#xff09;那么共有三种情况&#xff1a;…

【JavaEE进阶】 @RequestMapping注解

文章目录 &#x1f384;什么是RequestMapping 注解&#x1f333;RequestMapping 使⽤&#x1f332;RequestMapping 是GET还是POST请求&#xff1f;&#x1f6a9;使用Postman构造POST请求 ⭕总结 &#x1f384;什么是RequestMapping 注解 在Spring MVC 中使⽤ RequestMapping 来…

EasyNTS端口穿透服务新版本发布 0.8.7 增加隧道流量总数记录,可以知晓设备哪个端口耗费流量了

EasyNTS上云平台可通过远程访问内网应用&#xff0c;包含网络桥接、云端运维、视频直播等功能&#xff0c;极大地解决了现场无固定IP、端口不开放、系统权限不开放等问题。平台可提供一站式上云服务&#xff0c;提供直播上云、设备上云、业务上云、运维上云服务&#xff0c;承上…

m3u8网络视频文件下载方法

在windows下&#xff0c;使用命令行cmd的命令下载m3u8视频文件并保存为mp4文件。 1.下载ffmpeg&#xff0c;访问FFmpeg官方网站&#xff1a;https://www.ffmpeg.org/进行下载 ffmpeg下载&#xff0c;安装&#xff0c;操作说明 https://blog.csdn.net/m0_53157282/article/det…

用通俗易懂的方式讲解大模型:使用 FastChat 部署 LLM 的体验太爽了

之前介绍了Langchain-Chatchat 项目的部署&#xff0c;该项目底层改用了 FastChat 来提供 LLM(大语言模型)的 API 服务。 出于好奇又研究了一下 FastChat&#xff0c;发现它的功能很强大&#xff0c;可以用来部署市面上大部分的 LLM 模型&#xff0c;可以将 LLM 部署为带有标准…

精品Nodejs实现的校园疫情防控管理系统的设计与实现健康打卡

《[含文档PPT源码等]精品Nodejs实现的校园疫情防控管理系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Win…

uniapp中uview组件库丰富的Calendar 日历用法

目录 基本使用 #日历模式 #单个日期模式 #多个日期模式 #日期范围模式 #自定义主题颜色 #自定义文案 #日期最大范围 #是否显示农历 #默认日期 基本使用 通过show绑定一个布尔变量用于打开或收起日历弹窗。通过mode参数指定选择日期模式&#xff0c;包含单选/多选/范围…

gitlab 11.11.8的备份与恢复及500错误的修复

gitlab已经集成了非常方便的备份和恢复命令&#xff0c;只要我们执行这些命令就能完成gitlab的备份与恢复了。 我想gitlab备份与恢复的目的无非就是将已经运行了很久的旧的gitlab服务&#xff0c;迁移到新的服务器上。如果你旧的gitlab上项目很少&#xff0c;就需要考虑迁移服…

基于ElementUI二次封装el-table与el-pagination分页组件[实际项目使用]

效果&#xff1a; 二次封装el-table组件 <template><div><!-- showHeader:是否显示头部size:表格的大小height:表格的高度isStripe:表格是否为斑马纹类型tableData:表格数据源isBorder:是否表格边框handleSelectionChange:行选中&#xff0c;多选内容发生变化回…

基于虚拟机ubuntu的linux和shell脚本的学习,以及SSH远程登陆实战

简介 特点 是一款操作系统,跟windows,macos一样,有下面的特点 简单和高效,一切皆文件,所有配置都通过修改文件解决,不需要繁琐的权限和设置 权限高,把所有细节都交给用户,可完全自定义 安全,所有程序只有自己执行才会启动 分类 1、debian系主要有Debian&#xff0c;Ubun…

yolov8实战第四天——yolov8图像分类 ResNet50图像分类(保姆式教程)

yolov8实战第一天——yolov8部署并训练自己的数据集&#xff08;保姆式教程&#xff09;_yolov8训练自己的数据集-CSDN博客在前几天&#xff0c;我们使用yolov8进行了部署&#xff0c;并在目标检测方向上进行自己数据集的训练与测试&#xff0c;今天我们训练下yolov8的图像分类…