C++:指针和数组(为你解惑)

一.数组名就是指针?

相信听过这样的话:数组名就是指针。这不管是我们的授课老师,还是有些程序设计的书籍中都有这样说过。
但是,这样并不严谨。他是指针,他又不完全是。

现在来看一看数组表达式:ary[1]。显而易见,这是指数组中的第二个元素。
但是在编译器看来,这个表达式看作是*(ary+1)。这意味着实现的方法是先找到地址,再取其中的值。这里和指针异曲同工
看代码:
程序清单 1.1

	char str[]="123456";
	char *c=str;
	cout<<"*str:"<<*str<<endl;
	cout<<"*c:"<<*c<<endl;

运行结果:
在这里插入图片描述
从程序的输出可知:
*数组名 ,*指针, 数组名[ ]取值时是等价的。
在这种情况下,可以用相同的方式使用数组名和指针。但是有一个显著区别就是,指针是变量,可以修改值。数组名是常量。意思就是取值时,你可以 *(指针++) ,但是不可以 *(数组名++)

但是为什们说数组名不能直接说是指针呢?

1.第一点
我们对数组名使用sizeof运算符时得到的是数组的长度(占内存的大小),而对指向数组的指针使用该运算符时得到的却是指针的大小(往往是4字节)。
代码:
程序清单1.2

	char str[]="123456";
	char *c=str;
	cout<<"sizeof(str):"<<sizeof(str)<<endl;
	cout<<"sizeof(c):"<<sizeof(c)<<endl;
	system("pause");

运行结果:
在这里插入图片描述
这我们数组名和指针都是指向的同一个数组,但是得到的值确违背人意,因为按照我们上面的实现方法得不到我们想要的值。(注:
这里为啥会是这样的结果,我们等会下面会解释)

2.第二点
下面这段代码就很意思,让作者也感到意想不到

程序清单1.3:


void text(char str[]){
    cout<<"sizeof(str):"<<sizeof(str)<<endl;
}

int main(){
     char cs[10]="messi";
     cout<<"sizeof(cs):"<<sizeof(cs)<<endl;
    text(cs);
    system("pause");
    return 0;

}

读者可以先想5s,猜猜输出结果是啥?
5
4
3
2
1
运行结果:
在这里插入图片描述
函数中的输出结果 居然是4,有读者可能已经猜到,现在此时,数组名就是指针了。
为什们呢?
因为数组名在在作为形参传递的时候,遭到了降维打击,可以说是被强制转换为了一个指向该数组的普通指针。不能在作为原始数组。
这意味着,在此函数内,该数组名可以进行修改值的操作


二.数组名一定会被解释第一个元素地址吗?

有基础的读者知道,数组名单独拿出时往往是数组的第一个元素的地址(就是指针),
但是不完全如此,我们在程序清单1.2中,sizeof运算符中,数组名是第一个元素的地址,指针也是第一个元素的地址,但是运行结果却是截然相反呢?

因为:对数组名应用地址运算符时,得到的是整个数组的地址
话不多说,上代码:

程序清单2.1:

   int ary[5]={1,2,3};
   cout<<"ary:"<<ary<<endl;
   cout<<"ary+1:"<<ary+1<<endl;
   cout<<"&ary:"<<&ary<<endl;
   cout<<"&ary+1:"<<&ary+1<<endl;
   system("pause");

注:不知道有读者会不会像作者曾经一样,将 &ary 看作是取数组首地址的地址这是错误的错误的!! 而是得到整个数组的地址。

5
4
3
2
1
运行结果:
在这里插入图片描述
从,数字上来看,ary和&ary得到的地址相同,但是两个的概念截然不同
ary 是一个4字节大小内存块的地址;
&ary 是一个20字节大小内存块的地址;
ary+1 是地址值+4(一个int);
&ary+1 是地址值+20(数组的长度);

那么 &ary如何描述呢
int (*p) [5]=&ary ;
括号是不能省略的,如果省略括号的话,p先和 [5] 结合,导致p是一个指针数组。
这里顺便讲一句,如何确定指针的自身类型
将变量名丢掉,剩下的就是指针的自身类型。
如何确定指针指向的类型
将变量名和最近的 *删除,剩下的就是指向的类型。

所以:我们在平常时称数组名为第一个元素的地址更恰当,因为只说时数组的起始地址的话,不知道数组名+1的跨度为多少

·


版权声明:本文为qq_45853229原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。