*p++和*++p的区别

*p++操作执行的过程 在项目中遇见了 *p++ 这种操作,但不明白在 *p++中 ++ 和 * 是怎样执行的?现在我们来一一剖析它的运算过程。 C语言中取值运算符 * 与前置自增运算符++、后置自增运算符++都属于单目运算符,运算符的优先级顺序同为第2级,结合方向为 右到左。其中,* 使用形式为:*p,用于指针变量,前置自增使用形式为 ++i,后置自增使用形式为 ++i。 注意 同一优先级的运算符,运算次序由结合方向所决定。 简单记就是:! > 算术运算符 > 关系运算符 > && & 阅读详情

问题的起因是复习《数据结构》,看到顺序线性表的查找元素函数时

int LocateElem_Sq(SqList L,ElemType e,Status (*compare)(ElemType,ElemType))
//在顺序线性表L内查找第一个与e相等的元素
//返回其位序
{
	i = 1;//i的初值为第一个元素的位序
	p = L.elem;//p的初值为顺序
	while(i<=L.length&&!(*compare)(*p++,e))++i;//此处的*p++究竟是怎样的结合顺序?
	if(i<=L.length)return i;
	else return 0;

}
下面这篇博文给我以解答
转自http://blog.youkuaiyun.com/npy_lp/article/details/6927302


 接下来,通过示例彻底理解自增运算符的两种用法(自减的用法与之类似,只不过是加1变成了减1)。

    1、++i和i++的区别

    如清单1(注意代码中的注释): 

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int a, b, i = 7;  
  6.   
  7.     i++; //等价于i = i + 1;  
  8.     ++i; //等价于i = i + 1;  
  9.   
  10.     a = i++; //等价于a = i; i = i + 1;  
  11.     b = ++i; //等价于i = i + 1; b = i;  
  12.       
  13.     printf("a = %d, b = %d\n", a, b);  
  14.       
  15.     return 0;  
  16. }  

    例子输出结果: 

[cpp]  view plain copy
  1. a = 9, b = 11  

    在例子中,第7和第8行的作用一样,仅仅是为变量i加1,这时i的值已经增加为9,接下来第10行变量a先获得i的值(即9),然后i加1,第11行变量i先再加1,然后把得到的值赋给b,所以b的值为11。

    稍微复杂的例子,如清单2: 

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int a = 5;  
  6.   
  7.     int *p = &a;  
  8.   
  9.     int b = (*p)++; //等价于b = a++; 即b = a; a = a + 1;  
  10.   
  11.     int c = ++(*p); //等价于c = ++a; 即a = a + 1; c = a;   
  12.       
  13.     printf("b = %d, c = %d\n", b, c);  
  14.   
  15.     printf("(*p)++ = %d, ++(*p) = %d\n", (*p)++, ++(*p));  
  16.   
  17.     return 0;  
  18. }  

    例子输出结果: 

[cpp]  view plain copy
  1. b = 5, c = 7  
  2. (*p)++ = 8, ++(*p) = 8  

    在这个例子中,只不过是通过*p来间接地操作a,其他关于自增运算符的用法与清单1类似。第9行的*p一定要用小括号括起来,否则含义就不一样了。而第11行的++(*p)也可以写成++*p(用GCC验证过),那是因为对操作数p来说它只有一个运算符*在计算它,所以无关乎运算符优先级和结合性的问题。

    值得注意的是,由于C语言没有指定函数各参数的求值顺序,所以第15行的代码是不可移植的,用不同的编译器可能会产生不同的结果(对于这个例子,GCC是先计算++(*p),后计算(*p)++,所以两者都等于8)。

    知识点:

    (1)、副作用

    在对表达式求值的同时,修改了某些变量的值,其中修改值的行为在C语言中被叫作副作用,那是因为对C语言而言,计算的目的就是对表达式求值,如语句int a = 5,它的含义是先求值得到5,然后把5赋值给变量a,后一步的赋值就是此表达式的副作用。自增和自减运算符就是因为副作用而被使用,除了加1或减1之外,还给自身赋值。

    (2)、运算符的优先级

    在C语言中,把运算符的优先级分为15级,如下表,从上到下,依次为从最高优先级到最低优先级(为了方便记忆,将15级分成11类,并对每类进行了命名)。

初等运算符

包括小括号 ()、中括号 [] 、成员访问运算符 . 和 -> 。

一元运算符

包括自增++和自减--、正负号+ 和-、间接运算*和取址运算& 、类型转换(type)、 sizeof 、逻辑反! 、位取反~等。

算术运算符

包括两级,先乘除(*、/、%)后加减(+、-)。

位移运算符

包括左移 << 和右移 >> 。

关系运算符

包括小于 < 、小于等于 <= 、大于 > 、大于等于 >= 。

判等运算符

包括相等 == 和不相等 != 。

位逻辑运算符

分三级,依次为位与 &、位异或 ^ 和位或 | 。

逻辑运算符

分两级,依次为逻辑与 && 和逻辑或 || 。

条件运算符

? :

赋值运算符

包括= 、+= 、-=、 *=、 /=、 %= 、&= 、^=、 |= 、<<= 、>>= 。

逗号运算符

,

    (3)、结合性

    对于同一操作数,在具有两个相同优先级的操作符时决定先执行哪个操作符的问题就是由结合性决定的。

    相同优先级的操作符具有同样的结合性。右结合性就是说表达式中最右边的操作最先执行,然后从右到左依次执行。在C语言中,具有右结合性的操作符只有相应的三类,分别为一元运算符、条件运算符和赋值运算符。

    注意:C语言中的优先级和结合性都是针对同一操作数而言的。如表达式24/8*2,对于操作数8而言,/ 和*的优先级相同,所以再根据它们的左结合性可知,表达式是先计算24/8得到3,然后计算3*2得到6。

    C语言并没有规定同一运算符相关的多个操作数的计算顺序(&&、|| 、? : 和 , 运算符除外),如式子a = 8 * 9 + 20 * 4,对操作数9和20而言,根据优先级就可判断先乘后加,但表达式中的两个*并不共享同一操作数,所以从左到右的结合性并不适用它,8 * 9 和20 * 4的计算顺序是不定的,到底先计算8 * 9还是20 * 4由编译器决定。

    在上面例子中,8 * 9和20 * 4谁先执行都不影响最后结果的一致,但有些情况下就未必了,如“ b = 3; a = (b++) * (b++); ”这样的例子,对于不同的编译器最后a的值可能等于9,也可能等于12,甚至可能等于16。因此,在实际应用中不能出现这样的未确定性,根据自己的需要,可以把它改成类似“b = 3; c = b++; a = c * c;”这样的形式。

    2、*p++和*++p的区别

    举例,如清单3: 

[cpp]  view plain copy
  1. #include <stdio.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     int arr[] = {1, 2, 3, 4};  
  6.     int *p = arr;  
  7.   
  8.     int a = *p++; //等价于a = *(p++); 即a = *p; p = p + 1;  
  9.       
  10.     int b = *++p; //等价于b = *(++p); 即p = p + 1; b = *p;  
  11.       
  12.     printf("a = %d, b = %d\n", a, b);  
  13.   
  14.     return 0;  
  15. }  

    例子输出结果: 

[cpp]  view plain copy
  1. a = 1, b = 3  

    对于第8行的操作数p而言,*和++的优先级相同,但根据它们的右结合性可知,在这个表达式里可认为++的优先级高于*,即*p++等价于*(p++)。

    而对于第10行的操作数p而言,它只有一个运算符++,所以先计算++p得出结果,然后间接运算。

C语言的自增自减运算 #include <stdio.h> int main() { int a = 10, b = 20, c = 30, d = 40; int a1 = ++a; int b1 = b++; int c1 = --c; int d1 = d--; printf("a=%d, a1=%d\n", a, a1); printf("b=%d, b1=%d\n", b, b1); printf("c=%d, c1=%d\n", c, c1); 阅读详情

相关推荐

Win10管理员权限的‘暗门’:从mmc.exe被阻止,聊聊UAC与自动提权那些事儿

本文深入解析Windows 10中UAC(用户账户控制)与自动提权机制,探讨mmc.exe被阻止的深层原因及解决方案。从UAC工作原理到自动提权机制,再到具体诊断与修复步骤,帮助用户理解并解决权限管理问题,同时平衡安全性与便利性。

weixin_30521161的博客 417

C语言基础知识:*p++与*(p++),*++p与*(++p),(*p)++ 与 ++(*p),++*p的详细理解

p++ 和 *(p++) 都返回 p 自增之前的值。*++p 和 *(++p) 都返回 p 自增之后指向的值。关键在于理解前缀自增(++p)和后缀自增(p++)之间的区别,以及它们与解引用操作(*)的结合方式。前缀自增先改变指针的值,然后返回新的指针值;后缀自增返回原指针值,然后改变指针的值。解引用操作(*)则用于获取指针当前指向的值。二、(*p)++ 与 ++(*p)在C和C++中,(*p)++ 和 ++(*p) 这两个表达式虽然看起来相似,尽管它们都涉及到指针p。

qq_65582400的博客 8472

Starlink vs Kuiper vs OneWeb:三大低轨卫星网络架构对比与实战应用场景解析

本文对比分析了Starlink、Kuiper和OneWeb三大低轨卫星网络架构的技术差异与商业应用场景。从轨道设计、通信性能到商业落地,详细解析了各系统在近地卫星网络领域的独特优势与挑战,为未来全球宽带服务格局提供专业见解。

weixin_29255731的博客 805

*p++是什么意思?

利用指针引用数组元素,比较方便灵活,有不少技巧。在专业人员中常喜欢用一些技巧,以使程序简洁。在看别人写的程序时可能会遇到一些令人混淆的情况,要仔细的分析。 请分析下面几种情况(设p开始时指向数组a的首元素(即p=a)。 ① 分析: p++; * pi; p++使p指向下一元素a[1]。然后若再执行* p,则得到下一个元素 a[1]的值 ② *p++; 由于++和*同优先级,结合方向为自右而左,因此它等价于 *(p++)值。 先引用p的值然后,实现*p的运算,然后使p自增1...

爱吃炸鸡的小猪's blog 2万+

BIOS/UEFI完全指南:从开机自检到超频魔改的底层硬件控制

计算机启动过程始于固件层,其核心是负责硬件初始化与引导的系统软件。传统BIOS基于16位实模式,寻址能力有限,而现代UEFI采用保护模式,支持图形界面与安全启动,实现了从概念到架构的革新。这一演进带来了显著的技术价值:更快的启动速度、更强的安全性以及对大容量存储设备的原生支持。在工程实践中,无论是解决“虚拟化技术禁用”问题、调整内存XMP配置以提升性能,还是为老主板“魔改”添加NVMe支持,都需要深入理解并操作BIOS/UEFI设置。掌握这些底层交互能力,是进行硬件调试、系统优化与故障排查的关键,也是连接抽

weixin_34236869的博客 456

openstack卷分离异常问题处理

对于 2023-05-10 之后的所有 OpenStack 版本,需要将Nova 配置为向 Cinder 发送服务令牌,然后 Cinder 接收该令牌。cinder.conf处添加service_token_role配置。1.修改nova的config文件添加如下配置。确定service role 是否存在。有关详细信息,请参阅。重启nova cinder 服务。nova-compute日志。cinder-api日志。

weixin_43391291的博客 475

*p++、*(p++)、*++p、*(++p)、(*p)++、++*p区别和用法

按从右向左的结合原则,++*p求值的顺序即为先进行“*”,然后再进行“++”运算,即先取出*p的值并赋给a,然后将*p的值arr[1]加1,但*p指向的内容不变。由于括号内优先运算,所以表达式先取出*p(假设为arr[1])的值并赋给a,然后讲*p的值arr[1]所代表的内容加1。再根据p++的运算先取值再自增,即为先取*p,然后进行p++的自增操作。再根据++p的运算先自增再取值,即为先进行p++的自增操作,然后取*p。此时*p指向的内容会发生改变,变为数组的下一位。--变量名/变量名--

W_XiangYu的博客 1万+

C语言获取硬件信息(CPU序列号,硬盘序列号,网卡IP、MAC地址、是否插入网线)

本文主要介绍Linux和Windows下使用C语言获取各种硬件信息,包括CPU序列号、硬盘序列号、网卡信息(包括网卡名字、IP地址、MAC地址、网卡是否插入网线等)。

叶落花枯的博客 9378

*++p和*p++的区别

首先你应该明白* 和 ++的优先级是相同的,而且他们的结合性是从又往左的 #include <stdio.h> int main(int argc ,char * argv[]) { int str[]={1,2,3,4,5,6,7,8,9,10}; int *p = str; int a = *p++;//a=*p ,p=p+1即a=1,p=&str[1] int b = *++p;//p=p+1,b=*p即p=&amp

水枂的博客 1258

ROS机器人未知环境自主探索功能包explore_lite总结

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析,并进行概括总结。 本系列文章共包含六篇文章,前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_client.cpp等源码实现文件中全部函数的详细介绍,第六篇文章进行概括总结,包含自主探索功能包explore_lite的简介,实现未知环境自主探索功能的原理及流程总结,效果演示,使用功能包exp

慕羽★的博客 4460

YOLO26改进策略【YOLO和Mamba】| 替换骨干 Mamba-YOLO26-T !!! 最新的发文热点

模块是模型中的一个重要组成部分,其主要作用是在模型的初始阶段对输入图像进行处理,方便后续的特征提取和目标检测。以下是对。

Limiiiing的博客 900

*++p 和 *p++ 的区别,++*++p 和 ++*p++ 的区别?

C语言中*++p和p++的区别在于运算顺序:++p先移动指针再取值,属于右结合;p++先取值再移动指针,属于左结合。示例中,++p输出arr[1]的值20,而p++输出arr[0]的值10后指针才移动。对于复合运算++++p和++*p++,前者先移动指针再自增指向的值(如arr[1]从20变为21),后者先自增当前值(如arr[0]从10变为11)再移动指针。这些差异源于运算符的优先级和结合性规则。

m0_73139998的博客 427

ARFoundation系列讲解 - 手部跟踪编程

通过使用ARFoundation的手部跟踪子系统,我们可以轻松地在AR应用程序中实现与用户手部的交互。通过设置AR环境、创建场景和相机、添加手部跟踪功能以及编写相应的脚本,我们可以开始在AR场景中跟踪和操作用户的手部。在Unity中创建一个新场景,并将AR Session组件添加到场景中的一个空对象上。手部跟踪的具体实现可能因AR设备和平台的不同而有所差异,你可能需要根据你的使用情况进行一些适配和调整。当你将手部放入AR场景中时,手部跟踪系统将触发相应的事件,并调用脚本中的回调函数。

2301_79325339的博客 355

C语言指针 *p++和*++p及++*p的区别

今天复习了一下C语言的指针题目,发现在很多代码结果题目中都出现了表达式*p++、**++p和++*p,而这几个表达式特别容易混淆。 那么通过什么方式区分他们呢,答案就是运算符优先级。 *p++ ++和 *(指针访问运算符)优先级相同,根据从右往左的结合性,因此等价于 *(p++),又因为后置++是先使用再自加,所以先取值 *p,然后再让p加1. *++p ++和 *(指针访问运算符)优先级相同,根据从右往左的结合性,因此等价于 *(++p),也就是先让指针p加1,再取此时指针p的值。 ++*p ++和

EI_Capitan的博客 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

指针和指针运算符一起时的运算规则(比如*p++和*++p的区别)

指针和指针运算符一起时的运算规则(比如*p++和*++p的区别)

nyist327的专栏 4383

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C语言基础知识:*p++与*++p;(*p)++  与 ++(*p)的理解

首先查看C语言运算符优先级表,可以看到++和指针的*号运算优先级都是第二级。结合方向都是“右到左” *p++:等同于:*p;  p += 1; 解析:由于*和++的运算优先级一样,且是右结合。故*p++相当于*(p++),p先与++结合,然后p++整体再与*结合。前面陈述是一种最常见的错误,很多初学者也是这么理解的。但是,因为++后置的时候,本身含义就是先运算后增加1(运算指的是p...

baidu_37973494的博客 1万+

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

(C)*p++和*++p区别

接下来,通过示例彻底理解自增运算符的两种用法(自减的用法与之类似,只不过是加1变成了减1)。 1、++i和i++的区别 如清单1(注意代码中的注释): [cpp] view plaincopyprint? #include<stdio.h> intmain(void) { inta,b,...

aihuanyou6758的博客 261

C语言学习之指针 *p++、*(p++)、(*p)++

*p++与*(p++)是等价的,该表达式返回*p,即p表示的地址所存的数据,并且指针p自增1 (*p)++ 该表达式返回*p,即p表示的地址所存的数据,然后该数据自增1 C编译器认为*和++是同优先级操作符,且都是从右至左结合的,所以*p++中的++只作用在p上,和*(p++)意思一样;在(*p)++中,由于()的优先级比*和++都高,所以++作用在()内的表达式*p上。 比如有: i...

u013511885的博客 1万+

关于*p++ *(p++) (*p)++ *++p *(++p) ++*p ++(*p)

最近刚复习完指针,刚好朋友问了我这几个表达式的含义*p++  *(p++)  (*p)++  *++p  *(++p)  ++*p   ++(*p)  就写了这段代码帮助理解  求指正! // zhizhen.cpp : Defines the entry point for the console application. // #include "stdafx.h" int main(i

qqMRG的专栏 1041
上一篇: 最小生成树Prim算法
下一篇: 写给初学者的A*算法(A*Pathfinding for beginners)
code_xbug
博客等级 码龄13年 26粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值