C语言中++p与p+1的区别及*p+1和*++p结果不同的原因
C语言中++p与p+1的区别及p+1和++p结果不同的原因
嘿,这个问题问得太典型了!我刚摸C语言指针的时候,也在这些运算符优先级和自增操作上栽过跟头,咱们一步步把它拆明白~
首先得搞清楚两个最基础的区别:++p 和 p+1 根本不是一回事
++p是前缀自增运算符,它是个会“搞事情”的操作:它会直接修改指针p本身的指向——把p的地址往前挪一个对应类型的长度(这里是char*,所以挪1字节),而且这个表达式的结果就是修改后的p的值。简单说,用了++p之后,p就再也不是原来的p了!p+1是普通的算术运算,它是个“老实人”操作:只会计算出「p指向的地址往后挪一个类型长度」的新地址,但完全不会修改原指针p的值。计算完之后,p该指向哪还是指向哪,一点没变。
咱们先看你给的int变量例子,其实能看出点门道:
int i=0; printf("%d \n", i); //0 printf("%d \n", i+1); //1 这里i本身还是0,只是计算了i+1的结果 printf("%d \n", ++i); //1 这里i已经被改成1了,表达式结果也是1
这里看起来输出一样,但本质上i+1没改i,++i直接把i的值改了——只是这个例子里刚好结果都是1,容易混淆。
再回到你困惑的字符串指针例子,这就是运算符优先级和结合性在搞鬼了:
先看*p+1:
C语言里,解引用运算符*的优先级比加法+高,所以这个表达式的执行顺序是:
- 先执行
*p:拿到当前p指向的字符'H'(对应ASCII码72) - 再执行
+1:给这个ASCII码加1,得到73,也就是字符'I'
整个过程中,指针p的指向完全没变化,还是死死指着字符串的第一个字符'H'。
然后看*++p:
这里要注意,前缀自增++和解引用*是同一优先级,而且它们是右结合的——简单说就是“从右往左算”。所以这个表达式的执行顺序是:
- 先执行
++p:直接修改指针p,把它的地址往前挪1字节(因为是char*),现在p指向字符串的第二个字符'e'了 - 再执行
*:对修改后的p做解引用,拿到字符'e'
这时候p本身已经被永久修改了,后续再用p的话,它就指向'e'了。
现在你就能明白为什么两个输出不一样了:*p+1是给当前指向的字符的ASCII码加1,指针不动;*++p是先把指针挪位置,再拿新位置的字符——一个是改字符的码值,一个是改指针的指向,结果肯定不一样啊!
再补个小测试帮你加深理解:如果把代码顺序改成这样:
char str[] = "Hello"; char *p = str; printf("%c \n", *p); //'H' printf("%c \n", *++p); //'e' 这里p已经指向'e'了 printf("%c \n", *p+1); //'f' 现在*p是'e',加1就是'f'
你看,这时候*p+1的结果就变成'f'了,因为p已经被++p修改过了。
备注:内容来源于stack exchange,提问作者sankeedhan




