指针笔试题

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

image.png
&a取出的是整个数组的地址,&a+1跳过整个数组,把&a+1这个数组指针(int()[5])强制类型转换为(int)赋给ptr,ptr-1就是数组中5的地址。
a表示首元素的地址,a+1表示第二个元素的地址

笔试题2

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//p=(struct Test*)0x100000
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节(X86环境)
int main()
{
	printf("%p\n", p + 0x1);
	//因为p是一个结构体指针,这里结构体test的大小是20字节
	//所以+1,相当于加20字节。0x100000+20 --> 0x100014
	printf("%p\n", (unsigned long)p + 0x1);
	//把p强制类型转换为无符号的长整型,16进制转换为10进制:1048576
	//1048576+1 --> 1048577 转换为16进制:0x100001
	printf("%p\n", (unsigned int*)p + 0x1);
	//把p强制类型转换为无符号的整型指针,+1相当于跳过四个字节
	//0x100000+4 --> 0x100004
	return 0;
}

笔试题3

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    int* ptr1 = (int*)(&a + 1);
    int* ptr2 = (int*)((int)a + 1);
    //假设a的地址:0x0012ff40
    //a+1 --> 0x0012ff44
    //(int)a+1 --> 0x0012ff41 这里先把a强制转换为整型
    //整型加1就是加1,整型地址加1是跳过4个字节
    printf("%x,%x", ptr1[-1], *ptr2);
    // %x 打印的是十六进制
    //ptr1[-1] --> *(ptr1+(-1) --> *(ptr1-1)
    return 0;
}

image.png
int* ptr2 = (int*)((int)a + 1);
因为ptr2是整型指针,指向后面四个字节,又因为是小端存储模式,所以打印出来应该是0x02000000
image.png

笔试题4

#include <stdio.h>
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    //注意区分 {{0,1},{2,3},{4,5}};
    //这里的(,)是逗号表达式,实际上数组内容是1,3,5
    int* p;
    p = a[0];
    //a[0]没有放到sizeof内部,所以他表示第一行第一个元素的地址
    printf("%d", p[0]);
    //p[0] --> *(p+0) --> *p
    return 0;
}

image.png

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

解题思路:
1、a的类型:int()[5];p的类型:int()[4];把a赋给p,p默认+1跳过四个字节
2、p[4][2] --> ((p+4)+2)
image.png
&p[4][2] - &a[4][2] 的结果为-4
-4的补码为1111 1111 1111 1111 1111 1111 1111 1100;转换为16进制:FF FF FF FC
image.png

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

image.png
image.png

笔试题7

#include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 return 0;
}

image.png
image.png

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

由前三条语句可得下图:
image.png
printf("%s\n", **++cpp);cpp第一次++,由cp[0]指向了cp[1],解引用cp[1],得到c[3],解引用得到POINT
image.png
printf("%s\n", *--*++cpp+3);+(加号)的优先级比较低,所以在这里cpp再一次++并解引用,指向cp[2],c+1前置–,得到c,指向c[0],解引用得到ENTER,+3得到ER
image.png
printf("%s\n", *cpp[-2]+3);*cpp[-2] <==> **(cpp-2);cpp-2指向cp[0],解引用得到c+3,解引用得到FIRST,+3得到ST
image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值