八大指针笔试题带你overcome指针

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 八大指针笔试题带你overcome指针

前言

上期关于指针的文章,我们用多个试题对指针与数组的关系进行了全面多方位的讲解。这期文章我们将用八道经典的指针笔试题来全面多方位来了解指针。

第一题

答案是多少呢?为什么是这个答案呢?

int main()
{
 int a[5] = { 1, 2, 3, 4, 5 };
 int *ptr = (int *)(&a + 1);
 printf( "%d,%d", *(a + 1), *(ptr - 1));
 return 0;
}

解析

首先,我们知道:a是数组首元素的地址,而&a是取出的整个地址。所以a+1就是第二个元素的地址,解引用就是2。&a+1就是跳过整个数组,在5元素的后面,强制类型为int就意味着它后面地址加减的单位都是int类型。ptr就是&a+1的地址,所以ptr-1就是向前减一个int类型,就指向了5的地址,解引用就是5。

第二题

假设p 的值为0x100000。 如下表表达式的值分别为多少?
已知,结构体Test类型的变量大小是20个字节

struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
int main()
{
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
} 
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
int main()
{
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
}
struct Test
{
 int Num;
 char *pcName;
 short sDate;
 char cha[2];
 short sBa[4];
}*p;
int main()
{
 printf("%p\n", p + 0x1);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
}

分析

通过提示,我们知道他是一个结构体指针类型,大小为20个字节,地址为0x100000。0x1就是p+1就是加一个20大小的结构体类型,就是0x100000+20=0x100014。unsigned long p 就是将p转化为整型,整型加1就是加1.结果就是0x100000+1=0x100001 unsigned int* p就是将p转化为指针类型,所以p+1就是加了一个指针大小0x100000+4=0x100004

第三题

答案是多少?为什么是这样呢?

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

分析

a是首元素的地址,&a+1取出的是整个数组的地址 int*(&a+1)就是将&a+1的类型转化为int*的类型,ptr[-1]可以理解为*(ptr-1),ptr就是&a+1,所以ptr-1就是减一个int*类型大小,所以就在元素4的地址,解引用就是4 int a就是将地址a转化为整型,整型加1就是加1 ,我们又知道,在内存中一个地址就是一个字节,这里加1,所以a+1指向的内容就是00到02 0x02000000

第四题

答案是什么呢?为什么呢?

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

解析

通过观察:我们可以发现,a数组里面是(),所以是逗号表达式,保留右边的值,所以()里的值是1,2,3未满就补0,后面都是0,所以数组中布局就是画图后的样子。

p是a[0]的地址,而a[0]是代表的第一行,我们可以把a[0]理解为第一行的数组名,所以a[0]是首元素的地址,解引用就是1

第五题

答案是多少呢?为什么是这样呢?

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

解析

a数组是一个五行五列的二维数组 a是起始元素的地址 将a的地址赋给p 且q是一个数组指针 p的类型是int[4]。

所以p每加一跳过4个元素 所以p[4]就相当于*(p+4) p的地址就是画图后的地址 两地址相减结果就是中间元素的个数 所以&p[4][2]-&a[4][2]=-4

我们知道电脑中存的都是补码原码10000000000000000000000000000100

反码11111111111111111111111111111011

补码11111111111111111111111111111100

以%P打印就直接把补码当做地址打印了
以%d打印还是-4

第六题

答案是多少呢?为什么是这样呢?

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

解析

aa是首元素的地址,就是第一行的地址 &aa取出的是整个二维数组的地址
ptr1=&aa+1 &aa+1被转化为int*类型 所以ptr-1,就是减去一个int*类型大小,这时ptr指向10元素的地址,解引用为10

aa+1就是第一行的地址加1到第二行的地址,我们发现aa+1的类型也是int*,前面的int*就没用了。就可以理解为:int*ptr=*(aa+1),我们又可以把*(aa+1)理解为aa[1],aa[1]为第二行数组名,就是首元素地址,又因为ptr==*(aa+1)==aa[1],所以ptr-1就是指向元素5,解引用就是5

第七题

答案是多少呢?为什么是这样呢?

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

解析

我们要知道数组a里面存的char*类型的元素,是work,at,alibaba首元素的地址

用二级指针存放a的地址,pa==a,pa++==a++,a是首元素的地址,pa++==a++就是第二个元素的地址。

*pa就是at首字母的地址,%s就是通过首字符地址打印这一串字符

第八题

答案是多少呢?为什么是这样呢?

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

解析

c数组存放的是字符串首元素的地址,cp数组存放的是这些首元素的地址的地址,cpp存放的是cp的地址。这里我们还要注意一个点:++和--是直接改变了它们的值,会影响后面的计算的。


目录
相关文章
|
6月前
|
C语言
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
C语言:数组和指针笔试题解析(包括一些容易混淆的指针题目)
|
6月前
|
C语言
指针和数组笔试题解析(最详细解析,没有之一)
指针和数组笔试题解析(最详细解析,没有之一)
49 0
|
6月前
|
存储 编译器 C语言
经典指针与数组笔试题——C语言
经典指针与数组笔试题——C语言
|
5月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
6月前
|
存储 编译器 C语言
C语言初阶⑦(指针初阶)知识点+笔试题(上)
C语言初阶⑦(指针初阶)知识点+笔试题
39 0
|
5月前
|
存储 C++
有关【指针运算】的经典笔试题
有关【指针运算】的经典笔试题
31 4
指针与数组笔试题解析
指针与数组笔试题解析
|
6月前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(上)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
42 0
|
6月前
指针笔试题模拟
指针笔试题模拟
30 0
|
6月前
进阶指针笔试题
进阶指针笔试题
34 0