关于数组名,先说一下我的结论吧
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是数组类型
至此结论已经很明显啦