细节4:数组名何时拥有数组特性?何时沦落为普通指针

一、数组名具备数组特征和指针常量特征

int main()
{
	char a[20] = {'1','2','3'};
	char* p = a;
	cout << sizeof(a) / sizeof(char) << endl;
	cout << sizeof(p) << endl;
}

输出结果:
20
4

此时数组名a具有数组的结构特性

它的内涵指代一个数据结构实体-数组,因此拥有该数组的特性:长度

但我们又看到,a可以直接复制给指针p,这说明a类型和p是一致的。而且通过p我们也可以访问数组a的内容。实际原理如图所示:
在这里插入图片描述

它的外延表示一个指向首地址的指针常量,指向地址不可更改。

二、数组名退化为普通指针

看以下代码,数组作为函数形参,输出数组大小

void getlen(char a[]) {
	a[0] = '2';
	cout << sizeof(a) << endl;
}

int main()
{
	char a[20] = {'1','2','3'};
	char* p = a;
	getlen(a);
}

按照数组名的特性,应该具备数组特征,所以使用sizeof时应该就是传递到函数中的数组大小,,这是通常思路。

事实上,在传递到一个新的函数时,其实在栈空间新建一个栈帧,原来的数组存在于调用它的栈帧。而作为形参传入时只作为一个普通指针。可访问/修改数组内容,本身值也可修改。

void getlen(char arr[]) {
	arr[0] = '2';
	char chr = '9';
	arr = &chr;
	cout << sizeof(arr) << endl;
}

int main()
{
	char a[20] = {'1','2','3'};
	char* p = a;
	getlen(a);
}

在这里插入图片描述
关于这个,我的思路是在传递到新函数时,创建的形参已经不是原有的数组名,而是新创建的指针,只是拷贝数组名的值到新建指针中去。此时新建的指针就是在函数中的“数组名”,实际上仅仅为一个副本。这和实参和形参的转换方式是一致的。

此时在函数中,再输出所谓的“数组名”大小,实际为指针大小。
形式如char* a原理一样。

三、总结

(1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组;

(2)数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量;

(3)指向数组的指针则是另外一种变量类型(32位机器长度为4),仅仅指向着数组的存放地址

(4)数组名作为形参时,函数内部的“数组名”仅仅是指向数组的普通指针,不具备数组特征,即只在同一个栈空间内具备数组特征

参考:https://blog.youkuaiyun.com/qq100440110/article/details/51995655

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值