指针笔试题

作者 :ふり

专栏 :C语言进阶

格言 : 知行并进

在这里插入图片描述

💨 指针的笔试题


👉 笔试题(一)


#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;
}
//程序的结果是什么

答案 :2,5


#include<stdio.h>
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) 相当于 首元素地址加一得到第二个地址,解引用得到第二个数
  //ptr - 1 得到最后一个数的地址,解引用得到值
  
	return 0;
}

👉 笔试题(二)


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

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


答案 :


#include<stdio.h>
//这里告知结构体的大小是20个字节
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}* p = (struct Test*)0x100000;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
	printf("%p\n", p + 0x1);//0x100014
	//结构体指针加 1 跳过一个结构体大小
    //0x100000 + 20 -->0x100014

	printf("%p\n", (unsigned long)p + 0x1);//0x100004
	//0x100000 的整数是 1048576 +1 -> 1048577
	//0x100001


	printf("%p\n", (unsigned int*)p + 0x1);//0x100004
	//转换成无符号整型指针,加 1 跳过整个结构体
	//0x100000 + 4 --> 0x100004
	return 0;
}

👉 笔试题(三)


#include<stdio.h>
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;
}

答案 :4,2000000


在这里插入图片描述


👉 笔试题(四)


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

答案 : 1


int main()
{
	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
	//正常二维数组初始化应该是大括号
	//小括号是逗号表达式
	//int a[3][2] = { 1, 3, 5 };
	int* p;
	p = a[0];
	//a[0] 第一行的数组名,首元素地址,&a[0][0]
	printf("%d", p[0]);
	return 0;
}

👉 笔试题(五)


#include<stdio.h>
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;
}

答案 :


在这里插入图片描述


👉 笔试题(六)

#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

#include <stdio.h>
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int* ptr1 = (int*)(&aa + 1);
	//&aa 是整个二维数组的地址

	int* ptr2 = (int*)(*(aa + 1));
	//数组名是首元素的地址

	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}


👉 笔试题(七)


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

答案 : at
在这里插入图片描述
pa++是指向下一位,就是at


👉 笔试题(八)


#include <stdio.h>
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;
}

解析 :
POINT
ER
ST
EW


在这里插入图片描述

++cpp 解引用指向 c+2, c+2 指向的是 POINT

在这里插入图片描述

cpp 再次自加解引用指向 c+1 ,然后 c+1 自减变成 c , 指向 ENTER ,首元素地址 + 3 得到 ER

在这里插入图片描述

cpp - 2 解引用指向 c + 3 ,解引用指向 FIRST,首元素地址 + 3 得到 ST

在这里插入图片描述

cpp[-1][-1]+1 - - -> *( *( cpp - 1) - 1 ) + 1; 第三个元素的地址,cpp-1指向第二个元素的地址,解引用得到 c + 2 ,再 - 1 得到 c + 1 , c + 1就是
NEW 的地址,在解引用得到 NEW, + 1得到 EW


💙 总结

所以说指针这方面还是要学会画内存中的图,通过图来判断分析,不可以想当然。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值