指针、数组和指针算数
指针和数组基本等价的原因在于指针算数c++内部处理数组的方式。指针变量加1,增加的量等于它指向的类型的字节数。将指向double的指针加1后,如果系统对double使用8字节存储,则数值增加8字节。
下面的例子展示了指针、数组和指针算数。指针和指针都可以通过指针和数组的方式获取数组的值。
#include <iostream>
int main()
{
using namespace std;
double wages[] = { 10000,20000,30000 };
short stacks[] = { 3,2,1 };
double* pw = wages;
short* ps = &stacks[0];
cout << "pw = " << pw << ", *pw = " << *pw << endl;
pw = pw + 1;
cout << "pw + 1 " << endl;
cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";
cout << "ps = " << ps << ", *ps = " << *ps << endl;
ps = ps + 1;
cout << "ps + 1 " << endl;
cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";
cout << "access elements with array notation\n";
cout << "stacks[0]= " << stacks[0] <<", stacks[1]= "<<stacks[1] << "\n\n";
cout << "access elements with pointer notation\n";
cout << "*stacks= " << *stacks << ", *(stacks+1)= " << *(stacks + 1) << "\n\n";
cout << sizeof(stacks) << " size of stacks\n";
cout << sizeof(ps) << " size of ps\n\n";
ps--;
cout << "ps[0]= " << ps[0] << ", ps[1]=" << ps[1] << ", ps[2]=" << ps[2] << "\n";
cout << "*ps= " << *ps << ", *(ps+1)=" << *(ps+1) << ", *(ps+2)=" << *(ps+2) << "\n";
return 0;
}
输出
pw = 00DAFA28, *pw = 10000
pw + 1
pw = 00DAFA30, *pw = 20000
ps = 00DAFA18, *ps = 3
ps + 1
ps = 00DAFA1A, *ps = 2
access elements with array notation
stacks[0]= 3, stacks[1]= 2
access elements with pointer notation
*stacks= 3, *(stacks+1)= 2
6 size of stacks
4 size of ps
ps[0]= 3, ps[1]=2, ps[2]=1
*ps= 3, *(ps+1)=2, *(ps+2)=1
c++将数组名解释为地址。多数情况下c++将数组名解释为数组第一个元素的地址。 以下2种定义方式是等价的。
double* pw = wages;
short* ps = &stacks[0];
从输出可知,*(stacks+1), stacks[1], *(ps+1), ps[1]是等价的。通常使用数组表示法时,C++都会执行以下转换:
二者由2点不同:
- 可以修改指针的值,而数组名是常量
ptrname = ptrname + 1;//valid arrayname = arrayname + 1;// not valid
- 对数组使用sizeof得到的是数组的长度,对指针使用得到的是指针的长度,即使指针指向的是一个数组。例如本例中对stacks数组和ps指针使用sizeof得到的结果:
6 size of stacks
4 size of ps
short tell[10];
cout<<tell<<endl;
cout<<&tell;
二者虽然在数值上是相同的;但是从概念上说,&tell[0](即tell)是一个2字节内存块的地址,而&tell是一个20字节的内存块的地址。因此,表达式tell+1将地址值加2,而&tell+1将地址值加20.