您的位置:首页 > 编程语言 > C语言/C++

C语言查遗补缺——关于自增运算符的有趣的例子

2013-03-29 09:06 197 查看
只是找了一些例子并运行,没有总结出个规律来,想不清楚内部机制,大家一起给总结一下吧~

首先是跟宏定义结合,这是笔试题中可能遇到的题目,然后展开讨论,关于后自增在逻辑运算符和加法运算符中的区别,但是没有总结出规律,也不明白本质上怎么破。。欢迎大家留言给予指导~

#define BAND1(x) (((x) >= 5)&&((x) <= 10) ? (x) : 0)

#define BAND2(x) (((x) >= 5)&&((x) <= 5) ? (x) : 0)

int main()
{
int a;
int i = 5;
printf("\ntest1----->>>>>>>>>>>>\n");
printf("BAND1(++i) = %d\n", BAND1(++i));   //8
printf("i = %d\n", i);    //8

i = 5;
printf("\ntest2----->>>>>>>>>>>>\n");
printf("BAND1(i++) = %d\n", BAND1(i++));  //7
printf("i = %d\n", i);    //8

i = 5;
printf("\ntest3----->>>>>>>>>>>>\n");
printf("BAND2(++i) = %d\n", BAND2(++i));   //0
printf("i = %d\n", i);    //7
/*说明在((x) >= 5)&&((x) <= 5)部分执行了两次自增 */

i = 5;
printf("\ntest4----->>>>>>>>>>>>\n");
printf("BAND2(i++) = %d\n", BAND2(i++));   //0
printf("i = %d\n", i);    //7
/*说明在((x) >= 5)&&((x) <= 5)部分执行了两次自增 */

i = 0;
a = (i++) + (i++) + (i++);
printf("\ntest5----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //0
printf("i = %d\n", i);    //3
/*问题是在条件运算符内部就自增了,可是加法时就没有自增,自增操作的时机是?*/

i = 4;
a = (i++ >= 5);
printf("\ntest6----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //0
printf("i = %d\n", i);    //5
/*说明在(i++ >= 5)部分没有自增,比较完后才自增 */

i = 4;
a = (i++ >= 5)+(i++ >= 5);
printf("\ntest7----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //1
printf("i = %d\n", i);    //6
/*说明在第一个(i++ >= 5)之后,第二个(i++ >= 5)之前自增, 再执行加法*/

i = 4;
a = (i++ >= 4)&&(i++ >= 5);
printf("\ntest8----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //1
printf("i = %d\n", i);    //6
/*说明在(i++ >= 4)之后,(i++ >= 5)之前自增, 再执行逻辑运算*/

i = 1;
a = (i--)&&(i);
printf("\ntest9----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //0
printf("i = %d\n", i);    //0
/*说明在(i--)之后,i之前自减,再执行逻辑运算*/

i = 1;
a = (i)&&(i--);
printf("\ntest10----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //1
printf("i = %d\n", i);    //0
/*说明在(i)之后,i--之前没有自减,再执行逻辑运算*/
i = 1;
a = (i)&&(i--)&&(i);
printf("\ntest11----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //0
printf("i = %d\n", i);    //0
/*说明在(i)之后,i--之前没有自减,再执行逻辑运算*/
i = 1;
a = (i--)+(i);
printf("\ntest12----->>>>>>>>>>>>\n");
printf("a = %d\n", a);    //2
printf("i = %d\n", i);    //0
/*说明在i--之后,i之前没有自减,在整个加法运算完后才自减*/
/*只能说明整型运算符和逻辑运算符不一样。。。略乱。。。本质上怎么说呢?*/

printf("DONE!\n");
system("pause");
return 0;
}

跟同学讨论过后,觉得他说的很有道理哈~

对于逻辑表达式&&,会把前后表达式均作为一个完整的表达式来处理,所以,&&之前,i有后自增时,就会执行自增,测试9、10、11可以对照说明;而加法运算符,就会要求所有的连加执行完后,再进行自增,这就把整个加法表达式作为一个最小粒度的完整的表达式来处理。

而有>=、<=等运算符的表达式,也会作为一个最小粒度的完整的表达式来处理,测试6、7可以对照说明。

自增运算符与指针结合:

int main()
{
char temp;
char s[] = "hello";
char *p = s;
temp = *p++;
printf("temp = %c\n", temp);   //h
printf("*p = %c\n", *p);       //e
/* 说明在*p++中,先取出*p的值h赋给temp,指针p再自增。
原因:++与*同级,但结合方向自右向左,所以,++先与p结合,作用在指针上,
再取*p的值,然后++作用于指针之上 */

p--;                           //使得初始状态与上面的初始状态相同
temp = *(p++);
printf("temp = %c\n", temp);  //h
printf("*p = %c\n", *p);       //e
/* 与第一个测试结果相同,说明了按照结合方向运算 */

temp = ++*p;
printf("temp = %c\n", temp);  //f
printf("*p = %c\n", *p);  //f
/*说明只是取*p的值e,并自增1,值为f,赋给temp。
按结合方向从右至左,说得通。*/

temp = ++(*p);
printf("temp = %c\n", temp);  //g
printf("*p = %c\n", *p);  //g
/* 与上面测试结果同规律,说明了按照结合方向运算 */

printf("DONE!\n");
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: