进阶指针笔试题

1.

int main()
{
	int a[5] = { 1,2,3,4,5 };
	int* ptr = (int*)(&a + 1);  //&a 拿到整个数组的地址 +1 跳过整个数组 然后强制类型转换成(int*)改变步长
	printf("%d %d", *(a + 1), *(ptr - 1));//a为首元素地址 +1为第二个元素地址2  ptr为数组后面的地址 -1得到5
	return 0; //       2           5
}

2.

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//已知,结构体Test类型的变量大小是20个字节
//假设p的值为0x100000。如下表达式的值为多少?
int main()
{                          //本题考查的是指针+1到底加几个字节
	p = (struct Test*)0x100000;
	printf("%p\n", p + 0x1);   //p为结构体指针 大小为20个字节 所以+1跳过20个字节 0x100014     00100014
	printf("%p\n", (unsigned long)p + 0x1); //p强转成8字节的unsigned long型(不是指针) +1就单纯+1 0x100001被当做地址打印 00100001
	printf("%p\n", (unsigned int*)p + 0x1);//p强转成4字节(x86环境)的整形指针 +1跳过4个字节 0x100004  00100004
	return 0;
}

3.

int main()
{
	int a[4] = { 1,2,3,4 }; //一个字节一个地址 地址+1 跳过一个字节
	int* ptr1 = (int*)(&a + 1);   //跳过整个数组 强转int* 调整步长
	int* ptr2 = (int*)((int)a + 1);//把首元素地址强转成int类型+1 地址跳过一个字节  存入ptr2
	printf("%x,%x", ptr1[-1], *ptr2); // 如果是小端 01 00 00 00 02 00 00 00 跳过01 访问四个字节小端逆序得到02000000
	return 0;        //  4  02000000    
}

4.

#include<stdio.h>
int main()
{
	int a[3][2] = { (0,1),(2,3),(4,5) };//数组初始化应用{} 这个是逗号表达式 
	int* p;             //数组初始化为13 50 00
	p = a[0];           //p存放首行地址
	printf("%d", p[0]);//p[0]等价于 *(p+0) 为第一个元素 1 
	return 0;  //  1
}

5.

#include<stdio.h>
int main()
{
	int a[5][5];//5行5列的二维数组
	int(*p)[4];// 数组指针 指向4个int大小元素的数组
	p = a;    //&p[4][2]->*(*(p+4)+2)  p+1 跳过4个int +4 跳过16个int 
	          //解引用向后访问4个int +2 在解引用 得到第三个元素->第19个元素
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);//&a[4][2]->第23个元素
	return 0;//低地址-高地址   FFFFFFFC              -4
}//  -4 的原码 10000000000000000000000000000100
 //       反码 11111111111111111111111111111011
//        补码 11111111111111111111111111111100
// 按地址打印   F   F   F   F   F   F   F   C

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* 改变步长
	int* ptr2 = (int*)(*(aa + 1));//第一行+1 为第二行地址 解引用 为第二行首元素地址 改变步长
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));// 10      5
	return 0;  
}

7.

int main()
{
	char* a[] = { "work","at","alibaba" }; //指针数组a[0]存放w的地址 a[1]存放 a的地址 a[2]存放 a的地址 
	char** pa = a;  //a为首元素 a[0]的地址 存放在 二级指针pa中
	pa++;          //pa放的是 a[0]的地址 +1 指向a[1]的地址
	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);        // POINT
	printf("%s\n", *-- * ++cpp + 3);//ER
	printf("%s\n", *cpp[-2] + 3);   //ST
	printf("%s\n", cpp[-1][-1] + 1);//EW
	return 0;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sessy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值