IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 从0开始学c语言-15-数组作为函数参数的地址、值与类型变化深度解析 -> 正文阅读

[C++知识库]从0开始学c语言-15-数组作为函数参数的地址、值与类型变化深度解析

本人0基础开始学编程,我能学会的,你也一定可以,学会多少写多少。

下载安装请从官网入手,社区版本即可,这里主要使用的软件是VS2019,图标如下。

?上一篇:从0开始学c语言-15-一维数组与二维数组的创建、初始化以及在内存中的储存、数组越界和数组作为函数参数_阿秋的阿秋不是阿秋的博客-CSDN博客

目录

数组作为函数参数

书写形式

还未进入函数的监视

?进入函数1

?进入函数2

总结

形参实参的对比

进入函数之前

进入函数1

进入函数2

?总结

数组名是什么?

代码演示


接续上一篇

数组作为函数参数

书写形式

数组作为函数传参的时候
可以写成两种形式
1·数组形式
2·指针形式

//形参数组形式
void test1(int arr[]) //10可写可不写,因为传过来是首元素的地址
{
}
//形参指针形式
void test2(int* arr) //这两种写法都可以,本质上都是指针,只不过是两种书写方式
{
}
int main()
{
	int arr[10] = { 0 };
	test1(arr);
    test2(arr);
	return 0;
}

调试来看看

还未进入函数的监视

在未进入函数的时候展开看一下,arr是首元素的地址,包含所有值,类型为int[10]

??????可以看到arr和&arr在未进入函数的时候,地址和包含的值都一样,只有类型不一样。

?arr+1代表下一个元素的地址和值,类型为int*

*arr和arr[0]都是首元素的值,都为int类型。

?进入函数1

arr进入函数后,是首元素的地址和值,类型变为int*

&arr的地址有所变化,但是包含arr的地址与值,类型为int**

arr+1的地址、值、类型都未改变。

arr[0]和*arr也未发生改变。

?进入函数2

?可以看到函数2和函数1的图可以说是一模一样,这就是两种写法的监视图展示。

总结

名称地址类型
进入函数
arr首元素地址所有值只有首元素

int

[数组大小]

int*
&arr首元素地址新地址(包含arr地址)所有值只有首元素

int

[数组大小]*

int**
arr+1下一个元素地址下一个元素的值int*
arr[0]首元素的值
?
int
*arr
*(arr+1)下一个元素的值

写到这里,我想做个对比,之前在这篇文章里从0开始学c语言-14-关于(1)函数定义、函数分类、函数参数、函数调用以及函数练习_阿秋的阿秋不是阿秋的博客-CSDN博客

有写过形参和实参,但是我觉得还需要和数组对比来看才能更加清晰。

形参实参的对比

我们先拿来代码,这是一段需要交换两个数的值的代码。

void change1(int x, int y)//传值调用
{
	int z = x; //把z理解成空瓶,xy理解为酱油和醋
	x = y;
	y = z;
}
void change2(int* px, int* py)//传址调用
{
	int pz = *px; //通过x找到a,*x就相当于a
	*px = *py;
	*py = pz;
}
int main()
{
	int a = 9;
	int b = 98;
	printf("交换前:%d %d\n", a, b);
	change1(a, b);
	printf("交换后1:%d %d\n", a, b);
	change2(&a, &b);
	printf("交换后2:%d %d\n", a, b); 
	//a和b的地址不变,交换的只是存储的值	
	return 0;
}

我们可以看到,有传值调用和传址调用这两个书写形式,而我们在那个文章里总结的是

1·地址不会交换,只会交换储存的值

2·通过指针可以建立起函数和外界的联系,实现函数内外的数据同步。

这里我们再进行监视,深入剖析一下。

为了方便对比,我们把px和py改成x和y。

进入函数之前

&a和&b的类型是int*。

而*a和*b的a和b不是指针,所以没办法写成*a和*b。

这一点就和数组不一样,因为数组名字本身就代表首元素的地址,还是不多说了,指针这回事我还没出详细文章讲,现在就先记住不一样就行了!

进入函数1

?可以看到&x、&y的地址和&a、&b的地址并不一样,但是包含的值一样。

而在函数中的*x、*y的x和y甚至是未定义。(因为是传值调用啊,只有值怎么调用地址?)

进入函数2

这就可以看到什么叫做名副其实的传值调用了~

传过来的x、y与为进入函数前的&x、&y的地址与值相同(这里展示的是交换后的值)

而函数中的&x、&y则有了新的地址,但是会包含x、y对应的地址与值。

因为传过来的x与y是有地址的,所以此时的*x与*y便终于有了对应的值和类型!

?总结

名称地址类型
调用传值传址传值传址传值传址
x与&a相同intint*

与函数外传递过来的值

(没交换之前)相同

&x新地址新地址(包含&a)int*int**
*x不存在不存在int不存在相同

就总结到这里,后续学了指针会理解更深刻一些。

数组名是什么?

数组名是首元素的地址
两个例外:数组名会代表整个数组
1、sizeof(数组名) 中的数组名代表整个数组,计算的是整个数组的大小,单位是字节(函数调用中的sizeof(数组名)中的数组名包含首元素的大小
2、&数组名? 中的数组名代表整个数组,取出整个数组的地址

代码演示

int main()
{
	int arr[10] = { 0 };
	printf("%p\n", &arr);
	printf("%p\n\n", &arr+1); //加了十进制的40,十六进制的28

	printf("%p\n", arr);
	printf("%p\n\n", arr+1);  //加了4字节

	printf("%p\n", &arr[0]);
	printf("%p\n\n", &arr[1]);
	return 0;
}

第一组printf,&arr+1代表加了整个数组大小。

第二组printf,arr+1代表加了一个元素的大小。

第三组printf,&arr[0]实际上就是arr,&arr[1]实际上就是arr+1。

?下一篇会进行数组相关的练习,先搞清楚这篇意思再说。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:54:41  更:2022-09-13 10:56:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 5:35:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码