指针运算练习题

  • 前言
  • 例题一
  • 例题二
  • 例题三
  • 例题四
  • 例题五
  • 例题六
  • 例题七
  • 例题八
  • 尾语

前言

嗨喽,大家好~这里是咸鱼安忆.

现在是学C语言时刻~

C语言当中的指针向来是一个难点

本篇文章针对指针的相关运算列出了一些例题供以研究学习

希望看完本篇文章之后,你能有所收获~

例题一

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) 取出的是第二个元素的地址,解引用之后就是2

(ptr-1) 中ptr里存放的地址是由&a+1得到的,&a取得的是整个数组的第一,+1跳过整个数组,ptr就指向了5后面的地址,而ptr-1得到的就是5的地址了,解引用得到结果5

例题二


struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}* p;
//假设p 的值为0x100000
//此结构体20个字节
int main()
{printf("%p\n",p + 0x1);printf("%p\n",(unsigned long)p + 0x1);printf("%p\n",(unsigned int*)p + 0x1);return 0;
}

!指针类型决定了指针的运算
p + 0x1这个结构体p一共20个字节,加0x1等于加了一位,就加了20,记住要转为16进制,所以第一个是0x100014

(unsigned long)p + 0x1将p转为了无符号长整型,所以加的就是1,结果为0x100001

(unsigned int *)p + 0x1将p转为了无符号整型指针,跳过的就是一共整型指针的大小,加了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\n",ptr1[-1],*ptr2);return 0;
}

!Visual Studio 2019所采用的是小端存储

ptr1所得到的是&a+1的地址,&a取到的是整个数组的地址,当它+1之后,就跳过了一整个数组,拿到了4后面的地址

而ptr1[-1]与 * (ptr1+(-1)) 等价,所以ptr1-1得到的就是4的地址,而结果用%x,也就是十六进制输出,结果为0x00000004,0x和0都会被省略,结果输出4

ptr2所得到的是首元素地址a被强转为int型之后+1得到的

因为a原本是int*占4个字节,转为整型之后就意味着地址变成一个整数了,所以+1加的的就是十进制1,整型+1跳过一个字节

地址变成首元素后的第二个字节的地址,在小端存储下取出得到00 00 00 02,十六进制是0x02000000,输出结果为2000000

例题四

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

数组初始化内(1, 0)是一个逗号表达式,结果是1,所以 p [0] = 1

例题五

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

p=a将a的地址赋给了整型指针p

而p[4]取到的相当于从a的首地址开始,每四个字节一组,来到了a[3][1] 的位置

p[4][2] 就是取到这一组元素的下标为2的地址,求得a[4][2]的地址,再将他们相减得到-4

而-4用%p打印成十六进制则是FFFFFFFC,%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;
}

赋值过程如图解,其中*(ptr1-1)就是解引用ptr1前一位的地址,也就是10
而*(ptr2-1)就是解引用ptr2前一位的地址,(int*)这个强制转换是用来迷惑的,因为本来就是int型

例题七

int main()
{char* a[] = {"work","at","alibaba"};char**pa = a;pa++;printf("%s\n",*pa);return 0;
}

如果能理解前面的内容,此题就比较简单,二级指针pa取到了a的首元素地址,pa++就是a的首元素地址往后走一位,这里重点就在于了解数据是如何存储的,具体如图:

例题八

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

此题较为复杂,首先需要了解一下他们的存储结构和指向关系,存储结构图解:

了解了他们之间的关系之后我们再来开始计算:

1、

(**++cpp)

++在cpp之前,先加再运算,cpp本来是指向cp的首元素地址的,++后指向了(c+2)的地址,一次解引用得到c+2,第二次解引用得到POINT

2、

(*-- *++cpp+3)

+的优先级是比较低的,所以这里我们先运算++和解引用符号

cpp因为上一条语句的运算,现在指向的是(c+2)的地址,++后指向了(c+1)的地址,解引用后得到了c+1,–后使得(c+1)变成了c

此时再解引用得到了c的第一个元素”ENTER“的首元素地址,最后在+3得到第二个E的地址,用%s打印出来就是ER

3、

(*cpp[-2]+3)

可以先将cpp[-2]转换为 *(cpp+(-2)),得到的表达式就是

(* ( *(cpp-2))+3)

然后再将这个表达式一步步运算,先是cpp-2,现在的cpp还是指向(c+1)的地址,地址-2后得到了(c+3)的地址,

不过要注意,这里只是在运算表达式而没有将cpp真实指向的地址改变

得到(c+3)的地址后再解引用得到(c+3),再进行解引用得到c的第四个元素”FIRST“的首元素地址,最后再+3打印出来得到ST

4、

cpp[-1][-1]+1

首先还是将表达式转换一下,得到:

  • ( *(cpp-1)-1)+1

然后再进行运算:
cpp-1得到(c+2)的地址,解引用得到(c+2),再-1得到c+1,解引用得到c的第二个元素"NEW"的首元素地址,最后+1得到E的地址,用%s打印出来得到EW

尾语

感谢你看到这里~

希望本篇文章有对你带来帮助

【C】指针的相关运算练习题相关推荐

  1. c语言指针的相关运算,C语言指针的运算

    本文讨论使用指针进行的运算,最重要的运算是获取指针所引用的对象或函数.也可以比较指针,使用指针来遍历一个内存区域. 使用指针读取与修改对象 间接运算符 * 生成内存中的位置,该位置的地址存储在一个指针 ...

  2. 指针变量的声明、地址相关运算--“*”和“”

    内存空间如何访问 我们使用的内存的基本存储单位是字节,一个字节由8个二进制位组成.每个字节都会按照一定的规则编号,这个编号就是该字节存储单元的地址.计算机就是利用这种编号也就是字节存储单元的地址来定位 ...

  3. 数据结构源码笔记(C语言):B树的相关运算算法

    //B树的相关运算算法#include<stdio.h> #include<malloc.h>#define MAXM 10//定义B树最大的阶数 typedef int Ke ...

  4. C指针3:指针变量的运算

    由上节介绍我们知道,通过指针可以修改内存上的数据,并进一步可以交换数据.这种操作实际上也是在对地址进行操作运算.具体怎么实现指针变量的元素呢?为什么能实现指针变量的运算呢? 因为指针变量保存的是地址, ...

  5. matlab 多项式的相关运算

    多项式的相关运算 clc,clear; close all; %利用向量p构建多项式 p=[3 -2 4 6 8]; poly2sym(p)clc,clear; close all; %convolu ...

  6. 数据结构源码笔记(C语言):哈希表的相关运算算法

    //实现哈希表的相关运算算法 #include<stdio.h> #include<malloc.h> #include<string.h>#define MaxS ...

  7. 序列的卷积运算与相关运算——MATLAB

    一.实验目的 1.掌握有限长序列线性卷积的编程计算原理,并能够利用Matlab或C语言编写算法程序进行线性卷积运算的程序实现; 2.学会线性卷积函数和线性相关函数的使用方法,并能利用二者进行有限长序列 ...

  8. 分数加减乘除混合运算带答案_分数分数加减乘除混合运算练习题及答案_0.doc

    分数分数加减乘除混合运算练习题及答案_0 精品文档 2016全新精品资料-全新公文范文-全程指导写作 –独家原创 PAGE1 / NUMPAGES19 分数分数加减乘除混合运算练习题及答案 1.直接写 ...

  9. 通过具体的例子说明一维和二维的相关运算、卷积运算究竟是怎么做的。

    在图像处理中,大量的算法中用到的运算其实都是相关运算和卷积运算. 所以,我们很有必要知道相关运算.卷积运算究竟是怎么做的. 本篇博文通过具体而简单的例子向大家说明相关运算.卷积运算究竟是怎么做的. 0 ...

最新文章

  1. 04-dispatch_group
  2. 哈啰顺风车成立5亿元“顺风绿色出行基金”
  3. 对财务客户开具Invoice(无销售流程)
  4. find与grep的区别
  5. ARTS打卡计划第6周-REVIEW-超越编码的避免项目失败的软技能
  6. python中颜色介意用数字表示_利用Python实现颜色色值转换的小工具
  7. 2038年问题 php,php strtotime() mktime() 的2038年问题 Y2K38漏洞
  8. ncverilog脚本_基于脚本和test bench的ncverilog ASIC仿真实例分析
  9. stm32f10x系列.s汇编启动文件
  10. 201671010140. 2016-2017-2 《Java程序设计》java学习第十六周
  11. 深度剖析5款主流杀毒软件
  12. VS2019连接SQL2008实现登录注册功能.
  13. Google Code Jam
  14. html css星号选择器,CSS里面的星号*
  15. 一张图带你了解游戏程序员的学习之路
  16. PS | 工作区,工具栏不见了怎么办 -- 复位基本功能
  17. 30000字Linux期末考试复习总结
  18. 数据可视化 饼图_饼图之外的生活:合适工作的合适可视化效果
  19. Mysql——Undo日志
  20. 安装计算机的程序包,win10电脑中安装office提示无法打开此安装包请确认该程序包存在如何解决...

热门文章

  1. PMP——项目管理介绍
  2. linux输入特殊符号密码,linux 输入特殊符号
  3. 深度学习-聊天机器人
  4. Android SurfaceView、TextureView区别
  5. win10清理C盘好用的办法
  6. 【POI2013】bzoj3426 Tower Defence Game
  7. 京东登陆界面正则匹配
  8. 服务器dnf虚拟机多开吃显存吗,安卓模拟器多开对显卡有没有什么要求?
  9. kettle将文件路径定义为_Kettle 文件操作
  10. 总结2019,憧憬2020