在前面我们学习了各种类型的指针,也得知了数组也与指针有着紧密的联系,所以接下来看一下指针与数组的综合题
指针和数组综合
首先我们来复习一下
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
strlen
语句中,计算字符串的长度,遇到\0
才结束返回长度
//一维数组 int a[] = {1,2,3,4}; printf("%d\n",sizeof(a));//16 数组名单独放到sizeof中,计算的是整个数组的大小,结果是16 printf("%d\n",sizeof(a+0));//4/8 数组名不是单独放到sizeof中,这里的a表示数组首元素的地址,所以结果是指针的大小 4/8 printf("%d\n",sizeof(*a));//4 数组名不是单独放到sizeof中,a表示数组首元素的地址,解引用就是首元素,结果是4 printf("%d\n",sizeof(a+1));//4/8 数组名不是单独放到sizeof中,这里的a表示数组首元素的地址,a+1就是数组第二个元素的地址,结果是指4\8 printf("%d\n",sizeof(a[1]));//4 a[1]是数组首元素,大小是4 printf("%d\n",sizeof(&a));//4/8 &a,取出整个数组的地址,结果是4/8 printf("%d\n",sizeof(*&a));//16 解引用数组的地址,得到整个数组,大小是16 printf("%d\n",sizeof(&a+1));//4 数组的地址+1,类型仍是数组指针,大小4/8 printf("%d\n",sizeof(&a[0]));//4/8 取数组首元素的地址,大小是4/8 printf("%d\n",sizeof(&a[0]+1));// 4/8
//字符数组 char arr[] = {'a','b','c','d','e','f'}; printf("%d\n", sizeof(arr));//6 数组名单独放到sizeof中,计算整个数组的的大小,结果是6 printf("%d\n", sizeof(arr+0));//4/8 数组名并不是单独的,所以arr表示数组首元素地址,所以这里结果是4/8 printf("%d\n", sizeof(*arr));//1 数组名并不是单独的,所以arr表示数组首元素地址吗,再解引用,得到数组首元素,大小为1 printf("%d\n", sizeof(arr[1]));//1 arr[1]为数组首元素,大小为1 printf("%d\n", sizeof(&arr));//4/8 &arr,得到数组的地址,大小为4/8 printf("%d\n", sizeof(&arr+1));//4/8 printf("%d\n", sizeof(&arr[0]+1));//4/8 取数组首元素的地址,再+1,就是数组第二个元素的地址,大小为4/8 printf("%d\n", strlen(arr));//随机值 因为arr数组中没有\0,数组所占内存空间后面中在某个位置可能会有\0,所以是随机值 printf("%d\n", strlen(arr+0));//随机值 arr+0,表示数组首元素地址,结果仍是随机值 printf("%d\n", strlen(*arr));//错误 strlen中传的是一个地址,strlen(*arr)就是strlen('a')->strlen(97), //而97作为一个地址是不可以被访问的,非法访问 printf("%d\n", strlen(arr[1]));//错误 arr[1]是‘b’ASCII值是97,同样,非法访问 printf("%d\n", strlen(&arr));//随机值 &arr虽然是数组的地址,但是也是从数组起始位置开始的,数组中无\0,计算的还是随机值 printf("%d\n", strlen(&arr+1));//随机值 &arr是数组的地址,&arr+1是跳过整个数组的地址,求字符串长度也是随机值 printf("%d\n", strlen(&arr[0]+1));//随机值 &arr[0] + 1是第二个元素的地址,是'b'的地址,求字符串长度也是随机值
char arr[] = "abcdef"; printf("%d\n", sizeof(arr));//7 这个字符数组中,最后有\0,所以长度是7 printf("%d\n", sizeof(arr+0));//4/8 arr+0表示数组首元素地址,4/8 printf("%d\n", sizeof(*arr));//1 arr不是单独的,表示数组首元素地址,解引用得到首元素,大小为1 printf("%d\n", sizeof(arr[1]));//1 printf("%d\n", sizeof(&arr));//4/8 &arr取出数组地址,大小是4/8 printf("%d\n", sizeof(&arr+1));//4/8 &arr取出数组地址,+1跳过一个数组指针大小的空间,大小仍是4/8 printf("%d\n", sizeof(&arr[0]+1));//4/8 &arr[0]为数组首元素地址,+1为第二个元素地址,大小为4/8 printf("%d\n", strlen(arr));//6 这个数组中有\0,所以得到长度为6 printf("%d\n", strlen(arr+0));//6 arr+0为数组首元素地址,大小为6 printf("%d\n", strlen(*arr));//错误, *arr得到'a',ASCII值为97,strlen(97),非法访问 printf("%d\n", strlen(arr[1]));//错误,仍然非法访问 printf("%d\n", strlen(&arr));//6 &arr虽然是数组的地址,但是也是从数组起始位置开始的,结果是6 printf("%d\n", strlen(&arr+1));//随机值 &arr是数组地址,&arr+1跳过了整个数组的地址,后面地址中的内容不确定,所以是随机值 printf("%d\n", strlen(&arr[0]+1));//5 &arr[0]+1为第二个元素的地址,从第二个元素开始计算长度,结果是5
//字符指针 char *p = "abcdef"; printf("%d\n", sizeof(p));//4/8 p是字符指针,大小为4/8 printf("%d\n", sizeof(p+1));//4/8 p + 1是b的地址,是地址,就是4/8个字节 printf("%d\n", sizeof(*p));//1 *p是'a',sizeof(*p)计算的是字符的大小,是1字节 printf("%d\n", sizeof(p[0]));//1 printf("%d\n", sizeof(&p));//4/8 &p是二级指针,是指针大小就是4/8 printf("%d\n", sizeof(&p+1));//4/8 &p + 1是跳过p变量后的地址,4/8字节 printf("%d\n", sizeof(&p[0]+1));//4/8 p[0]就是‘a’,&p[0]就是a的地址,+1,就是b的地址,是地址就是4/8 printf("%d\n", strlen(p));//6 字符串长度 printf("%d\n", strlen(p+1));//5 p + 1是b的地址,求字符串长度就是5 printf("%d\n", strlen(*p));//错误 *p是'a',非法访问 printf("%d\n", strlen(p[0]));//错误 同上 printf("%d\n", strlen(&p));//随机值 &p拿到的地址是指针变量p的地址,随机值 printf("%d\n", strlen(&p+1));//随机值 &p+1是跳过p变量的地址,从这里开始求字符串长度也是随机值 printf("%d\n", strlen(&p[0]+1));//5 &p[0] + 1是b的地址,从b的地址向后数字符串的长度是5
//二维数组 int a[3][4] = {0}; printf("%d\n",sizeof(a));//求二维数组的大小,3*4*4 = 48 printf("%d\n",sizeof(a[0][0]));//4 printf("%d\n",sizeof(a[0]));//a[0]是第一行的数组名,数组名单独放在sizeof内部计算的就是数组(第一行)的大小,16个字节 printf("%d\n",sizeof(a[0]+1));//a[0]作为第一行的数组名,没有单独放在sizeof内部,没有取地址 //表示的就是第一行数组首元素的地址,那就是a[0][0]的地址,a[0]+1就是第一行第二个元素的地址,是地址就是4/8个字节 printf("%d\n",sizeof(*(a[0]+1)));//*(a[0] + 1)是第一行第2个元素,4个字节 printf("%d\n",sizeof(a+1));//a是二维数组的数组名,数组名表示首元素的地址,就是第一行的地址,a+1就是第二行的地址,4/8 printf("%d\n",sizeof(*(a+1)));//a+1是第二行数组的地址,*(a+1)表示的就是第二行,4*4 = 16 printf("%d\n",sizeof(&a[0]+1));//&a[0]是第一行的地址,&a[0]+1是第二行的地址,地址的大小就是4/8 printf("%d\n",sizeof(*(&a[0]+1)));//*(&a[0] + 1) 是对第二行的地址解引用,得到的就是第二行,计算的就是第二行的大小 printf("%d\n",sizeof(*a));//a表示首元素的地址,就是第一行的地址,*a就是第一行,计算的就是第一行的大小 16 printf("%d\n",sizeof(a[3]));//a[3]是第四行数组名,数组名单独放到sizeof内部,计算第四行的大小 16
经过这些题,相信大家对于数组与指针会有进一步的理解