目录
一.
int main ()
{
int a [ 5 ] = { 1 , 2 , 3 , 4 , 5 };
int * ptr = ( int * )( & a + 1 );
printf ( "%d,%d" , * ( a + 1 ), * ( ptr - 1 ));
return 0 ;
}
程序运行的结果是什么?
1.1分析
&a在这里取得的是整个数组的地址,&a+1后跳到数组的最后;
ptr所存放的地址就是数组结束的后面(元素”5“的后面的地址),类型为int (*)[5];
再强制类型转化为int (*);
*(a+1)这里的a代表数组首元素的地址,加一后解引用表示第二个元素,结果为2;
*(ptr-1)表示原来在“5”的后面,减1后,指向5的地址,解引用为5.
结果展示
1.2代码
#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;
}
//程序的结果是什么?
二.
struct Test
{
int Num ;
char * pcName ;
short sDate ;
char cha [ 2 ];
short sBa [ 4 ];
} * p ;
// 假设 p 的值为 0x100000 。 如下表表达式的值分别为多少?
// 已知,结构体 Test 类型的变量大小是 20 个字节
int main ()
{
printf ( "%p\n" , p + 0x1 );
printf ( "%p\n" , ( unsigned long ) p + 0x1 );
printf ( "%p\n" , ( unsigned int* ) p + 0x1 );
return 0 ;
}
/*注:这里是在x86的环境下运行。
2.1解析
首先我们要知道*p为结构体指针;
p+ox1表示的是地址加1,p为结构体指针,加一跳过20个字节,结果为0x100014;
(unsigned long)p是将指针转化为无符号长整形的数,数字加一,再以地址的形式输出,结果为0x100001;
(unsigned int*)p是先将p转化为无符号整形指针类型,加一,跳过4个字节,结果为0x100004;
结果展示
/*注:这里我们的地址只是假设的。
2.2代码
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
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 ;
}
3.1解析
&a+1指向的是数组结尾的后面,类型为int (*)[]4;在强制类型转化为int(*);
ptr1[-1]等价于*(ptr1-1),类型为int *, 这里输出结果为4;
(int)a+1是想将a类型转化为int ,再加上1,a原先是地址,转化成int ,是将地址转化成int 型,如图(这里为小端存储)
*ptr2为2 00 00 00
结果展示
3.2代码
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;
}
本文含有隐藏内容,请 开通VIP 后查看