通过一些试题来学习和进一步来熟练指针。判断这里printf函数的输出,并分析这样输出的原因
一、整形数组
注意:在x36位系统中,指针的大小是4字节。在x64位系统中指针大小是8字节
- 数组名:
- 1.sizeof(arr) ,这里arr表示的是整个数组。
- 2.&arr,这里也是表示取的整个数组的地址。
- 然后其他的数组名,都是表示数组首元素地址。
int a[]={1,2,3,4};
1: printf("%d\n",sizeof(a));
2: printf("%d\n",sizeof(a+0));
3: printf("%d\n",sizeof(*a));
4: printf("%d\n",sizeof(a+1));
5: printf("%d\n",sizeof(a[1]));
6: printf("%d\n",sizeof(&a));
7: printf("%d\n",sizeof(*&a));
8: printf("%d\n",sizeof(&a+1));
9: printf("%d\n",sizeof(&a[0]));
10: printf("%d\n",sizeof(&a[0]+1));
1. 这里 a 代表的是整个数组,整个数组的大小是16字节,所以这里输出16
2. 这里 a 没有单独放在sizeof()内部,代表首元素地址,是个指针,所以输出4 |(或者)8
3. 这里解引用a (*a) ,得到的是首元素 1 ,1是整形,整形的大小是4字节,所以输出4
4. a+1,首地址+1,首地址是个int*类型的指针,+1跳过4个字节,指向数组第二个元素的地址,也是个指针,所以输出4|8
5. a[1],可以写成 *(a+1),是数组的第二个元素2,是个整形类型,大小为4字节,所以输出4
6. 这里取地址a(&a),表示整个数组的地址,是个指针,大小为4|8字节,输出4|8
7. 这里可以看做*和&相互抵消,sizeof()里面就一个a,表示整个数组大小为16字节,所以输出16
PS:如果*&a不在sizeof内部,就是首元素的地址。
8. &a是整个数组的地址,+1跳过整个数组,指向跳过整个数组的下一个地址。也是指针,所以输出4|8
9. a[0]为数组首元素,&a[0]为取首元素的地址,是个指针,所以输出4|8
10. &a[0]为首元素的地址,元素为int类型,是一个int*类型的指针,+1跳过一个int类型的大小(4字节),跳过后指向第二个元素的地址,是个指针,所以输出4|8
二、字符数组
char arr[]={'a','b','c','d','e','f'};
1:printf("%d\n",sizeof(arr));
2:printf("%d\n",sizeof(arr+0));
3:printf("%d\n",sizeof(*arr));
4:printf("%d\n",sizeof(arr[1]));
5:printf("%d\n",sizeof(&arr));
6:printf("%d\n",sizeof(&arr+1));
7:printf("%d\n",sizeof(&arr[0]+1));
1. arr表示整个数组,arr为字符数组,大小为6,输出6
2. arr没有单独放在sizeof()内部,表示首元素地址,+0还是本身,是个指针,所以输出4|8
3. 解引用arr(*arr),得到的是数组首元素a,是个char类型,大小为1,所以输出1
4. arr[1]等价于,*(arr+1),得到的是第二个元素b,是个char类型,所以输出为1
5. &arr表示整个数组的地址,是个指针所以输出为4|8
6. &arr表示真个数组的地址,+1跳过整个数组,指向数组的下一个地址,是个指针,所以输出4|8
7. &arr[0],arr先跟[0]结合,是数组首元素,取数组首元素地址再+1,首元素地址的指针类型为char*类型,+1跳过一个字节,指向数组第二个元素b的地址。是个指针,所以输出4|8
三、字符数组长度
char arr[]={'a','b','c','d','e','f'};
1:printf("%d\n",strlen(arr));
2:printf("%d\n",strlen(arr+0));
3:printf("%d\n",strlen(*arr));
4:printf("%d\n",strlen(arr+1));
5:printf("%d\n",strlen(arr[1]));
6:printf("%d\n",strlen(&arr));
7:printf("%d\n",strlen(&arr+1));
8:printf("%d\n",strlen(&arr[0]+1));
PS:这样初始化字符数组,不会在数组后面默认放上