持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
数组名与指针的共同点
在C++中,数组名可以当作数组第一个元素的指针来用。例如:
short x[] = {1,2,3};
short* y = x;
cout << x[0] << " " << y[1] << " " << *(x+1) << " " << *(y+2) << endl;
输出: 1 2 2 3
如上例,无论是数组名x还是指针y,都可以使用下标的方式或解引用的方式来访问数组中的某个元素。那么,数组名和元素指针真的完全一样,没有区别吗?
其实,这二者还是有区别的。
与数组名与指针的区别
-
数组名是常量,不可修改
首先数组名只能指向这个数组,不能指向其他地址。
x = x+1; // error y = y+1;x = x+1会报编译错误,而指针y指向的地址则可以修改。
-
数组名和元素指针的sizeof大小不同
cout << sizeof(x) << " " << sizeof(y) << endl;输出: 6 8
这里面,6代表x这个数组的大小,因为是short类型2字节,3个元素,所以一共6个字节。而y的大小为8则是64位指针的大小。
-
取地址操作表现不同
数组名x进行取地址&x,得到的是整个数组的地址;而对指针y进行取地址得到的则是指针的地址。它们有什么区别呢?看看代码:
cout << "x:" << x << " &x:" << &x << " x+1:" << x+1 << " &x+1:" << &x+1 << " &y:" << &y << " &y+1:" << &y+1 << " " << endl; 输出:x:0x7ffee8c3fada &x:0x7ffee8c3fada x+1:0x7ffee8c3fadc &x+1:0x7ffee8c3fae0 &y:0x7ffee8c3fad0 &y+1:0x7ffee8c3fad8可以看到,数组的地址(&x:0x7ffee8c3fada)与第一个元素地址(x:0x7ffee8c3fada)在数字上相同,但数组的地址表示的是整个数组的大小,因此&x+1操作实际上偏移了6个字节(即sizeof x),而x+1只偏移了2个字节(short的长度)。
而指针y的地址(&y:0x7ffee8c3fad0)则与第一个元素地址没有联系,&y+1偏移了8个字节(即sizeof y)。
-
初始化方式不同
用数组名的方式实际上直接分配了数组的内存空间,所以可以直接用初始化列表进行初始化,数组声明后也可以直接对某个元素赋值。
而指针在声明时只分配了指针本身的内存空间,因此需要用new或者其他已经分配好的空间进行赋值,才能使其指向有效的内存地址。 我们不能这样初始化:
short* z = {1,2,3};但对于字符串,却可以用下面两种方式初始化:
char st1[] = "string"; char* st2 = "string";对于第一种,为字符串分配了内存空间,没有问题。但第二种,有些编译器可能不会为st2单独分配内存空间,而是对于相同的字符串字面量,共享同一个内存空间。因此,我们最好不要修改st2,有些IDE也会给出提示
改进方法很简单,只需声明为const类型即可:
const char* st2 = "string";