int a [ 5] = { 1,2,3,4,5 };
int* ptr = (int* ) ( &a + 1) ;
printf ( "%d,%d",* (a + 1), * (ptr - 1) ); //2,5
解释:&a取出一整个数组的地址,+1后跳到数组最后一个元素的后一个地址,类型是int(*)[5],是数组指针的类型,需要强制类型转换为int,才能赋给指针ptr,ptr-1到下标为4的元素,解引用得到元素5,a是首元素地址,+1得到第二个元素地址,解引用得到2
考察的是:指针类型决定了指针的运算!
这里结构体的大小是20个字节
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); //0x100014 +0x1就是+1,因为p指向的是结构体,大小为20个字节,所以这里的+1是指+20个字节,跳过一个结构体类型,20的十六进制是14,所以结果是0x100014
printf("%p\n",(unsigned long)p + 0x1); //0x100001 指针p强制类型转换为了整型,所以加1就是1
printf("%p\n",(unsigned int *)p + 0x1); //0x100004 指针p强制类型转换为了整型指针类型,指针类型+1,跳过的是该类型所占字节数的大小,所以这里的+1是跳过4个字节
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) ; //4,2000000
return 0;
}
解释:&a取出整个数组的地址,+1后到最后一个元素的后一块地址,ptr1指针就指向这里,输出ptr1指针时,ptr1[-1] == (ptr+(-1)) == * (ptr-1),所以-1后ptr1就指向元素4的起始地址,因为是int类型,访问4个字节,因为在小端存储模式下,数据低位在低地址,数据高位在高地址,所以读出来是00000004,就是4 ;
a指向首元素的地址,(int)a则将十六进制的地址强制类型转换为了整型,再+1,然后再转回指针类型,如0x0012ff44 --> int+1 -->0x0012ff45,因为地址都是相隔一个字节存放的,所以ptr2指向了01后一块地址,输出时解引用向后访问4个字节,因为小端存储,所以输出是02000000,即2000000
如果想要输出结果有0x,输出格式可写为:%#x
int main()
{
int a [3][2]= {(0,1), (2,3),(4,5)};
int* p;
p = a[0];
printf ("%d", p[0]); //1
return 0;
}
解释:这道题的重点不在于指针p,而是二维数组的初始化,二维数组正确初始化的话里面应是大括号,而现在使用的是小括号,小括号括起来的是一个逗号表达式,只取最后一个元素的值,所以该数组初始化的结果为
p[0] == *(p+0) == *p,而指针p指向首元素的地址,所以输出1
int main()
{
int a[5][5];
int (*p)[4];
p = a; //p:int(*)[4] - > a:int(*)[5];
printf ("%p, %d\n",&p[4][2] - &a[4][2],&p[4][2] - &a[4][2]); //FFFFFFFC,-4
}
解释:二维数组a是5行5列的,而数组指针p访问时是以4个元素为单位进行,虽然在p = a时会有警告类型不匹配,但指针p仍然指向数组a的首元素地址,分别找到a[4] [2]的地址和p[4] [2]的地址,如图所示,发现不是同一块地址,而地址相减的结果是地址之间元素的个数,而由因为是低地址减去高地址,所以是-4;
-4的原码:1000 0000 0000 0000 0000 0000 0000 0100
反码:1111 1111 1111 1111 1111 1111 1111 1011
补码:1111 1111 1111 1111 1111 1111 1111 1100
因为-4在内存中是以补码形式保存的,当以%p形式打印时,编译器会把-4看成一个地址,因为地址没有负数,所以将-4的补码转为十六进制就是FFFFFFFC
补码:1111 1111 1111 1111 1111 1111 1111 1100
因为-4在内存中是以补码形式保存的,当以%p形式打印时,编译器会把-4看成一个地址,因为地址没有负数,所以将-4的补码转为十六进制就是FFFFFFFC
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)