前言
上期我们介绍了strlen、sizeof的各种用法,本期带大家来学习指针类的笔试题。大家也要多多思考才行。
指针笔试题
首先我们来了解两点:
%p是打印地址
%x是以16进制形式打印
题一
#include<stdio.h> int main() { //程序的结果是什么? int a[5] = { 1, 2, 3, 4, 5 }; int *prt = (int *)(&a + 1); printf( "%d,%d", *(a + 1), *(prt - 1)); return 0; }
输出:2,5
分析:
我们知道 &a+1 里 &a 取出的是整个数组地址(&a的类型是 int(*)[5] ,该类型大小为5个字节长度) +1 是跳过整个数组,指向的位置如图:
前面加个 (int *) 是强制类型转换的意思,将 int( * )[5] 类型强制转换为 int 类型,那么该类型的变量加一减一所跳过长度就是4字节(上期有讲过指针变量加一减一步长)
因此,prt - 1 所指向的位置如下图:
解引用就得到 5 ,(a + 1)==>a[1] ,也就是2.
题二
我们来看一道关于结构体指针的例题:
#include<stdio.h> 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; //因为0x100000的类型是int型,所以要强制类型转换 printf("%p\n", p + 0x1); printf("%p\n", (unsigned long)p + 0x1); printf("%p\n", (unsigned int*)p + 0x1); return 0; }
本题考查指针加一步长多少?
输出:
分析:
p = (struct Test*)0x100000; printf("%p\n", p + 0x1); //00100014 //指针 p 所指向的类型是 struct Test ,该类型占20字节单位,因此加一跳过20字节。 printf("%p\n", (unsigned long)p + 0x1); //00100001 //强制类型转换为 unsigned long 类型,就是一个整数,整数加一就是加一个字节 printf("%p\n", (unsigned int*)p + 0x1); //00100004 //强制类型转换为 unsigned int* 类型,p就指向一个无符号整型,占4个字节,加一就是加4个字节
题三
#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
分析:
int a[4] = { 1, 2, 3, 4 }; int* ptr1 = (int*)(&a + 1); //&a取出整个数组地址,加一跳过整个数组,强制类型转换为int *型,prt1指针指向下图1位置 int* ptr2 = (int*)((int)a + 1); //将首元素地址强制类型转换为整型,加一跳过一个字节,再转换回来,int*类型解引用访问4个字节,见图二 printf("%x,%x", ptr1[-1], *ptr2); //prt1[-1]==>*(prt1-1),prt1-1指向下图1位置
图一:
图二:
题四
#include <stdio.h> int main() { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; 数组的初始化内容有逗号表达式,实际上数组初始化的是1,3,5 //如果要将上数全部存进去,可以这样写{{0,1},{2,3},{4,5}},或者{0,1,2,3,4,5} int* p; p = a[0]; printf("%d", p[0]); return 0; }
输出:1
解析:
int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int* p; p = a[0]; //将a[0][0]存放入p中 printf("%d", p[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; }
输出:
解析:
p的首地址指向a的首地址,我们将数组a画出来,指针p指向的数组是4个元素,如下:
所以,p[4][2]和a[4][2]如图:
&p[4][2] - &a[4][2],指针相减结果就是两地址间的元素个数,就是4,但是它是小的减大的所以是-4,以%p打印就是FFFFFFFC,以%d打印就是-4