bilibiliclass41_C语言_指针的进阶_指针和数组笔试题解析

指针笔试题

笔试题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;
}
//程序的结果是什么?

解析:
 

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

笔试题2

//已知结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}* p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
printf("%p\n", p + 0x1);

printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int)p + 0x1);
return 0;
}

解析:
指针+-整数

 

//结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}* p;//结构体指针
//假设p 的值为0x100000。
int main()
{
printf("%p\n", p + 0x1);
// 123456789abcdefg
// 0x1==1
// 20->16+4->14
// 0x100014
printf("%p\n", (unsigned long)p + 0x1);
// 整数+1=整数
// 0x00100014->1048576
// 1048576+1==1048577==0x00100001
// 0x100001
printf("%p\n", (unsigned int)p + 0x1);
// 整形跳过4
// 0x00100004
return 0;
}


笔试题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;
}

解析:
内存(小端存储)
01 00 00 00 | 02 00 00 00  | 03 00 00 00 | 04 00 00 00
低地址                                                                高地址

//%x意思是16进制输出( 以16进制输出变量地址)
int main()
{
   int a[4] = { 1, 2, 3, 4 };
   int *ptr1 = (int *)(&a + 1);
   int *ptr2 = (int *)((int)a + 1);
   //(int)a-->首元素地址转整形,例如0x00000005
   //(int)a+1-->整形+1=整形(向后访问一个字节),例如5+1=6
   //地址,例如0x00000006
   printf( "%x,%x", ptr1[-1], *ptr2);
   //ptr1[-1]==*(ptr1+(-1))=*(ptr1-1)
   //4->0x00 00 00 04
   
   //00 00 00 | 02
   //0x02000000
   //0x02 00 00 00
   return 0;
}


笔试题4

#include <stdio.h>
int main()
{
   int a[3][2] = { (0, 1), (2, 3), (4, 5) };
   int *p;
   p = a[0];
   printf( "%d", p[0]);
return 0;
}

解析:

#include <stdio.h>
int main()
{
   int a[3][2] = { (0, 1), (2, 3), (4, 5) };//逗号表达式{1,3,5}
   int *p;
   p = a[0];//1 3
   printf( "%d", p[0]);//1
return 0;
}
// right
// 1 3
// 5 0
// 0 0

//err idea
// 0 1 --p--p[0]==0
// 2 3
// 4 5


笔试题5

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 a[5][5];
   int(*p)[4];//指向四个元素数组的指针
   p = a;//首元素a[0]的地址
   printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
   //结果FFFFFFFC和-4
   return 0;
}

 a[0]     a[1]        a[2]      a[3]            a[4]  
|****|*   ***|**      **|***    *|**|**         **|***
|      |        |            |         |   |               |
P    p+1   p+2       p+3   p+4 p[4][2]   a[4][2]

p[4][2]==*(*(p+4)+2)
&p[4][2] - &a[4][2]//指针相减==指针中间有几个元素==4
//小-大==-4
//%d打印-4原码10000000 00000000 00000000 00000100
10000000 00000000 00000000 00000100原码
11111111 11111111 11111111 11111011反码
11111111 11111111 11111111 11111100补码
//%p打印地址,-4在内存中用补码存储,直接看成地址打印
11111111 11111111 11111111 11111100
F   F    F    F     F   F    F   C
FFFFFFFC

 

笔试题6

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()
{
   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));
   //10和5
   return 0;
}


1 2 3 4 5 |6 7 8 9 10|
               |                |
               |                &aa+1
              aa+1
*(aa + 1)==aa[1]第二行首元素的地址
第二行的地址 解引用 等于 第二行的数组名aa[1]

 

笔试题7

#include <stdio.h>

int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}

解析:
 

#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
//char* p="abcdef";//存的是a的地址
//a
// char* "work"
// char* "at"
// char* "alibaba"
char* *pa = a;
//a == 首元素的地址 == 首元素是指针是"work"的地址 == 指针的地址是二级指针
//*pa表明是指针
//char*是指向的类型
pa++;
//跳过一个char*的字节数
//指向"at"的指针
printf("%s\n", *pa);
//at
return 0;
}

 


笔试题8

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;
}


解析:

//%s在C语言中代表字符串型格式符。
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char* *cp[] = {c+3,c+2,c+1,c};
char** *cpp = cp;
printf("%s\n", **++cpp);//打印POINT
printf("%s\n", *--*++cpp+3);//打印出ER
printf("%s\n", *cpp[-2]+3);//打印出ST
printf("%s\n", cpp[-1][-1]+1);//打印出EW
return 0;
}


c数组
char* 存放"ENTER"首字符地址
char* 存放"NEW"首字符地址
char* 存放"POINT"首字符地址
char* 存放"FIRST"首字符地址

cp[]数组
char**指针 c+3"FIRST"
char**指针 c+2"POINT"
char**指针 c+1"NEW"
char**指针 c"ENTER"

cpp指针指向cp[]数组
cpp指向cp首元素的地址

**++cpp
++cpp//c+2的地址
*++cpp//拿到c+2的内容
**++cpp//通过c+2的内容,拿到"POINT"
//打印POINT

*--*++cpp+3
cpp//c+2的地址
++cpp//指向c+1的地址(由于上一条语句已经改变了)
*++cpp//拿到c+1的内容
--*++cpp//拿到c的内容
*--*++cpp//拿到ENTER的内容
*--*++cpp+3//拿到E的地址
//打印出ER

*cpp[-2]+3
cpp//c+1的地址
cpp-2//c+3的地址
cpp[-2] == *(cpp+(-2)) == *(cpp-2)//拿到c+3
*cpp[-2]+3//拿到S的地址
//打印出ST

cpp[-1][-1]+1
cpp[-1] == *(cpp-1)
cpp[-1][-1] == *(*(cpp-1)-1)
cpp[-1][-1]+1 == *(*(cpp-1)-1)+1
cpp//c+1的地址
cpp-1//c+2的地址
*(cpp-1)//拿到c+2
*(cpp-1)-1//拿到c+1
*(*(cpp-1)-1)//拿到NEW,就是N的地址
*(*(cpp-1)-1)+1//拿到E的地址
//打印出EW

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值