/*
a &a &a[0][0]都是指着数组的首地址
差别见代码部分,输出结果
*/
#include
using namespace std;
int main()
{
int a[3][3]={{1,2,3},{4,5,6},{7,8,9}};
/************************************************************/
cout << " &a = " << &a << endl;
cout << " &a+1 = " << &a+1 << endl << endl;//偏移了整个二维数组a[3][3]字节的量
/************************************************************/
cout << " a = " << a << endl;
cout << " *a+1 = " << *a+1 << endl;
cout << " a+1 = " << a+1 << endl << endl;//偏移二维数组a[3][3]的a[i]字节的量
/************************************************************/
cout << " a+1 = " << a+1 << endl;
cout << " (a+1)+1 = " << (a+1)+1 << endl << endl;//偏移二维数组a[3][3]的a[i]字节的量
/************************************************************/
cout << " &a[1][0] = " << &a[1][0] << endl;
cout << " &a[1][0]+1 = " << &a[1][0]+1 << endl << endl;//偏移了一个int字节的量
/************************************************************/
cout << " *(a+1) = " << *(a+1) << endl;
cout << " *(a+1)+1 = " << *(a+1)+1 << endl; //偏移了一个int字节的量
/************************************************************/
cout << " **a = " << **a << endl; //抽取第一个元素的值
cout << " **(a+1) = " << **(a+1) << endl << endl; //抽取第四个元素的值
/************************************************************/
/*
cout << " *(a+1) = " << *(a+1) << endl
这里为什么是输出a[i]的地址而不是元素值。
a *a **a
a 是说明这个数组有3行。
*a 是说明每行有3个元素
**a是说明每行中的每个元素
打印函数只打印内置的数据类型,并不提供输出数组类型的。
只有具体指向某个int类型值才能正确输出来
*/
}
举个例子
一本书 做"上" " 中" "下" 三部分个标签。不管怎么未翻开的书,显示总是封面的。
&a表示这本书 &a+1 直接把这本书翻完了、
a表示这本书三部分 a+1直接翻过上部,到中部了
*a表示表示这本上部分 *a+1翻过封面的直接到第一页了。
**a 就是表示这本呢书封面
我们不可能把一本书看看了封面就丢了吧。
是从封面一页一页的内容读。
若读得绝得不爽了,我就可以直接跳到看看结局。实际我们还是读的是页面的内容。
int a[6] = {5, 7, 8, 9, 10, 11};
1、 a; &a[0]; &a;三个地址数值都一样
2、a代表为此数组的首地址和&a[0]一样,如果加1的话都是跨越sizeof(int)个字节(即下一元素)。
3、其中a是比较特殊。(取a的地址和a在数值上一样):
a、如果用sizeof(a);值是为3 * sizeof(int)为整个数组空间的小大,由于a代表此数组的首地址且数组为int类型可以赋给int类型的指针,加1的话是跨越sizeof(int)个字节(即下一元素)。
b、由于a所代表整个的数组空间,&a是代表整个数组空间的首地址,如果加1的话就是跨越3*sizeof(int)个字节。如果表达示:int *p = &a; 这样就不会有警告,数据类型不兼容。
****************************************************************
再来看二维数组织。
int b[2][3] = {{5, 7, 8},{9, 10, 11}};
1、*b, b[0], b, &b[0], &b 和&a[0][0], *a[0]个地址数值都一样
2、注意一点二维数组是一个一维数组(行)中的元素也是一维数组(列)。(我是这样理解的)
3、用sizeof()分别求出*b、b[0]空间都为3 *sizeof(int)个字节(每行的空间大小)。但是如果加1的话中是跨越的空间是sizeof(int)个字节(即0行下一元素),也相当于一维数组名a。也是可以赋值给int类型的指针。(**b和*b[0]就是a[0][0]了)
4、再来看下b和&b[0](想一想:上面的*b和b[0]可以说是等效的,那么&b[0] 等效于&(*b) 这样就变成了b了,这是我的理解,在程序中&(*b)这样表达式是不行), 用sizeof()求出b为6 * sizeof(int)整个数组空间的小大,但是加1的话是跨越3*sizeof(int)个字节。如果表达示:int *p = b; 这样就不会有警告,数据类型不兼容。
5、由于b又是代表整个的数组空间,&b是代表整个数组空间的首地址,如果加1的话就是跨越6*sizeof(int)个字节。如果表达示:int *p = &b; 这样就不会有警告,数据类型不兼容。
其实不管是几维的数组,其实在内存中都是线性储存的,只是计算机对这块区域的分不同的基本空间大小。
如果是一维数组,a+i就是表示i+1个元素,记住数组下标是从0开始的。
然而二维数组,形式就是这样:2 3 4
5 6 7
这样的你要确定一个元素,第一要知道它在第几行,在要知道是第几列,这样才能确定一个元素。
*(a+i) 不是其中的元素而是第 i+1 行的首地址
&a[0]与&a[0][0]表示的是同一个地址
建议你还是找本书好好看看数组与指针,这个对于C语言很重要!!
首先&a[0]与&a[0][0]是不相等的,因为一个二维数组和一个一维数组是不能比较的,
a表示其首地址&a[0][0],a+i就是偏移量为i的元素地址,可以理解为行偏移量*(a+i)是表示第i行的首地址,*(a+i)等效于*(*(a+i)+j),此时j=0;即a[i][0],也就是是说第第i行的首地址了。