文章目录
- 题目
- 答案与解析
- 1、
- 2
- 3
- 4、
- 5、
- 6、
- 7、
- 8、
题目
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
//由于还没学习结构体,这里告知结构体的大小是20个字节
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
p = (struct Test*)0X100000;
printf("%p\n", p + 0x1);//
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf( "%x,%x", ptr1[-1], *ptr2);
return 0;
}
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
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;
}
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char**cp[] = {c+3,c+2,c+1,c};
char***cpp = cp;
printf("%s\n", **++cpp);
printf("%s\n", *--*++cpp+3);
printf("%s\n", *cpp[-2]+3);
printf("%s\n", cpp[-1][-1]+1);
return 0;
}
答案与解析
重点知识点:
数组名在大多数情况下表示数组首元素的地址,但是两种情况除外
(1)sizeof(数组名),这时表示整个数组的大小
(2)&数组名,这时表示整个数组的地址
1、
答案:
解析:
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int* ptr = (int*)(&a + 1);//&a,取出的是整个数组的地址,加一,跳过整个数组的大小
printf("%d,%d", *(a + 1), *(ptr - 1));//这里两个都是int*类型的指针,且都是普通的加减一,都只跳过4个字节
return 0;
}
2
答案:
解析:
int main()
{
p = (struct Test*)0X100000;
//这里的p是结构体指针,加一跳过一个结构体大小的字节,跳过20个字节,由于是16进制,所以显示14
printf("%p\n", p + 0x1);
//这里将p强制转化为了unsigned long类型,非指针,加一就只是加1个字节
printf("%p\n", (unsigned long)p + 0x1);
//这里将p强制转化为了unsigned int* 类型,加一跳过一个Int类型的大小,4个字节
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
3
答案:
解析:
int main()
{
int a[4] = { 1, 2, 3, 4 };
//&a 取出的是整个数组的地址,加1跳过整个数组的大小(4 * 5 =20个字节)
int* ptr1 = (int*)(&a + 1);
//将p转化为Int 类型,加一就只会跳过一个字节
int* ptr2 = (int*)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
4、
答案:
解析:
int main()
{
//下面数组中的元素有逗号表达式:例:(0,1),这样只会取到1的值,所以数组元素是(1,3,5)
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int* p;
//a[0]是二维数组第一行的数组名,其内有1,3 两个元素
p = a[0];
//p[0] = 1
printf("%d", p[0]);
return 0;
}
5、
答案:
解析:
int main()
{
int a[5][5];
//数组指针类型
int(*p)[4];
//类型不一样,但是也可以存储,只是每次存储4个值
p = a;
//&p[4][2]-&a[4][2] = -4;将地址转化为16进制
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
6、
答案:
解析:
int main()
{
int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//&aa 是取整个数组的地址,加1跳过整个数组
int* ptr1 = (int*)(&aa + 1);
//aa 代表二维数组第一行的值,加1跳过5个元素
int* ptr2 = (int*)(*(aa + 1));
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
return 0;
}
7、
答案:
解析:
int main()
{
//是一个指针数组,存储的是美格字符串的首元素一直
char* a[] = { "work","at","alibaba" };
//二级指针来保存a的地址
char** pa = a;
//正常的加1,跳过一个元素
pa++;
printf("%s\n", *pa);
return 0;
}
8、
答案:
解析:
解析:
- c[]中存放的数据是每个字符串的首元素
- cp[]中存放的数据其实就是c中的反过来
- 对1:++cpp执行,指向c+2,解引用,得到c+2,再解引用得到了P的地址,打印出point
- 加号的优先级很低,先算其他的;打印的时候会把获得地址到\0之间的地址都打印
- 对2:++cpp执行,指向c+1,解应用得到C+1,指向N,–执行,指向E,解引用,得到E的地址,在加3,向后移3未,得到的是ENETR中第二个E的地址
- cpp已经经过了两次++,cpp[-2]得到得是跳转到C+3,得到F的地址,在进行解引用,跳到FIRST地址中,+3得到S的地址
- 对4:cpp还是指向c+1,cpp[-1]跳转到C+2,指向P,cpp[-1][-1]跳转到P的上一个NEW中,对其+1,得到E的地址