指针浅谈(三)

     在指针浅谈(二)http://t.csdnimg.cn/SKAkD中我们讲到了const修饰指针、指针运算、野指针、assert断言和传址调用的内容,今天我们继续学习有关数组名、指针访问数组、一维数组传参的本质相关的内容,内容比较深入,如果觉得哪里讲解的不行,可以参考其他大佬的文章呦。

1.数组名的理解

     在之前我们使用指针访问数组时,有以下代码:

int arr[10]={1,2,3,4,5,6,7,8,9,10};
int* p=&arr[0];

     这里&arr[0]表示取出数组第一个元素的地址赋给指针变量p,但是你看下面这个代码和运行结果:

#include<stdio.h>
int main()
{
   int arr[10]={1,2,3,4,5,6,7,8,9,10};
   printf("&arr[0]=%p\n",&arr[0]);
   printf("arr=%p",arr);
   return 0;
}

     你会神奇的发现,wc,这出错了吧,这怎么可能,数组名的地址怎么能和数组第一个元素的地址相同呢?但事实上,数组名就是数组首元素的地址。

      这时候倘若我放出下面这段代码,阁下该如何应对?

#include <stdio.h>
int main()
{
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 printf("%d\n", sizeof(arr));
 return 0;
}

       我直接懵逼了,到底哪个是对的?其实两个都是对的,数组名确实是数组首元素的地址,但在两个情况下是例外的:

 (1)sizeof(数组名):sizeof中放数组名,数组名表示整个数组,计算整个数组的大小。

 (2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址,这和首元素的地址是有区别的。区别就在于下面这段代码

#include <stdio.h>
int main()
{
 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
 printf("&arr[0] = %p\n", &arr[0]);
 printf("&arr[0]+1 = %p\n", &arr[0]+1);
 printf("arr = %p\n", arr);
 printf("arr+1 = %p\n", arr+1);
 printf("&arr = %p\n", &arr);
 printf("&arr+1 = %p\n", &arr+1);
 return 0;
}

     我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1相差4个字节,这是我们意料之中的,毕竟数组名是数组首元素的地址,但&arr和&arr+1相差40个字节,这是因为&arr是数组的地址,+1之后直接跳过整个数组,虽然它和数组首元素地址相同,但区别就在于指针+-运算跳过的多少。

     总的来说,数组名是数组首元素的地址,但是有sizeof和&数组名两个意外。

2.使用指针访问数组

     讲的是指针,那我们就要用指针,已经知道了这么多关于数组的知识,就应该学习如何用指针访问数组。

#include <stdio.h>
int main()
{
 int arr[10] = {0};
 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);//也可以这样写
 //scanf("%d", arr[i]);
 //scanf("%d", p[i]);
 }
 //输出
 for(i=0; i<sz; i++)
 {
 printf("%d ", *(p+i));
 printf("%d ", p[i]);//或者这样写
 printf("%d ", arr[i]);
 }
 return 0;
}

      这段代码怎么理解呢?其实并不难,将数组首元素的地址赋给了指针变量p,那我们就可以访问整个数组,毕竟数组是一段连续的存储空间,知道了首元素地址,就可以顺藤摸瓜找到其他元素,运用指针运算,遍历整个数组进行赋值,因为数组首元素也是地址,相当于一个指针,所以也可以写成arr+i,等价于arr[i]。其实数组名arr和p在这里等价,所以也可以是p[i],输出时,我们需对指针变量解引用获取元素值即可。

3.一维数组传参的本质

     我们知道数组是可以传递给函数的,那数组是把自己所有元素全部传过去吗?显然不是,在早期的计算机设备中,内存是很小的,如果一下传很多元素过去,会很占用内存,效率低下,那数组是怎么传过去呢?下面就让我们了解一下。

     之前我们都是在函数外部计算数组的元素个数,那能不能在函数内部进行求解呢?

#include <stdio.h>
void test(int arr[])//形参也可以写成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;
}

     我们发现其实并不能这样做,这时候就要学习数组传参的本质了,刚才学到数组名是数组首元素的地址,那传参传的是数组名,也就是说本质上数组传参传递的是数组首元素的地址。

     所以函数形参应该使用指针变量来接收首元素地址,那我们在函数内部写sizeof(arr)计算的是一个地址的大小,不是数组的大小,正是因为这样,我们在函数内部是没有办法求数组元素个数的。

     今天的指针先讲到这里,下期再见!

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

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

相关文章

Java EE 多线程之线程安全的集合类

文章目录 1. 多线程环境使用 ArrayList1. 1 Collections.synchronizedList(new ArrayList)1.2 CopyOnWriteArrayList 2. 多线程环境使用队列2.1 ArrayBlockingQueue2.2 LinkedBlockingQueue2.3 PriorityBlockingQueue2.4 TransferQueue 3. 多线程环境使用哈希表3.1 Hashtable3.…

QT----第三天,Visio stdio自定义封装控件

目录 第三天1 自定义控件封装 源码&#xff1a;CPP学习代码 第三天 1 自定义控件封装 新建一个QT widgetclass&#xff0c;同时生成ui,h,cpp文件 在smallWidget.ui里添加上你想要的控件并调试大小 回到mainwidget.ui&#xff0c;拖入一个widget&#xff08;因为我们封装的也…

jemeter,断言:响应断言、Json断言

一、响应断言 接口A请求正常返回值如下&#xff1a; {"status": 10013, "message": "user sign timeout"} 在该接口下创建【响应断言】元件&#xff0c;配置如下&#xff1a; 若断言成功&#xff0c;则查看结果树的接口显示绿色&#xff0c;若…

maui 开发音乐播放APP 优化(2)

界面改为&#xff1a; 音量可以调整 。同时当前状态 显示。以及播放音乐.视频有时可以自动播放有时候要手动。 界面代码 <?xml version"1.0" encoding"utf-8" ?> <ContentPage xmlns"http://schemas.microsoft.com/dotnet/2021/maui&quo…

MySQL的事务以及springboot中如何使用事务

事务的四大特性&#xff1a; 概念&#xff1a; 事务 是一组操作的集合&#xff0c;它是不可分割的工作单元。事务会把所有操作作为一个整体&#xff0c;一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 注意&#xff1a; 默认MySQ…

最新UI酒桌喝酒游戏小程序源码,直接上传源码到开发者端即可,带流量主

源码介绍&#xff1a; 2023最新UI酒桌喝酒游戏小程序源码 娱乐小程序源码 带流量主.修改增加了广告位&#xff0c;直接上传源码到开发者端即可。 通过后改广告代码&#xff0c;然后关闭广告展示提交&#xff0c;通过后打开即可。无广告引流。 流量主版本的&#xff08;配合流…

proteus元件合集(一)

LCD LM018L​​ 绿色的LCD寻找方法&#xff1a; 直流电压源 直流电压源寻找方法&#xff1a; 滑动变阻器 滑动变阻器寻找方法&#xff1a; 注意&#xff1a;它出来之后会自动出现那两个红色的。那是电源。

崩坏:星穹铁道【V1.5攻略】五星(金)-遗器主、副词条成长数值参考

星穹铁道中五星遗器词条成长数值攻略&#xff1a; 温馨提示&#xff1a;以下数据会可能会出现一点一点误差&#xff0c;见谅... --------------------------- 一、如图&#xff1a; ----->>细节补充<<----- ①实际数值可能与游戏中不一&#xff0c;若数据出现无法忽…

详解Java中的异常体系结构(throw,throws,try-catch,finally,自定义异常)

目录 一.异常的概念 二.异常的体系结构 三.异常的处理 异常处理思路 LBYL&#xff1a;Look Before You Leap EAFP: Its Easier to Ask Forgiveness than Permission 异常抛出throw 异常的捕获 提醒声明throws try-catch捕获处理 finally的作用 四.自定义异常类 一.异…

深入理解亚信安慧AntDB-T数据库子计划的执行流程

概要&#xff1a; SQL语句在执行时会转换为执行计划&#xff0c;若其中包含了子查询或子链接并且不能被优化&#xff0c;则执行计划会生成子计划&#xff08;查看AntDB的执行计划时看到标记为SubPlan[1] 的部分即为子计划&#xff09;。在整个AntDB数据库中&#xff0c;子计划…

现代C++ 实现单例模式

传统写法有什么问题 如果你了解过单例模式&#xff0c;双重检查锁定模式&#xff08;Double-Checked Locking Pattern&#xff0c;后文简称DCLP&#xff09;的写法你一定不会陌生&#xff0c;甚至你或许认为它是最正确的代码。 class Singleton { public://获取单例Singleton…

MySQL 8.x temp空间不足问题

目录 一、系统环境 二、问题报错 三、问题回顾 四、解决问题 一、系统环境 系统Ubuntu20.04 数据库版本MySQL 8.0.21 二、问题报错 在MySQL上执行一个大的SQL查询报错Error writing file /tmp/MYfd142 (OS errno 28 - No space left on device) Exception in thread …

用C语言实现链队列的基本操作

不多解释&#xff0c;直接上代码&#xff0c;代码已经写了注释&#xff01; //队列链式结构的基本操作&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int QueueElememtType; typedef struct QNode//链队的定义 {…

什么是蜘蛛池,蜘蛛池是什么蚂蚁SEO

蜘蛛池是一种通过大量模拟真实用户行为来提升网站搜索引擎排名的技术。这种技术利用大量的网络爬虫程序&#xff0c;模拟搜索引擎蜘蛛的爬行行为&#xff0c;通过大量的模拟爬行和页面抓取&#xff0c;提高网站的权重和排名。 如何联系蚂蚁seo&#xff1f; baidu搜索&#xf…

如何查看自己的文章是否被数据库收入?【查收查引】

致谢&#xff1a;特别感谢图书馆的蔡老师&#xff0c;告诉我怎么操作&#xff01; 另外&#xff0c;查收查引报告中的文章可以分开开&#xff0c;放在一起开不是必须的。&#xff08;放在一起开大概是院士工作量需要的。不是很了解。&#xff09; 如何查看自己的文章是否被数据…

杰发科技AC7840——CAN通信简介(1)

简介 7840支持4路CAN-FD Demo调试 官网下载demo&#xff0c;烧录&#xff0c;打开串口发现打印如下。原因是没有连接CAN盒子&#xff0c;总线错误。 CAN收发器端波形 CAN_L有信号&#xff0c;CAN_H没有 波形放大 GPIO端波形 有持续波形输出 波形放大查看&#xff0c;有50U…

.NET 反射优化的经验分享

比如针对 GetCustomAttributes 通过反射获取属性的优化,以下例子 // dotnet run -c Release -f net7.0 --filter "*" --runtimes net7.0 net8.0public class Tests{public object[] GetCustomAttributes() => typeof(C).GetCustomAttributes(typeof(MyAttribute…

如何快速将图片转为excel?

一、打开金鸣表格文字识别软件。 二、点击添加文件按钮&#xff0c;在打开的窗口中选择目标图片&#xff0c;然后点击“打开”&#xff0c;将图片添加进待识别的列表中。 三、点击提交识别或识别全部。 四、识别完成后点击“打开文件”即可打开识别好的结果文件&#xff08;EXC…

Enabling Application Engine Tracing 启用应用程序引擎跟踪

Enabling Application Engine Tracing 启用应用程序引擎跟踪 By default, all Application Engine traces are turned off. To see a trace or a combination of traces, set trace options before you run a program. 默认情况下&#xff0c;所有应用程序引擎跟踪都处于关闭…

Python学习笔记(四):函数的定义、函数的返回值、None类型、函数说明文档、函数的嵌套调用、局部变量、全局变量、global关键字

目录 一、函数介绍 1. 函数是&#xff1a; 2. 使用函数的好处是&#xff1a; 二、函数的定义&#xff1a; 三、函数的参数 1.传入参数的功能是&#xff1a; 2.函数的传入参数 - 传参定义 3.注意事项&#xff1a; 4.练习&#xff1a;测量体温 四、函数的返回值 1.函数…