这节主要解析几个指针运算的题加深对指针的理解。
题目一
#include <stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}程序结果是什么?
结果是2,5
首先看int * ptr = (int*)( &a + 1)
&a, 意思是拿到a数组的地址, 加上1就是偏移一个数组的大小,即偏移5个整形。然后强制类型转换成int*赋值给ptr,这个时候ptr是个野指针。
然后打印*(a + 1) 好说, 打印的是2, 然后*(ptr - 1), 意思是 ptr向后偏移一个整形, 本来ptr指向了a偏移5个整形的位置, 现在又向后偏移了一个位置, 所以,结果就是a偏移4个整形的位置。 也就是5那个位置。 所以打印是5.
答案2,5
题目二
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}输出结果是什么?
结果是0
首先p应该指向的是a这个二维数组的第一行。
a【0】是数组指针,但是被赋值给p后隐式类型转换成整形指针。 最后p【0】输出0.
题目三
#include <stdio.h>
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *ptr1 = (int *)(&aa + 1);
int *ptr2 = (int *)(*(aa + 1));
printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
输出结果是啥?
10,5
要知道输出是什么, 只需要直到ptr1, ptr2分别指向什么。
首先, ptr2好说, 就是二维数组和数组指针结合问题.aa是一维数组地址, 偏移一个单位变成第二行的数组地址。 然后赋值给ptr2同时隐式类型转换。 ptr2指向6的位置。
对于ptr1, &aa意思是拿到二维数组的地址, 加一直接偏移10个单位。 成为野指针。
然后赋值给ptr1, ptr1这个时候是个野指针。 指向10的下一个位置。 但是减一后向后偏移一个单位指向10, 所以打印10。
答案10, 5
-------------------------------------------------------------------------------------------------------------
题目四
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));分析分别打印什么
arr在sizeof中标识数组整体,所以第一个sizeof打印6.
arr + 0已经发生了计算, 这个时候整体标识一个地址, 所以第二个答案是4或者8
*arr解引用, 一个字符大小是1,所以第三题为1.
arr【1】同第三题, 大小是1。
&arr代表数组的地址, 既然是地址, 那么就是4或者8.
第六题同第五题, 都是地址。
第七题同样是地址。
题目五
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));
分析打印的结果是什么
第一题首先不确定。 因为字符数组arr没有\0,所以strlen不能判断大小。
第二题同样的, 没有\0不能判断。
第三题参数错误, strlen的参数应该是地址, 而不是一个字符常量。
第四题同第三题。
第五题:没有\0。
第六题: 对数组取地址再加1就跳过数组了。野指针。
第七题:同第六题。
题目六
char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));
分析打印的结果
第一题应该是7, 因为字符串后面默认有一个\0。
第二题加了0就是一个地址了。 所以4或8.
第三题1.
第四题同第三题, 1.
第五题地址, 4或者8.
第六题地址
第七题同样是地址。