wap网站建设费用,上海建筑建材业网官网,网站建设技术服务,手工制作大全视频教程目录 前言
1、案例一
1.1 答案
1.2 解析
2、案例二
2.1 答案
2.2 解析
3、案例三
3.1 答案
3.2 解析
4、案例四
4.1 答案
4.2 解析
5、案例五
5.1 答案
5.2 解析
总结 前言 “纸上得来终觉浅#xff0c;绝知此事要躬行”。本篇通过对指针实际案例的分析…目录 前言
1、案例一
1.1 答案
1.2 解析
2、案例二
2.1 答案
2.2 解析
3、案例三
3.1 答案
3.2 解析
4、案例四
4.1 答案
4.2 解析
5、案例五
5.1 答案
5.2 解析
总结 前言 “纸上得来终觉浅绝知此事要躬行”。本篇通过对指针实际案例的分析由浅入深来加强我们对指针的理解。
1、案例一
#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;
} 先自己想想下面公布答案。
1.1 答案 答案是25。
1.2 解析 其实第一个输出的2比较好理解主要是第二个输出可能会有疑问。 对于*a1本身a表示数组的首元素地址a1表示数组的第二个元素的地址因此解引用a1得到的结果就是数组的第二个元素的值2。解引用就是* 对于*ptr-1首先我们看看ptr是什么前面定义 ptr int*a 1 首先a表示将整个数组的地址取出来其类型为 int*[5]大小是5个整型的大小所以a1直接跳过整个数组指向数组后面一个位置的地址但是最后又通过int*强制将其转化成了int*类型步长变回一个整型的大小所以ptr其实就是指向数组最后一个元素后面一个位置地址的指针类型为int*类型步长为1个整型数据的大小。因此输出时ptr-1其实只往回跳了一个整型大小的长度指向了数组第五个元素最后一个元素再解引用得到的答案就是5啦。 2、案例二
#include stdio.h
struct Test
{int Num;char* pcName;short cha[2];short sBa[4];
}*p (struct Test*)0x100000;
//假设p 的值为0x100000。如下表达式的值分别为多少。
//已知结构体Test类型的变量大小是20字节。
//x86环境
int main()
{printf(%p\n, p 0x1);printf(%p\n, (unsigned long)p 0x1);printf(%p\n, (unsigned int*)p 0x1);return 0;
} 这是一道结构体指针的运算定义结构体*p其值设定为0x100000。在x86环境下进行了三种不同的运算分析结果。 2.1 答案 答案是00100014 00100001 00100004 2.2 解析 对于 p0x1是将结构体指针p1由于p是结构体指针所以其步长为1个结构体的长度题目说这样一个结构体长度为20其实可以通过自己计算结构体的内容得出所以加1直接跳过20个字节因此输出结果为00100014。16进制20就是14。 对于unsigned longp 0x1,将p强制转换成了无符号长整型p已经不再是指针变成了一个长整型1,048,567。加1变成1,048,568。输出时用的%p也就是地址类型的输出因此是16进制1,028,568转换回16进制就是00100001。 对于unsigned int*p 0x1将p转化成了无符号整型指针那其步长就变为了4p1就指向4字节后的地址因此对p1输出结果为00100004。 3、案例三 #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;
} %x代表16进制输出来想想这题的答案吧
3.1 答案 怎么样算对了吗
3.2 解析 这道题难点在第二个输出下面我们一个个分析 对于ptr1来说定义时int*a 1a取出了整个数组的地址1跳过整个数组指向数组最后一个元素后面一个位置的地址 然后再将它强制类型转换回int*类型步长变回一个整型数据的大小。输出时ptr[-1]其实就是输出ptr前一个地址的访问值ptr前一个地址指向的就是数组最后一个元素因此输出为4. 对于ptr2来说定义时int*inta 1先将a强制转换成int类型已经不是指针了因此1就是存粹往a上加个1。 在内存中a[4]的存放是如上图的强制类型转换后1指向的其实是如上图的位置那么再对其进行解引用得到的就是02000000因为我们用的编译器是小端存储数据的低位是放在地址的低位的存储时反着存读取时要反着读取。 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;
}
4.1 答案 答案是1是不是没想到
4.2 解析 其实这题在初始化是有坑的仔细看我们在初始化的时候用到了我举个例子
01这个式子其实就是1这是个逗号表达式逗号表达式的值就是最后一个,后面的那个值在这里就是1.其实a[3][2]这个数组只初始话了3个值{1 , 3 , 5}。 好了现在再来分析p指针对于p来讲pa[0]将a第一行赋值给p其实就是第一行元素的首地址给了p最后打印时p[0]其实就是访问a第一行第一个元素的值相当于a[0][0],最后打印出来就是1。 5、案例五
#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;
} 5.1 答案 答案是FFFFFFFC,-4
5.2 解析 这题p是一个数组指针其步长为4个整型数据大小比a数组的每一行长度少1个整型数据大小p和a一开始指向的是同一个地址每当p1时p只能跳过4个整型数据大小的地址而对于a来说a1可以跳过5个整型数组的大小的地址。所以p[4][2]和a[4][2]比较它们都跳过了4行因此a[4][2]在地址上比p[4][2]多4个整型大小的值而我们知道指针和指针相减得到的是两个指针之间的元素个数因此是-4%p是输出地址其没有原码反码补码的概念直接将内存中-4的补码输出就是FFFFFFFC。 总结 本篇通过五个例子来加强我们对指针和数据存储的理解希望对你学习c语言的指针有所帮助