首页 > 其他分享 >深入理解指针(4)(上)

深入理解指针(4)(上)

时间:2024-08-31 21:24:19浏览次数:6  
标签:arr int 元素 数组名 地址 理解 深入 数组 指针

3abea50b9066429d84133aad1c0112e2.png

目录:

1. 数组名的理解

2. &数组名的理解

3.使用指针访问数组

4.一维数组传参的本质


1.数组名的理解

上一章我们在模拟strlen函数时,使用了数组名进行了函数的传参,那么数组名到底意味着什么呢?

#include<stdio.h>
int main()
{
    int arr[5] = {1,2,3,4,5};
    int *p = &arr[0];
}

当我们使用&arr[0]时,我们会将数组首元素的地址取出来

那我们将数组名的地址打印出来呢?

c1fc8c8e984d4f2eb505ac8de97469d9.png

即使没有取出数组名的地址,系统也并没有报错,打印出来的地址还是和首元素地址一样

难到数组名就是地址吗?

没错,数组首元素的地址和数组名就是一样的,其实数组名本身就是地址,而且就是数组首元素的地址

什么?!!那arr[0],该怎么理解,地址[0]是什么鬼?

其实,arr[0]的含义是 *(arr+0) ,这样得到的数组首元素的值

结论:

数组名就是一个地址

数组名就是数组首元素(第一个元素)的地址


2.&数组名的理解

疑问时刻:

数组名是首元素的地址,那把数组名的地址取出来后,得到的是什么呢?

c89639b640044074a6f539687ee9723d.png

我们可以看到,无论是打印arr[0]的地址,还是打印arr,还是&arr的地址,它们的地址都是一样的

但其实&arr是与另外两者有区别的,&arr取出的其实是整个数组的地址,但是只是显示出数组首元素的地址

实测如下:

071bd3d366d848b5a5a8a1d05912a162.png

我们会发现,arr与arr[0],它们加1后跳过了4个字节

但是 &arr+1 后 打印出的地址跳过了20个字节,也就是整个数组的大小

其实 &arr+1后,打印出的地址跳过了一整个数组

这就是它们的区别

结论:

arr与arr[0]都是数组首元素的地址,并且它们的含义一样

但是&arr取出的是首个元素的地址


 

 

2.1数组名的两个意外(重要结论)

关于数组名使用的两个例外(其他所有数组名都为首元素地址)

1.sizeof(数组名)

当我们使用sizeof(数组名)时,这里的数组名表示整个数组,因此测量的是整个数组的字节大小

2.&数组名

这里的数组名表示整个数组,取出的是整个数组的地址


3.使用指针访问数组

既然数组名可以表示首元素地址,那么我们可不可以用数组名进行整个数组的访问呢?

其实是可以的,比如:

3e7f99e09af2412292124ceff54cd0e5.png

这样我们既可以实现输入,也可以实现输出,同时使用(p+i)可以更加的节省代码与内存空间

否则就需要定义一个新的指针变量或者重新定义指针变量的值

比如:

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

	for (int i = 0; i < 5; i++) {
		scanf("%d",&*(p));
        p++;	
	}
    
    p = arr;

	for (int i = 0; i < 5; i++) {
		printf("%d ", *(p + i));
	}
}

我们知道arr是数组首元素的地址,arr[0]可以访问数组首元素,那么把arr存放在指针变量中,可以利用这个指针变量访问到数组的元素吗?
其实是可以的,比如:

c174e55770ac47e680d6c28ba89a42d1.png

其实我们在使用数组时,arr就一直都是地址,只不过我们现在才发现

既然arr是地址,那么之前所学的访问的方式依旧成立


4.一维数组传参的本质

在上一章中,我们利用数组名进行了函数的传参

那么传过去的是什么呢?

我们可以做个代码验证一下,比如:

9975e369bf824b44ad60784f01574618.png

我们发现,利用函数将数组名传过去,用指针变量进行接受时系统并没有报错,说明得到的是一个地址,并且这个地址和我们优先进行打印的数组首元素地址一样

结论:

可见,一维数组传参本质上传递的也是地址


2d109cecd199439e9dedb086d751bad2.png

 

标签:arr,int,元素,数组名,地址,理解,深入,数组,指针
From: https://blog.csdn.net/2301_80349538/article/details/141609928

相关文章

  • 深入解析:如何在复杂 C++ 项目中高效集成 CMake 和 Conan
    目录标题第一章:C++项目中的Conan和CMake基础架构1.1项目架构概述1.2CMake与Conan的基本角色1.2.1CMake的角色1.2.2Conan的角色1.3在项目中合理结合使用CMake和Conan1.4实例分析1.5结语第二章:C++项目中的CMake和Conan实践2.1项目结构概览......
  • 深入解析 Go 中 Map
    0前言Go语言中的map是一种内建的数据结构,用于存储键值对。它类似于其他编程语言中的哈希表或字典,提供了快速的插入、删除和查找操作。本文将深入浅出介绍map基本概念、使用方式、核心原理、性能以及最佳实践,帮助读者更好的理解和使用map。如果您觉得有帮助,请关注我,另......
  • 深入解析 Go 中 Slice
    0前言slice是一种灵活且强大的数据结构,它在功能上类似于其他编程语言中的数组,但提供了更多的灵活性。与数组不同,slice允许动态调整长度,使其在大多数场景中更加适用。本文将深入解析slice的基本概念及底层实现原理,并通过分析一些面试中常见的易错题,加深对slice的理......
  • Swift concurrency 6 — TaskGroup的理解与使用
    在SwiftUI中,TaskGroup是一种处理并发任务的工具,特别适用于需要并发执行多个独立任务并在它们都完成后进行进一步处理的场景。TaskGroup提供了一种结构化并发的方法,使得并行任务的启动、管理和结果收集变得更加简便和安全。一、TaskGroup的基本概念TaskGroup是Swift并......
  • kerberos 认证流程-理解
    kerberos认证理解一、认证过程1)AS-REQ(请求)域内的用户向KDC(域控服务器)发送请求包,告诉域控,我要获得访问服务的票据。请求包:用户名,主机名,认证因子Authenticator(由客户端用户hash加密的时间戳等信息),其他信息2)AS-REP(响应)KDC接受到客户端的请求包。KDC判断用户是不是......
  • 深入解析多商户商城系统源码:如何开发直播商城小程序?
    本篇文章,小编将深入解析多商户商城系统源码的关键技术,并详细探讨如何基于这些源码开发一个功能完善的直播商城小程序。一、多商户商城系统源码的核心构架多商户商城系统源码的核心在于其能够支持多个商户独立运营,但同时又在一个统一的平台上实现数据的共享与整合。这个系统的核心构......
  • 多线程编程(面试重中之中,超简单理解)
    最近项目比较紧急,固本之旅卡顿了一段时间,抽时间看了一下多线程,面试重点知识!!!多线程编程优点:提高程序的响应速度,增加用户的体验;提高计算机系统CPU的利用率;优化程序结构,将一个复杂的单线程分化成多个清晰化的单线程,更有利于维护并行指两个以上的事物在同一时刻同时发......
  • 08.类:更深层次的理解
    8.类:更深层次的理解8.1接口与实现分离我们的每个先前的类定义示例都将一个类放在一个头文件中进行重用,然后将类的定义包含到一个包含main的源代码文件中,这样我们就可以创建和操作类的对象。传统的思想认为,使用类的一个对象,客户(例如main函数)只需要知道:1.调用什么成员函数......
  • 07.指针
    7.指针指针也允许pass-by-reference,并且可以用来创造和操作动态数据结构,例如列表、队列、栈和树(lists,queues,stacksandtrees)。7.1指针变量的声明和初始化指针变量包含内存地址作为其值,指针包含变量的内存地址,而变量的内存地址又包含一个特定的值。在这个意义上,变量名直......
  • 3.从对变量的理解到数据类型的一种解释
    1变量1.1变量在使用过程中有三点注意事项1.变量必须是字母数字和下划线组成2.变量的命名开头不能是数字,数字会与python中的数字重复,导致错误3.变量不能使用内置的字,如print1.2变量的规范1.一般情况下需要进行分割,就是用_2.变量在使用的过程中也要注意,不要乱命名,会导致后续......