C语言学习(十五)---数组的扩展知识、实参和形参

在前面的两节内容中,我们学习了数组的相关概念,并对数组使用过程中的部分注意事项进行了强调,今天,我们接着讲解一些关于数组的特别内容,然后介绍实参和形参的区别
话不多说,开整!!!

数组的扩展知识

数组名的默认含义

到目前为止,我们已经学会了数组的定义方式,如下所示:

  int arr[] = {1,2,3};

我们即定义了一个整型数组,数组的名称是arr,这个大家都知道,那么如果打印arr,我们会得到什么结果呢,我们不妨来试一试,代码如下:

#include<stdio.h>
int  main()
{
    int arr[] = {1,2,3};
    printf("%d\n",arr);
    return 0;
}

此时编译器会提示我们%d期待的打印对象为整型,但此处的arr为int*,如下所示:
在这里插入图片描述
前面我们讲到过,x*代表的是指针类型,那么我们不妨听从编译器的建议,就打印指针类型,大家还没有忘记吧,打印指针类型的变量符号%p,修改代码,然后保存编译,可以得到以下结果:
在这里插入图片描述
我们得到了一个十六进制数字,仔细一看,这怎么和我们之前打印的地址长得这么像呢,那么他到底是不是地址呢,如果是地址,又是什么地址呢?
在这里先说明结论,然后进行验证:

一般情况下,数组名代表着数组中首个元素的地址(两种情况除外)

所以我们在打印数组时,打印出来的就是数组首元素的地址,既然是地址,那自然就是指针变量了,因为只有指针变量才能存放地址,这也就证明了前述中编译器的建议是正确的。
现在我们进行验证,我们再对数组中的首元素地址进行打印,查看二者的地址是否一样,代码如下:

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

编译查看结果:
在这里插入图片描述
可以发现确实二者的值一样,确实是一个地址,因此上述的说法成立。

数组名默认含义的两种特殊情况

上述说到,数组名默认为数组中首个元素的地址(两种情况除外),下面就来介绍这两种特殊情况是什么。

sizeof函数内

我们在之前的内容中就学习了这个函数的作用是什么,其作用是计算数据的占用空间,因此,当使用该函数时,其中的数组名arr不是代表数组中首元素的地址,而是整个数组,上述代码后添加以下:

 printf("%d\n",sizeof(arr));

编译运行,得到如图所示结果:
在这里插入图片描述
表示12个字节,因为我们定义的数组为整型数组,每个整型为4字节,数组内有3个元素,因此3*4=12字节,所以:

在sizeof函数内,数组名不代表数组中的首元素地址,而是整个数组

&数组名

数组名默认含义的第二种失效环境就是类似如下形式:

&arr

此时其也不代表着默认的含义而是代表着整个数组的地址,注意:是整个数组的地址,示例代码如下:

#include<stdio.h>
int  main()
{
    int arr[] = {1,2,3};
    printf("%p\n",arr);
    printf("%p\n",&arr[0]);
    printf("%d\n",sizeof(arr));
    printf("%p\n",&arr);
    return 0;
}

保存编译运行,结果如下:
在这里插入图片描述
看到这里,你可能会疑惑,这不和数组首元素的地址一样吗,为什么我还要着重强调它代表着的是整个数组的地址而不是首元素地址呢,下面我们验证。
我们对代表首元素地址的arr和代表整个数组的地址&arr分别加1,可能你不明白为什么地址还能加减,在此处简单理解:地址存放的我们称为指针变量,既然是一个变量,那么自然可以进行加减法运算,后面在指针内容时还会详细讲解,示例代码如下:

#include<stdio.h>
int  main()
{
    int arr[] = {1,2,3};
    printf("%p\n",arr+1);
    printf("%p\n",&arr[0]+1);
    printf("%d\n",sizeof(arr));
    printf("%p\n",&arr+1);
    return 0;
}

编译查看结果:
在这里插入图片描述
我们将两个结果进行对比,如下所示:
在这里插入图片描述
从这张对比图中,我们可以更加清楚的了解为什么要强调此处的&arr代表的是整个数组的地址,我们对于首元素地址加1,其只增加了4个字节,而&arr进行加1却增加了一个数组的长度即12个字节,运算过程如下:
在这里插入图片描述
所以说:

&arr 代表整个数组的地址

除了上述两种例外之外,其余时刻,arr均代表的是数组中首元素的地址

实参与形参

实参与形参,又称为实际参数与形式参数,从马克思主义的基本观点来看,二者可以说是:你中有我,我中有你,辩证统一
至于二者的区分呢,也非常容易区分,在你调用函数时,括号内的参数即为实参,定义函数时,括号内的参数即为形参。如下所示代码:

#include<stdio.h>
int test(int a)
{
    int sum = a + 1;
}
int main()
{
    int a = 1;
    int sum = test(a);
    return 0;
}

如下图所示的标记:
在这里插入图片描述

联系

二者是的命名是可以相同的,二者之间的联系是:

形参是实参的一份临时拷贝,使用完之后就会自动销毁

什么意思呢,也就是说:
调用函数test时,会将a =1这个值临时拷贝一份,放入test函数中使用,再调用函数结束之后,该值自动从内存中删除

区别

既然有联系,自然就有区别,不然怎么能叫辩证统一呢。其区别就在于:

修改形参不会改变实参的值

也就是我改变了形参值,外部的实参值,是不会改变的,比如我想要实现两个数字互换位置的功能,a=5,b=2调用函数后变为a=2,b=5;那我编写了一个代码如下:

#include<stdio.h>
void exchange(int a,int b)
{
    int temp = a;//创建临时变量存储a
    a = b;
    b = temp;
}
int main()
{
    int a = 5;
    int b = 2
    exchange(a,b);
    printf("a= %d b= %d ",a,b);
    return 0;
}

那么它能实现这个功能吗,编译查看结果:
在这里插入图片描述
我们可以看到并没有像我们想象的一样,交换二者的值,这正是因为型参与实参的区别,我们现在进行调试,可以看到监视窗口此时的a、b以及其对应地址如下:
在这里插入图片描述
在进入自定义函数后,再查看监视窗口
在这里插入图片描述
可以看到此处,二者确定已经交换了值,但为什么打印时,二者的值没有出现交换呢,细心的朋友可能已经发现了,在前后两次a、b的地址是不一样的,如下:
在这里插入图片描述
也就是我在另外的地址交换了,那和我原来的地址毛关系没有,
那么如何解决这种问题呢?既然二者的地址不一样,那我传地址是不是就可以了,下面进行测试,此时传入a、b的地址由于传入的是地址,所以需要接受为指针变量,代码如下:

#include<stdio.h>
void exchange(int* a,int* b)
{
    int temp = *a;//创建临时变量存储地址a中的数值
    *a = *b;
    //*解引用操作符:也就是把地址b中的内容取出来赋值给a所在的地址
    *b = temp;
}
int main()
{
    int a = 5;
    int b = 2;
    exchange(&a,&b);
    printf("a= %d b =%d ",a,b);
    return 0;
}

编译运行,可以得到以下结果:
在这里插入图片描述
此时,我们看到二者的内容进行了交换,那么到这里我们不得不疑问了:到底什么时候传值,什么时候传地址呢,大家只需记住以下的话即可

想要改变外部的值则传址,无需改变则传值

上述内容交换即使前者,所以需要进行传地址才可以。
上述内容即使今天的全部内容了,感谢大家的观看。
如果方便,辛苦大家点个赞和关注哦!
您的点赞或评论或关注是对我最大的肯定,谢谢大家!!!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器 xiaohu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值