首先看看自增运算符的用法。
有以下代码:
int a=2;
printf("%d,",++a);
printf("%d",a);
输出结果是3,3。
修改一下:
int a=2;
printf("%d,",a++);
printf("%d",a);
结果是2,3。
比较一下两段代码:
第一段代码是++a,在使用a之前,先使a的值加1,再使用a。
第二段代码是a++,在使用a之后,再使a的值加1。
原因是自增运算符++是单目运算符,结合方向为自右向左,意思就是,如果要对一个变量进行自增运算,那么,应该把自增运算符放在变量的左边!
但把自增运算符++放在变量右边也没有报错啊?!我想这可能跟C标准有关吧。但是,其他结合方向为自右向左的运算符就不能这么写,你试试看a!,b&?
由于C标准不把a++当成一种错误,所以在很多时候,我们都用在用它,甚至它的频繁度比++a还要高。只能说是利用一种不完美来实现我们的目的吧。
(以上三段运算符结合性和变量位置的关系,是个人理解,不知道对不对,望高手指点)
写这一段的目的,是要记住++a是体现了++的结合方向的,而a++这种写法是先用a,再使a加1。所以,在printf("%d,",a++);语句里面,是看不到a变化后的结果的。
++在右边,变化不立显。
++在左边,变化立刻显。
下面谈谈指针。
我们都知道,内存是用来存放数据的,而内存也有容量大小的不同。内存的最小可编址(也叫寻址)单位是字节。内存给这些小单位进行编号,编号就是地址。
指针存放的是某一个变量在内存中的地址,这个地址所在的内存单元里面放有该变量的值。
有以下代码:
int a=2;
int *p;
p=&a;
printf("%d\n",*p);
printf("%d\n",p);
结果是
1
?
?是p的值,也是变量a在内存中的地址,它由运行环境决定。它是一个随机产生的值,系统在编译的时候为变量a分配内存空间,a分到哪个内存单元,*就是这个单元的编号(地址)。
接着来,在上面的代码后面加上这些代码:
p=p+1;
printf("%d\n",*p);
printf("%d\n",p);
结果是
?
?
先说第二个?,它比上面的一段代码中?的值多了4,因为指针p指向int型变量a,a占4个字节,p=p+1使指针移位一次,即移动4个字节。而第一个?的值,就是随机出现的了。
下面进入正题。
圆括号()的优先级是1,结合方向是自左向右。
指针运算符*和自增运算符++的优先级都是2,结合方向都是自右向左。
把指针运算符*,自增运算符++和圆括号与一个指针变量p搭配,可以都得到以下运算组合:(假定之前有p=&a;)
1、*p++
2、*p(++)
3、(*p)++
4、*++p
5、*(++p)
6、++*p
7、++(*p)
分析结果:
1、*p++,后缀++的优先级比*递引用运算符的优先级高,所以*p++的结合顺序应该是*(p++),根据上面后缀++的语义很容易得到*p++就相当于tmp=p, p=p+1, *tmp;
2、*p(++),虽然有优先级更高的圆括号()把++括起来,但就算要先计算括号里面的东西,光有一个++,什么也做不了。没办法,只能让p先跟*结合,再跟++结合。这就跟第1种组合一样。
3、(*p)++,由于优先级,圆括号里面的先计算,所以先取*p,再使(*p)自增1,而不是使指针p指向内存中下一个位置。结果改变不能立即看出。
4、*++p,由于结合性,这种写法体现了++和*自右向左的结合方向,先使指针p指向内存中下一个位置,再取*p。结果改变可以立即看出。
5、*(++p),同第4种组合。
6、++*p,由于结合性,这种写法体现了++和*自右向左的结合方向,先使*p自增1,再取*p。结果改变可以立即看出。
7、++(*p),同第6种组合。
总结一下:
*p++等价于*p(++),取值,移位(不安全)。
(*p)++,取值,增值。
*++p等价于*(++p),移位,取值(不安全)。
++*p等价于++(*p),增值,取值。
---------------------------------------------------------------------------------------------
原因是自增运算符++是单目运算符,结合方向为自右向左,意思就是,如果要对一个变量进行自增运算,那么,应该把自增运算符放在变量的左边!
LZ的这段话,
其实都是可以自增的。
看你用在什么地方了,是需要先自增再处理,还是先处理再自增
一般字符串的话,
比如:
char str[222];
char * p = str;
while(*p++)
{
............
}
这里就需要先对P所批向的字符先判断的。
如果先++那么可能就会丢掉了第一个字符了。
--------------------------------------------------------------------------------
++运算符分前缀++和后缀++,这两个实际上可以说是不同的运算符,表现在以下几点
1. 后缀++的优先级比前缀++高
2. 后缀++是左结合的,而前缀++是右结合的
3. 在写++运算符重载函数时,两个函数声明也是不同的
前缀++是operator++(),而后缀++是operator++(int)
4. 语义上的差别
a++表示a自增1,但表达式的值是a原来的值,类似
tmp=a, a=a+1, tmp;
++a表示a自增1,表达式的值就是a自增后的值,类似
a=a+1, a;