深⼊理解指针1(指针和数组)

⽬录

1. 数组名的理解

2. 使⽤指针访问数组

3. ⼀维数组传参的本质

4. 冒泡排序

5. ⼆级指针

6. 指针数组

7. 指针数组模拟⼆维数组

正文开始:

1.数组名的理解

首先我们已经知道应该如何用指针来访问数组

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 0 };int* p = &arr[0];return 0;
}

这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且是数组⾸元素的地址 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 0 };int* p = &arr[0];printf("arr[0] = %p\n", &arr[0]);printf("arr    = %p\n", arr);return 0;
}

 我们发现数组名和数组⾸元素的地址打印出的结果⼀模⼀样,数组名就是数组⾸元素(第⼀个元素)的地址

那么这里就会产生一个疑问:

如果arr是数组⾸元素的地址,那输出应该的应该是4/8才对,这里为什么会打印40?

这里是因为有两个特殊情况:

sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节

&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的) 

这里打印出的三个地址都是一样的,那么我们进一步探究一下: 

  这里我们发现&arr[0]和arr都只跳过了一个·字节,而&arr代表的是整个数组的地址,+1会跳过整个数组

2. 使⽤指针访问数组

接下来我们会实现用指针来访问数组

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 0 };int i = 0;int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0;i < sz;i++){scanf("%d", p + i);}for (i = 0;i < sz;i++){printf("%d ", *(p + i));}return 0;
}

另外因为arr和p装的都是数组首元素地址,所以我们把p换成arr也可以

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 0 };int i = 0;int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0;i < sz;i++){scanf("%d", arr + i);}for (i = 0;i < sz;i++){printf("%d ", *(arr + i));}return 0;
}

同样我们换成p[i]也可以正产打印

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr[10] = { 0 };int i = 0;int* p = arr;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0;i < sz;i++){scanf("%d", arr + i);}for (i = 0;i < sz;i++){printf("%d ", p[i]);}return 0;
}

综上,我们可以得到四种写法

p[i] = arr[i] = *(p+i) = *(arr+i) 

拓展:

根据加法之间的交换律,我们可以把 *(arr+i) 写成 *(arr+i) ,因此我们就可以吧arr[i]写成i[arr],虽然看起来有些奇怪,但同样可以得到正确的编译结果

这种方法可行,但是不推荐

所以本质上p[i] 是等价于 *(p+i)。同理arr[i] 应该等价于 *(arr+i),数组元素的访问在编译器处理的时候,也是转换成⾸元素的地址+偏移量求出元素的地址,然后解引⽤来访问的。

注意

1.数组就是数组是一块连续的空间()

2.指针(变量)就是指针(变量),大小为4字节或者8字节

3.数组名是地址,是首元素的地址

4.可以用指针来访问数组

3. ⼀维数组传参的本质.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void Print(int arr[10], int sz)
{int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);Print(arr, sz);return 0;
}

这是我们之前数组传参来打印数组的写法,但是我们来看下一种写法

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void Print(int arr[10])
{int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };Print(arr);return 0;
}

结果显示是错误的,这是为什么呢?

其实我们知道数组在传参时传递的是数组名arr,也就是数组首元素的地址,所以在进行sizeof(arr)计算时计算的是⼀个地址的⼤⼩(单位字节)⽽不是数组的⼤⼩(单位字节),正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。

既然传递的时数组首元素地址是我们就也可以采用指针来接收。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//void Print(int arr[10])
//{
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int i = 0;
//	for (i = 0;i < sz;i++)
//	{
//		printf("%d ", arr[i]);
//	}
//}
void Print(int* arr, int sz)
{int i = 0;for (i = 0;i < sz;i++){printf("%d ", *(arr + i));}
}
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int sz = sizeof(arr) / sizeof(arr[0]);Print(arr, sz);return 0;
}

所以我们可以得到一个结论:

1.数组传参的本质是传递了数组首元素地址的,所以形参访问的数组是和实参的数组是一样的

2.形参的数组是不会再单独创建空间的,所以形参的数组是可以省略大小的

4. 冒泡排序

冒泡排序的核⼼思想就是:两两相邻的元素进⾏⽐较

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void bubble_sort(int arr[10], int sz)
{int i = 0;//趟数for (i = 0;i < sz - 1;i++){int j = 0;//每一趟比较多少次for (j = 0;j < sz - 1 - i;j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}
int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}return 0;
}

优化:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void bubble_sort(int arr[10], int sz)
{int i = 0;//趟数for (i = 0;i < sz - 1;i++){int j = 0;//假设已经有序了int flag = 1;//每一趟比较多少次for (j = 0;j < sz - 1 - i;j++){if (arr[j] > arr[j + 1]){int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;flag = 0;}}if (flag == 1){break;}}
}
int main()
{int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr, sz);int i = 0;for (i = 0;i < sz;i++){printf("%d ", arr[i]);}return 0;
}

 5. ⼆级指针

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int a = 10;int* p = &a;//p是一级指针int** pp = &p;//pp是二级指针return 0;
}

 6. 指针数组

首先我们要知道指针数组是数组,整形数组存放的整形,字符数组存放的是字符,那么指针数组存放的就是指针

 

7. 指针数组模拟⼆维数组 

 

 

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 2,3,4,5,6 };int arr3[] = { 3,4,5,6,7 };int* arr[] = {arr1,arr2,arr3};int i = 0;for (i = 0;i < 3;i++){int j = 0;for (j = 0;j < 5;j++){printf("%d ", arr[i][j]);}printf("\n");}return 0;
}

arr[i] = *(arr+i)

arr[j] = *(arr+j)

完!!!

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

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

相关文章

Pytest中doctests的测试方法应用

在 Python 的测试生态中,Pytest 提供了多种灵活且强大的测试工具。其中,doctests 是一种独特而直观的测试方法,通过直接从文档注释中提取和执行测试用例,确保代码示例的正确性。本文将深入介绍 Pytest 中 doctests 的测试方法,包括基本用法和实际案例,以帮助你更好地利用…

Task05:PPO算法

本篇博客是本人参加Datawhale组队学习第五次任务的笔记 【教程地址】https://github.com/datawhalechina/joyrl-book 【强化学习库JoyRL】https://github.com/datawhalechina/joyrl/tree/main 【JoyRL开发周报】 https://datawhale.feishu.cn/docx/OM8fdsNl0o5omoxB5nXcyzsInGe…

微服务—RabbitMQ

目录 初识MQ 同步和异步通讯 同步通讯的优缺点 异步调用方案 异步通信优缺点 常见MQ技术对比 RabbitMQ快速入门 安装RabbitMQ RabbitMQ整体架构与相关概念 常见消息模型​编辑 入门案例 SpringAMQP 基本介绍 SpringAMQP案例——模拟HelloWorld消息模型 Sprin…

如何在Shopee平台上进行手机类目选品?

在Shopee平台上进行手机类目的选品是一个关键而复杂的任务。卖家需要经过一系列的策略和步骤&#xff0c;以确保选品的成功和销售业绩的提升。下面将介绍一些有效的策略&#xff0c;帮助卖家在Shopee平台上进行手机类目选品。 先给大家推荐一款shopee知虾数据运营工具知虾免费…

ffmpeg合成mp3音频,解决音频属性不一致问题

1. 需求&#xff0c;amr转成mp3&#xff0c;再将此mp3和其他mp3合成 2. 问题&#xff1a;拼接后的第一段音频可以播放&#xff0c;第二段自动跳过&#xff0c;无法播放。 3. 解决&#xff1a; 3.1 查看各文件属性 # 查看amr转为mp3文件的属性&#xff1a;ffprobe 文件名&am…

Pytorch从零开始实战18

Pytorch从零开始实战——人脸图像生成 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——人脸图像生成环境准备模型定义开始训练可视化总结 环境准备 本文基于Jupyter notebook&#xff0c;使用Python3.8&#xff0c;Pytorch2.0.1cu118&#…

[力扣 Hot100]Day20 旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在原地旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 出处 思路 旋转时每四个位置为一组进行swap操作&#xff0c;找好对…

【蓝桥杯51单片机入门记录】LED

目录 一、基础 &#xff08;1&#xff09;新建工程 &#xff08;2&#xff09;编写前准备 二、LED &#xff08;1&#xff09;点亮LED灯 &#xff08;2&#xff09;LED闪烁 延时函数的生成&#xff08;stc-isp中生成&#xff09; 实现 &#xff08;3&#xff09;流水灯…

OpenHarmony—开发及引用动态共享包

对于企业大型应用开发&#xff0c;有部分公共的资源和代码&#xff0c;只能在开发态静态共享&#xff0c;并且打包到每个依赖的HAP里&#xff0c;这样导致包体积较大&#xff0c;且有重复多份公共资源和代码重复打包到应用中。 为了解决运行态状态无法共享&#xff0c;以及减少…

2024美赛B题保姆级分析完整思路代码数据教学

2024美国大学生数学建模竞赛B题保姆级分析完整思路代码数据教学 B题&#xff1a;Searching for Submersibles 搜索潜水器 从给定的背景信息中&#xff0c;我们知道MCMS是一家位于希腊的公司&#xff0c;他们制造能够将人类运送到海洋深处的潜水艇。他们现在希望使用他们的潜水…

UML---用例图,类图

用例图 用例图&#xff08;Use Case Diagram&#xff09;主要描述系统的功能需求和参与者与系统之间的交互。它是用户与系统交互的最简表示形式&#xff0c;展现了用户和与他相关的用例之间的关系。用例图被视为系统的蓝图&#xff0c;通过它&#xff0c;人们可以获知系统不同种…

C语言·贪吃蛇游戏(下)

上节我们将要完成贪吃蛇游戏所需的前置知识都学完了&#xff0c;那么这节我们就开始动手写代码了 1. 程序规划 首先我们应该规划好我们的代码文件&#xff0c;设置3个文件&#xff1a;snack.h 用来声明游戏中实现各种功能的函数&#xff0c;snack.c 用来实现函数&#xff0c;t…

C# 根据USB设备VID和PID 获取设备总线已报告设备描述

总线已报告设备描述 DEVPKEY_Device_BusReportedDeviceDesc 模式 winform 语言 c# using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Window…

2024美赛数学建模C题思路分析 - 网球的动量

1 赛题 问题C&#xff1a;网球的动量 在2023年温布尔登绅士队的决赛中&#xff0c;20岁的西班牙新星卡洛斯阿尔卡拉兹击败了36岁的诺瓦克德约科维奇。这是德约科维奇自2013年以来首次在温布尔登公开赛失利&#xff0c;并结束了他在大满贯赛事中历史上最伟大的球员之一的非凡表…

hivesql的基础知识点

目录 一、各数据类型的基础知识点 1.1 数值类型 整数 小数 float double(常用) decimal(针对高精度) 1.2 日期类型 date datetime timestamp time year 1.3 字符串类型 char varchar / varchar2 blob /text tinyblob / tinytext mediumblob / mediumtext lon…

EtherCAT FP介绍系列文章—UDP gateway

EtherCAT主站上的Mailbox Gateway功能&#xff0c;可以用于将EtherCAT mailbox相关协议从外部设备的工具通过邮箱网关路由到EtherCAT从站设备。在EtherCAT规范中定义的所有邮箱协议在此功能中都可用&#xff0c;例如CoE, FoE, VoE, SoE。 但是&#xff0c;这里特别注意的是Mai…

2024美赛数学建模E题思路分析 - 财产保险的可持续性

1 赛题 问题E&#xff1a;财产保险的可持续性 极端天气事件正成为财产所有者和保险公司面临的危机。“近年来&#xff0c;世界已经遭受了1000多起极端天气事件造成的超过1万亿美元的损失”。[1]2022年&#xff0c;保险业的自然灾害索赔人数“比30年的平均水平增加了115%”。[…

【STM32F103单片机】利用ST-LINK V2烧录程序 面包板的使用

1、ST‐LINK V2安装 参考&#xff1a; http://t.csdnimg.cn/Ulhhq 成功&#xff1a; 2、烧录器接线 背后有标识的引脚对应&#xff1a; 3、烧录成功 烧录成功后&#xff0c;按下核心板的RESET键复位&#xff01;&#xff01;&#xff01;即可成功&#xff01; 4、面包板的…

2024美赛数学建模D题思路源码

赛题目的 赛题目的&#xff1a; 问题描述&#xff1a; 解题的关键&#xff1a; 问题一. 问题分析 问题解答 问题二. 问题分析 问题解答 问题三. 问题分析 问题解答 问题四. 问题分析 问题解答 问题五. 问题分析 问题解答

2024美赛数学建模E题:房产保险的可持续性,思路全解,代码模型分析

2024美赛数学建模E题思路全解&#xff0c;代码模型分析,完整详细内容见文末名片 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 保险公司应该在承保保单时考虑多种因素&#xff0c;以确保公司的长期健康和稳定性。以下是一个可能的模式&#xff0c;以确…