关于数组,一些必会的数组运算
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
// 4*4=16 sizeof(数组名)代表整个数组的长度
printf("%d\n",sizeof(a+0));
// 4 a+0 代表第一个元素的地址
printf("%d\n",sizeof(*a));
// 4 a=&a[0] *a=a[0],第一个元素
printf("%d\n",sizeof(a+1));
// 4 a+1 代表第二个元素的地址
printf("%d\n",sizeof(a[1]));
// 4 a[1] 第二个元素
printf("%d\n",sizeof(&a));
// 4 &a 代表取整个数组的地址 另:vc6.0下 结果为 16,错误!
//(&为取地址符,地址长度为4个字节或者8个字节,跟平台有关,32位平台地址为4个字节)
printf("%d\n",sizeof(&a+1));
// 4 &a+1 表示指向下一个数组
printf("%d\n",sizeof(&a[0]));
// 4 &a[0] 第一个元素的地址
printf("%d\n",sizeof(&a[0]+1));
// 4 &a[0]+1 第2个元素的地址
解释:
sizeof(…)是运算符,参数可以是数组、指针、类型、对象、函数等。
它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
上面一组算式中sizeof()中的含义,由下图可直观的看到:
再看下一组计算:
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
// 6 整个数组字节长度
printf("%d\n", sizeof(arr+0));
// 4 首元素地址
printf("%d\n", sizeof(*arr));
// 1 第一个元素
printf("%d\n", sizeof(arr[1]));
// 1 第二个元素
printf("%d\n", sizeof(&arr));
// 4 整个数组的地址
printf("%d\n", sizeof(&arr+1));
// 4 下一个数组的地址
printf("%d\n", sizeof(&arr[0]+1));
// 4 第二个元素的地址
printf("%d\n", strlen(arr));
// 10(假定) strlen以'\0'为结尾,以上数组无法计算,结果为随机值,假定结果为10,方便下面讨论
printf("%d\n", strlen(arr+0));
//10
printf("%d\n", strlen(*arr));
// 错误 (*arr为首元素,strlen()中参数类型为char * ,传进来是 char ,类型不匹配。从这位地址开始往后到‘\0’结束,所以此处放的是首元素时,就被当成地址来处理,就有可能无法访问该位置的内存)
printf("%d\n", strlen(arr[1]));
//错误 (原因同上)
printf("%d\n", strlen(&arr));
//10
printf("%d\n", strlen(&arr+1));
//4(10-6) (&arr+1 表示指向下一个数组,数组内容未知)
printf("%d\n", strlen(&arr[0]+1));
//9(10-1) (第二个元素的地址)
VS2013监视如下:
再来一组:
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4
printf("%d\n", sizeof(p+1)); //4
printf("%d\n", sizeof(*p)); //1
printf("%d\n", sizeof(p[0])); //1
printf("%d\n", sizeof(&p)); //4
printf("%d\n", sizeof(&p+1)); //4
printf("%d\n", sizeof(&p[0]+1)); //4
printf("%d\n", strlen(p)); //6
printf("%d\n", strlen(p+1)); //5 (p表示首元素地址,p+1表示第二个元素)
printf("%d\n", strlen(*p)); //错误 传参类型不匹配(*为解引用,*p为97'a')
printf("%d\n", strlen(&p[0])); //6
printf("%d\n", strlen(&p)); //随机 (&p代表指针变量p的地址,见下图)
printf("%d\n", strlen(&p+1)); //随机(同上)
printf("%d\n", strlen(&p[0]+1)); //5
下图可看出&p代表的含义:
再来一组二维数组的计算:
//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a)); //48
printf("%d\n",sizeof(a[0][0])); //4
printf("%d\n",sizeof(a[0])); //16
printf("%d\n",sizeof(a[0]+1));
//4 a[0]代表第一个元素(第一个元素为4个元素的一维数组),a[0]+1代表第一行的第二个元素,也就是a[0][1]
printf("%d\n",sizeof(a+1));
//4 a为首元素(这里的元素为一维数组)地址,a+1代表第2行的地址
printf("%d\n",sizeof(&a[0]+1));
//4 &a[0]+1等价于a+1
printf("%d\n",sizeof(*a));
//16 *a代表首元素,二位数组首元素为{0,0,0,0},即为a[0]/*(a+0)
printf("%d\n",sizeof(a[3]));
//16 a[3]代表第四个元素,数组的下一个元素可以访问,不能写入。
a[3][4]二维数组可看作有三个“元素”的一维数组,这三个“元素”分别是{0,0,0,0},{0,0,0,0},{0,0,0,0},这样一解释上面的*a、a[3]就不难解释了。
**对于多维数组来说,只有最后一个中括号的数值不能省略,其他的课省略。例:a[ ][5]
**要看一个数组里有几个元素,以第一个中括号里的值为准。例:a[2][4] ->2个元素 -> 每个元素为有4个元素的一维数组。
上图:
总结:
数组名代表整个数组的时候只有两种情况:
sizeof(数组名),这里的数组名表示整个数组。
&数组名,这里的数组名表示整个数组。
按例上图~康娜