数组名与指针的联系和区别(数组名不是指针,而是关于“数组类型”的一个对象或者说变量 )

关于数组名,先说一下我的结论吧

1.数组名不是指针,它是“数组类型”的一个对象或者变量(就好比int i中的i,CString str当中的str)

2.“数组类型”的对象可以隐式转化为指针(当它转化为指针时,实际上是转化为指向数组第一个元素的指针)

先来看下面几个例子:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

例1:

#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
	char * ss1 = "0123456789";
	char   ss2[] = "0123456789";
	printf("ss1的大小为%d\n",sizeof(ss1));
	printf("ss2的大小为%d\n",sizeof(ss2));
	return 0;
}

结果为

假如ss1和ss2同为指针的话,他们的结果应该是一样的,都应该等于4个字节,但是从结果上看来明显不一样,ss1是指针没错,ss2却更像是一个对象

----------------------------------------------------------------------------------------------------------------------------------------------------------

例2

#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
	char * ss1 = "0123456789";
	char   ss2[] = "0123456789";
	printf("ss1为%d\n",(int)ss1);
	printf("ss1的引用为%d\n",(int &)ss1  );
	printf("ss2为%d\n",(int)ss2);
	printf("ss2的引用为%d\n", (int &)ss2);
	return 0;
}

结果为:

我们都知道指针是地址,它的值是一个无符号32位整数,既然这样,那么将它强转为整型和将它强转为整型的引用应该是一样,就如同上图结果的第1行和第2行。。但是第3行和第4行却不一样,这也从侧面证明了ss2不是指针

那么ss2的这两个值是怎么来的呢?

我们在例2程序中加上如下一句代码:

printf("&ss2[0]为%d\n",&ss2[0]);

编译执行

原来ss2转化为整型得到的值和指向ss2数组的第一个元素的指针相同,表明ss2是可以转化为指针的值的

那ss2的转化为引用的值怎么得到的呢????????

要解释这种现象,我们先看一个float型转为int 型和转为int &型

#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
	float f = 1.0;
	printf("f转为整型为%d\n",(int)f );
	printf("f转化为整型的引用为%d\n",(int &)f);
	return 0;
}

得到结果

仔细想一下,之所以出现这样的结果,是因为float型和int型在计算机中的存储是不一样的

foat型转为整型,是编译器实现的,它知道怎么转为整型,所以float型的1.0转为整型就是1

但是如果转为int &型,编译器没有定义这种情况,所以它只好到float的地址那里取连续4个字节,最后转化为整型,浮点型1.0在计算机内存中存储的是00 00 80 3F这4个字节,考虑的x86结构是小端结构,所以它对应的整型是0x3F8000,即十进制的1065353216

根据上面的情况,我们可以做一个类比假设,假设如下:

我们不妨假设一下,ss2能由编译器自动转化为指针,但是它并非指针,而是一个对象(就好比float型可以转化为整型,但是它并非整型,float型内部存储并不像整型那样存储,所以转为int和转为int &结果是不一样的)

因为“0123456789”的前4个字节是 ‘0’ ‘1’ ‘2’ ‘3’即16进制的 30 31 32 33,考虑到x86的小端结构对应的整型即为0x33323130,刚好是十进制的858927408,我们的假设吻合

上面只是我们的类比做出假设,我们如何更确定我们的假设呢,请看例3

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

例3

#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
	char * ss1 = "0123456789";
	char   ss2[] = "0123456789";
	cout << typeid(ss1).name() << endl;
	cout << typeid(ss2).name() << endl;
	return 0;
}

得到结果

可以看到ss1是指针类型,而ss2是char [11]类型。。。

我想,这已经算是数组名不是指针的铁证了。。

或许还有人会说char [11]是指针类型,毕竟好像也没有哪本书上说过char [11]类型,还是可以狡辩的,好吧,下面看例4

---------------------------------------------------------------------------------------------------------------------------------------------------------------------

例4

#include "stdio.h"
#include <iostream>
using namespace std;
int main()
{
	char * ss1 = "0123456789";
	char   ss2[] = "0123456789";
	ss2 = 1;
	return 0;
}

尝试编译执行,报错

编译器已经说的很清楚了,ss2是数组类型

至此结论已经很明显啦

 

 

 

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值