【C语言】指针剖析(2)

©作者:末央&

©系列:C语言初阶(适合小白入门)
©说明:以凡人之笔墨,书写未来之大梦

在这里插入图片描述

目录

  • 一、数组名
    • 1.概念
    • 2.sizeof和&里面的数组名
      • sizeof
      • &
  • 二、使用指针访问数组
  • 三、一维数组传参本质
  • 四、指针数组
    • 1.概念
    • 实例(模拟二维数组)
  • 五、手脑并用

一、数组名

什么是数组名?例如以下

1.概念

int arr[10];
//arr就是数组名;

那么数组名在内存中的地址有什么特殊的地方吗,可以看看。
在这里插入图片描述

总结:数组名是数组首元素的地址,即arr[0]的地址

2.sizeof和&里面的数组名

这里相对于我们上面总结的可以理解"数组名是数组首元素的地址"是两个例外

sizeof

int arr[10];
printf("%d\n", sizeof(arr));

在这里插入图片描述

&

int arr[10];
printf("arr[0]%p\n", &arr[0]);
printf("arr   %p\n", &arr);

在这里插入图片描述
这里值得注意的是arr和arr[0]的地址是一样的,那么&arr和&arr[0]还有区别吗?我们不妨在上面基础上再修改一下代码。

int arr[10];
printf("arr[0]%p\n", &arr[0]+1);		
printf("arr   %p\n", &arr+1);

结合我们上期的知识,知道指针加减一个整数取决于他的指针类型,&arr[0]的指针类型是int,&arr的指针类型是一个数组指针(后期会讲),那么那么前者+1就是跳过一个int(4个字节),后者+1就是跳过一个数组(40个字节)
这里还要注意的是我们为什么可以进行直接的指针+1-1运算,因为我们数组在内存中是连续存放的,如果不是连续存放的就有可能访问到我们没有权限访问的空间。
在这里插入图片描述

总结:sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩, 单位是字节
&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素 的地址是有区别的)
除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。

二、使用指针访问数组

我们通常访问数组都是以数组下标的方式来访问数组的,例如:

	int arr[10] = { 0 };
	int i;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}


但是我们也可以这样写:

int arr[10] = { 0 };
int i = 0;
int* p = arr;
for (i = 0; i < 10; i++)
{
	printf("%d\n", p[i]);
}

为什么指针也可以替代数组名的位置了,其实不管是数组访问还是指针访问都可以化成这样的形式:*(数组名/指针变量名+变量/常量)
那也可以这样写:

int arr[10];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
//输⼊
int* p = arr;
for (i = 0; i < sz; i++)
{
	scanf("%d", p + i);
	//scanf("%d", arr+i);//也可以这样写
}
//输出
for (i = 0; i < sz; i++)
{
	printf("%d ", *(p + i));
}

i[p]和i[arr]也可以,编译器
会把数组名[变量]转换为*
(数组名+变量)形式这里的[变量]
相当于a+b中的+号如果是-变量则是减号,支持加
法交换律

三、一维数组传参本质

看以下代码
1.

void test(int arr[])
{
 int sz2 = sizeof(arr)/sizeof(arr[0]);		//特别注意这里
 printf("sz2 = %d\n", sz2);
}
int main()
{
 int arr[10] = {1,2,3,4,5,6,7,8,9,10};
 int sz1 = sizeof(arr)/sizeof(arr[0]);
 printf("sz1 = %d\n", sz1);
 test(arr);
 return 0;

在这里插入图片描述
为什么这里的sz2是1而不是和sz1一样是10呢,这就涉及到一维数组传参的问题了
我们刚刚在讲数组名的时候不是讲了除了sizeof和&里面的数组名以外,其他全是首元素地址。所有这里传参arr本质上就是传的首元素地址

又因为sizeof(arr) 计算的是⼀个地址的⼤⼩(单位字节)⽽不是数组的⼤⼩(单位字节)。正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。
所以首元素地址只有4个字节(int类型),4/4=1

四、指针数组

1.概念

指针数组到底是数组还是指针,指针是形容词数组是名词。所以指针数组本质上还是数组.其次整形数组是存放整形的数组,字符数组是存放字符的数组,那么指针数组实际上就是存放指针的数组
在这里插入图片描述

在这里插入图片描述

实例(模拟二维数组)

int arr1[] = {1,2,3,4,5};
 int arr2[] = {2,3,4,5,6};
 int arr3[] = {3,4,5,6,7};
 //数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
 int* parr[3] = {arr1, arr2, arr3};
 int i = 0;
 int j = 0;
 for(i=0; i<3; i++)
 {
 for(j=0; j<5; j++)
 {
 printf("%d ", parr[i][j]);
 }
 printf("\n");

在这里插入图片描述
要注意的是,上述代码只是模拟二维数组,实际上并不是真正的二维数组,因为他的行并不是连续存储的。而是通过指针找到每一行的首元素地址来进行访问。

再回忆一下我们之前说的p[i]=(p+i)这是一维数组用指针访问,那么二维数组是不是也可以触类旁通的写成:(*(arr+i)+j)

五、手脑并用

来来来,咱们直接上代码

nt main()
{
  int aa[2][5] = {10,9,8,7,6,5,4,3,2,1};
  int *ptr1 = (int *)(&aa + 1);
  int *ptr2 = (int *)(*(aa + 1));
  printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
  return 0;
}

小提示:这里明显涉及到我们上面讲的&数组面和前几篇文章讲的指针加减整数运算的概念问题。

好了,我们直接上图来看看吧
在这里插入图片描述
这里字有点丑哈,请谅解
那么结果就是:1 6

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C语言中常用的运算符、表达式和语句

C语言是一种通用的、高级的编程语言&#xff0c;其历史可以追溯到20世纪60年代末至70年代初。C语言最初是由丹尼斯里奇&#xff08;Dennis Ritchie&#xff09;在贝尔实验室为开发UNIX操作系统而设计的。它继承了许多B语言的特性&#xff0c;而B语言则是由迷糊老师&#xff08;…

C#基于SkiaSharp实现印章管理(3)

本系列第一篇文章中创建的基本框架限定了印章形状为矩形&#xff0c;但常用的印章有方形、圆形等多种形状&#xff0c;本文调整程序以支持定义并显示矩形、圆角矩形、圆形、椭圆等4种形式的印章背景形状。   定义印章背景形状枚举类型&#xff0c;矩形、圆形、椭圆相关的尺寸…

springboot宠物医院管理系统-计算机毕业设计源码07221

目 录 1 绪论 1.1 选题背景和意义 1.2国内外研究现状 1.3论文结构与章节安排 2 宠物医院管理系统系统分析 2.1 可行性分析 2.1.1技术可行性分析 2.1.2 操作可行性分析 2.1.3 法律可行性分析 2.2 系统功能分析 2.2.1 功能性分析 2.2.2 非功能性分析 2.3 系统用例分…

docker配置国内镜像加速器

1、搜索阿里云 2、搜索容器镜像服务 点击管理控制台 配置镜像加速器

uniapp部署服务器,uniapp打包H5部署服务器,uniapp将config.js抽离

目录 步骤一.在static文件夹下新建config.js文件 config.js文件说明 在config.js中放入使用的请求的接口地址,资源路径等 congfig.js中的变量在页面中如何使用 步骤二.manifest.json配置 1.在项目根目录(与app.vue同级)创建template.h5.html文件 2.在manifest.json配置刚刚创…

手机屏幕贴合项目(ni视觉如何找矩形的角坐标)

首先&#xff0c;我们存储了cg和dito感兴趣八个角图像的模板&#xff0c;用来匹配位置。 cover指的是cg的四个角模板&#xff0c;lcm是dito四个角匹配模板。 其次&#xff0c;我们采集的8副图像&#xff08;m_DlgCCDViewArr[2][4]&#xff09;中一定包含匹配模板的特征。 好&…

土体中应力的计算

土中的应力的计算 非水面以下土体中应力的计算&#xff1a;水面以下的土中的应力计算 参考视频&#xff1a; https://www.bilibili.com/video/BV1Rh411J72h/?spm_id_from333.788&vd_source02b2bad477a153eaeb9c48cbbedaf8df 非水面以下土体中应力的计算&#xff1a; 按成…

C++自定义智能指针

template <class T> class counted_ptr;// 智能指针引用计数类 template <class T> class Ref_Ptr {friend class counted_ptr<T>; private:T* m_pTtr; // 实际的指针size_t counted_ptr; // 引用计数Ref_Ptr(T* p);virtual ~Ref_Ptr(); };template <clas…

Golang | Leetcode Golang题解之第200题岛屿数量

题目&#xff1a; 题解&#xff1a; func numIslands(grid [][]byte) int {res : 0for i : 0; i < len(grid); i {for j : 0; j < len(grid[i]); j {if grid[i][j] 1 {resdfs(grid, i, j)}}}return res }func dfs(grid [][]byte, r, c int) {h, w : len(grid), len(gri…

标准版小程序订单中心path审核不通过处理教程

首先看自己小程序是不是已经审核通过并上线状态才在站内信里面提醒的&#xff1f; 如果没有提交过审核&#xff0c;请在提交的时候填写。path地址为&#xff1a;pages/goods/order_list/index 如果是已经上线的小程序&#xff0c;当时没要求填这个&#xff0c;但新的政策要求填…

如何通过Profile快速定位Doris查询瓶颈

1 如何获取profile 参考文档&#xff1a;https://doris.apache.org/zh-CN/docs/query/query-analysis/get-profile 我们时常遇到对应 SQL 执行时间不及预期的情况&#xff0c;为了优化 SQL 达到预期查询时延&#xff0c;通过 Profile 我们能够看出可以做哪些优化。现在说明在…

为何同一PDF文档用不同软件打印效果不同?

通过扫描仪生成的同一PDF文档&#xff0c;同样的设置&#xff0c;为什么别的电脑打出来是白底我的打出来有灰色格子背景&#xff1f;这种情况通常是由于PDF阅读软件的不同造成的差异。 ### 可能的原因和解决方法&#xff1a; 1. **PDF阅读软件的不同**&#xff1a; - **解决方…

小型光纤抗干扰无人机技术详解

一、光纤通信技术应用 光纤通信技术是现代通信技术的重要组成部分&#xff0c;其在小型无人机中的应用为无人机的数据传输带来了革命性的改变。光纤通信具有高速率、大带宽、低损耗和抗电磁干扰等优点&#xff0c;使得无人机在执行任务时能够实时传输高清图像、视频和大量数据…

[JS]BOM操作

介绍 BOM(Browser Object Model)是浏览器对象模型 window对象是一个全局对象, 也是JS中的顶级对象通过var定义在全局作用域中的变量和函数都会变成window对象的属性和方法window对象下的属性和方法调用时一般省略window 间歇函数 定时器 定时器是间歇函数的一种, 可以每个每…

《昇思25天学习打卡营第2天 | 昇思MindSpore张量 Tensor》

第二天学习 1.今天学习了张量 Tensor&#xff0c;了解到Tensor是一个可用来表示在一些矢量、标量和其他张量之间的线性关系的多线性函数&#xff0c;也是一个特殊的数据结构&#xff0c;与数组和矩阵非常相似。是MindSpore网络运算中的基本数据结构。学些了张量和稀疏张量的属性…

Node版本管理工具 fnm 安装使用

fnm 是一个基于 Rust 开发的 Node 版本管理工具&#xff0c;它的目标是提供一个快速、简单且可靠的方式来管理 Node.js 的不同版本。同时&#xff0c;它是跨平台的&#xff0c;支持 macOS、Linux、Windows。&#x1f680; Fast and simple Node.js version manager, built in R…

五十九周:文献阅读+FiLM

目录 摘要 Abstract 文献阅读&#xff1a;用于长时间序列预测的频率改进的勒让德记忆模型 一、现有问题 二、提出方法 三、相关知识 1、Legendre Projection&#xff08;Legendre投影&#xff09; 2、Fourier Transform&#xff08;傅立叶变换&#xff09; 四、提出的…

文件操作与管理

程序经常需要访问文件和目录&#xff0c;读取文件信息或写入文件信息&#xff0c;在Python语言中对文件的读写是通过文件对象&#xff08;file object&#xff09;实现的。Python的文件对象也称为类似文件对象或流&#xff08;stream&#xff09;&#xff0c;因为Python提供一种…

数据库-数据完整性-用户自定义完整性实验

NULL/NOT NULL 约束&#xff1a; 在每个字段后面可以加上 NULL 修饰符来指定该字段是否可以为空&#xff1b;或者加上 NOT NULL 修饰符来指定该字段必须填上数据。 DEFAULT约束说明 DEFAULT 约束用于向列中插入默认值。如果列中没有规定其他的值&#xff0c;那么会将默认值添加…

ProPainter – AI视频去水印工具,可以去除视频中的静态水印、动态物体/人物等 本地一键整合包下载

ProPainter是一个基于E2FGVI实现的AI视频编辑工具&#xff0c;它可以一键移除视频内的移动物体和水印。这个开源项目提供了一个简单而强大的解决方案&#xff0c;帮助用户轻松编辑和改善视频内容。 项目地址&#xff1a;https://github.com/sczhou/ProPainter 一键包下载&…