学习了上一期的一些笔试题,这一期我们来看一些关于指针的笔试题:
下面就是一些关于指针的笔试题
笔试题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; }
//程序的结果是什么?
解析:
我们首先来解释一下第二行代码的意思:&a是取出整个数组的地址,+1跳过了整个数组指向,5后面的呢块地址,然后我们把它强制类型转换为int*,然后赋给ptr . *(ptr-1)的意思是,因为此时ptr 的类型是int *,-1向前移动一个字节,指向5 的起始地址,然后解引用得到的就是5, *(a+1)a是数组元素名,也是数组首元素,+1并且解引用指向第二个元素。所以打印结果为2 ,5
笔试题2
来看下面的几行代码,猜测会输出什么结果
//由于还没学习结构体,这里告知结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
int main()
{
p=(struct Test*)0x100000;
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
解析:
p是一个结构体指针,上面代码强调了结构体指针大小是20个字节,这里p+0x1是相当于+20,但是这里要注意是16进制,所以20应该转换为16进制然后在加; p原本是结构体类型的指针,但是这里被强制类型转换为(unsigned long)变成整型了,所以整数+1就是+1; p原本是结构体类型的指针,但是这里被强制类型转换为变成整型指针(unsigned int*)p,所以整型指针加1 就是+4.所以打印结果为0x100014 0x100001 0x100004
笔试题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; }
解析:
ptr1[-1]—>*(ptr1-1),所以这个和第一题类似,只是形式不同。我们具体来分析一下 * ptr2 a是数组名,也是数组首元素地址,我们把它强制类型转换为int,又+1,如果它作为地址的话,它就与起始地址差了一个字节,当我们又把它转换为int * 时我们就要具体分析一下他在内存中是如何存放的,假设我们的机器是小端。画图为例:数据在内存中就是这样存放的因为机器是小端,所以取出来,并按照16进制打印,所以打印结果就是0x4 0x2000000.
笔试题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; }
解析:
这道题,比较简单,但是有一个坑我们需要特别注意,数组初始化时{ (0, 1), (2, 3), (4, 5) ,这里是逗号表达式,只要这个注意到了,这个题做对还是比较简单的,其实数组是以下图的形式存放在 内存中的,这里的p[0]等价于 *(p+0)所以打印结果就是1
笔试题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;
}
解析:
这里的&p[4][2]== * (*(p+4)+2))具体看下面的图:我们之前知道数组随着下标的增长,地址是由低到高的所以 &p[4][2] - &a[4][2],是一个低地址,减一个大地址,而且指针减指针,计算的是之间差的元素个数 ,y以%d的形式打印就是-4,但是以%p的形式打印的就是FFFFFFFC -4 FFFFFFFC.
笔试题6
来看下面的几行代码,猜测会输出什么结果
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0; }
解析:
我们首先来看一下a数组在内存中的存放,我们是把这三个字符,放到数组中了吗?不是的,我们之前说过字符指针,这其实是把每个字符的起始地址,放到了数组a中。如下图所示:
pa++就指向了然后解引用我们就拿到了首字符a的起始地址,所以%s打印的就是 at
以上就是一些关于指针的笔试题
🌟Hello world 我们下期见!