两个地址相差36,为16*2+4;其原因是因为&符号是将整个数组当做一个整体,再取其地址,也就是整个数组的首地址,而直接arr取得的地址是这个数组的首元素的首地址.倘若进行&arr+1操作,则是跳过整个数组,取得的地址就要在原有的地址上加上整个数组所占的字节数,而进行arr+1操作,只要在原基础上加上一个 int所占的字符数就可以.
4.函数指针
函数指针是一个指向函数的指针
形如void ( * pfun1 )() 是一个函数指针,其原因是 pfun1可以存放。pfun1先和*结合,说明pfun1是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。 5.函数指针数组 形如 int ( * parr [ 10 ])(); 则是一个函数指针数组 parr 先和 [] 结合,说明 parr 是数组,数组的内容是 int (*)() 类型的函数指针。接下来 进行一组练习题
1.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
其原因是a是元素的首元素地址,所以a+1是先将a进行隐式转换成指针a,在进行加一操作,得到此数组里第二个元素的地址,在进行*解引用操作,得到值为2
而&a是将数组a当做一个整体,取整个数组的地址,在进行加一操作,就是跳过整个数组,指针直接指向这个数组之后的第一个地址,在进行强制类型转换为int*类型,当ptr-1时,就是指这个指针向后偏移一个int ,指向了数组的最后一个元素5,在进行*操作,得到了结果为5.
2. struct Test { int Num ; char * pcName ; short sDate ; char cha [ 2 ]; short sBa [ 4 ]; } * p = (struct test*)0x100000 ; int main () { printf ( "%pn" , p + 0x1 ); printf ( "%pn" , ( unsigned long ) p + 0x1 ); printf ( "%pn" , ( unsigned int* ) p + 0x1 ); return 0 ;}
第一个结果为0x100014,其原因是因为p+0x1 就是将结构体指针p当做一个整体,并且跳过整个结构体,结构体的大小事20个字节,所以为0x100014;特别注意的是20个字节要转成16进制的数字,所以为14
第二个结果为00100001,其原因是(unsigned long)p结构体指针强制转换为一个long类型的整数,整数进行+1操作,得到00100001
第三个结果是因为(unsigned int*)p将将这个结构体指针强制转换为一个无符号的int* 类型,占四个字节,所以为0010004
3.
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 ; } 第一个结果的原因是&arr+1是指向这个数组向后的一个地址,在强制转换为一个int*类型,在打印的时候ptr[-1]相当于指针向前移动一个元素,指向了4



