《指针进阶-3》

//——————————————————10. 指针笔试题
//笔试题1
//#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));//*(a+1):指的是数组a中第二个元素2
//    //(int*)(&a + 1),(int*)表示强制类型转换为(int*),(&a + 1)指的是整个数组的地址后面的那一位元素的地址,即5+1,*(ptr - 1)正好抵消+1,为5
//    return 0;
//}
程序的结果是什么?
2,5

笔试题2(整形+1与指针+1的区别)
//由于还没学习结构体,这里告知结构体的大小是20个字节
此代码在X86环境下才能运行,%p可以打印整形
struct Test
{
   int Num;
   char* pcName;
   short sDate;
   char cha[2];
   short sBa[4];
}*:此部分为结构体类型
//#include<stdio.h>
//struct Test                 
//{
//    int Num;
//    char* pcName;
//    short sDate;
//    char cha[2];
//    short sBa[4];
//}*p=(struct Test*)0x100000;//将0x100000赋值给p,并进行强制类型转换
假设p 的值为0x100000。 如下表表达式的值分别为多少?
//int main()
//{
//    printf("%p\n", p + 0x1);//p为整个结构体,+1跳过整个结构体,即在十六进制的基础上+20。
//    //0x1=十六进制的1,即 p + 0x1=p+1//0x100014
//    printf("%p\n", (unsigned long)p + 0x1);//unsigned long:无符号长整型。
//    //为整数则p为1048576(0x100001的十进制),+1为1048577=0x100001
//    printf("%p\n", (unsigned int*)p + 0x1);//强制类型转换为unsigned int*,无符号整型指针,
//    //+1跳过一个无符号整型的大小,4个字节。0x100000+4//0x100004
//    return 0;
//}//结果为
00100014
00100001
00100004

//笔试题3
//#include<stdio.h>
//int main()
//{
//    int a[4] = { 1, 2, 3, 4 };
//    int* p1 = (int*)(&a + 1);//(&a + 1)中a取出的是整个数组的地址,+1指向数组外面的位置,假设为‘5’
//    int* p2 = (int*)((int)a + 1);//((int)a + 1),首元素地址a先被强制类型转换为int,所以a不是首元素地址,而是整型值,+1就是数值+1
//    printf("%x,%x", p1[-1], *p2);//ptr1[-1]==*(ptr1+(-1))==*(ptr-1)
//    return 0;
//}//结果为4,200000
如图所示
a=01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00(小端存储模式,小放小,大放大)
  低地址                                高地址
a=0x12ff40
a+1=0x12ff44//a为整个数组//差4个字节
ptr1:指向‘04 00 00 00’的最后一个‘00’的后面,-1指向‘04’,*后访问的是‘04 00 00 00’的值,则拿出来的值为‘00 00 00 04’
%x为十六进制打印(有效数字前面的0不打印),为‘4’
ptr2:
(int)a+1=0x12ff41//a先被强制类型转换为整型//差1个字节,即‘01’的位置是0x12ff40,
+1后就指的是01后的00,地址为0x0012ff41,相差一个字节。
(int*):地址强制类型转换为int*,从而把它当成指针分给ptr2,因此ptr2指向01后的00的位置,
因为是整型占4个字节,所以ptr2的整型所指为‘02 00 00 00’由于是小端存储,所以值为2
*ptr2:ptr2本身为一个整型指针,则从‘00’向后访问一个整型(四个字节),*整型指针访问一个整型,
即访问的是‘02 00 00 00’%x为十六进制打印(有效数字前面的0不打印),为‘2 00 00 00’

//笔试题4
//#include <stdio.h>
//int main()
//{
//    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//    //此处有坑,正常二维数组初始化为int a[1][2]={{1,2}.{3,4}};图形为:1 2 3 4
//    int* p;//而此处是((0,1),(2,3),(4,5))考的是逗号表达式(从左向右以此计算),
//    //即整个表达式结果为最后一个表达式的结果,因此初始化为(1,3,5)
//    p = a[0];//a[0]=a[0][0]二维数组第一行第一个元素1
//    printf("%d", p[0]); //p[0]为第一行第一个元素:1//p[0]=*(p+0)=*p
//    return 0;
//}//结果为1

笔试题5
// #include<stdio.h>
//int main()
//{
//    int a[5][5];//二维数组的数组名a表示第一行的地址,类型为int(*)[5]
//    int(*p)[4];//p:数组指针,指向一个有四个整型元素的数组.类型:int(*)[4]
//    p = a;//第一行的地址赋给p,虽然a为5行5列,并且p指向a的开始端,p+4:p每次跳过4个整型
//    printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//p[4][2]==*(*(p+4)+2)
//    return 0;
//}//结果为:fffffffc,-4
-4的原码:10000000 00000000 00000000 00000100
-4的反码:11111111 11111111 11111111 11111011(符号位不变,其余的按位取反)
-4的补码:11111111 11111111 11111111 11111110(反码+1)
4个二进制位=1个十六进制位-->fffffffc,c=12


笔试题6
// #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,同理于笔试第三题

笔试题7
//#include <stdio.h>
//int main()
//{
//    char* a[] = { "work","at","alibaba" };
//    char** pa = a;//a为首元素地址work
//    pa++;//+1==a[1]==at
//    printf("%s\n", *pa);
//    return 0;
//}结果为at


笔试题8
// #include<stdio.h>
//int main()
//{
//    char* c[] = { "ENTER","NEW","POINT","FIRST" };//c数组的元素都是char*
//    char** cp[] = { c + 3,c + 2,c + 1,c };//cp数组的元素都是char**//c为首元素地址:ENTER,
//    //则c + 3=FIRST。c + 2=POINT。c + 1=NEW。c=ENTER
//    char*** cpp = cp;//cp为首元素地址:FIRST,cpp指向FIRST
//    printf("%s\n", **++cpp);//++cpp=cpp+1=cp+1=c+2,cpp+1指向POINT,打印POINT
//    printf("%s\n", *-- * ++cpp + 3);//++cpp=cpp+1=cp+2=c+1,--cpp==cpp=cp+3=c,
//    //*后拿到的是'ENTER'中‘E’的地址,+3为‘E’,打印为ER
//    printf("%s\n", *cpp[-2] + 3);//*cpp[-2]=*(*(p-2)),cpp指向cp[2],cpp-2指向cp[0],
//    //*后指向的是'FIRST',+3指向'FIRST'的's'打印为ST
//    printf("%s\n", cpp[-1][-1] + 1);//cpp[-1][-1]=*(*(cpp-1)-1),cpp指向cp[2],cpp-1指向cp[1],
//    //*后拿到的是c+2:POINT,-1后拿到的是c+1:NEW,+1后指向‘NEW’的‘E’打印为EW
//    return 0;
//}//结果为
POINT
ER
ST
EW

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值