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

只是找了一些例子并运行,没有总结出个规律来,想不清楚内部机制,大家一起给总结一下吧~

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


[cpp]
#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--之前没有自减,再执行逻辑运算*/        

    #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--之前没有自减,再执行逻辑运算*/       [cpp] view plaincopyprint?       
        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--)&&(i);
        printf("\ntest11----->>>>>>>>>>>>\n");
        printf("a = %d\n", a);    //0
        printf("i = %d\n", i);    //0
        /*说明在(i)之后,i--之前没有自减,再执行逻辑运算*/[cpp] view plaincopyprint?    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 = 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可以对照说明。

 


自增运算符与指针结合:


[cpp]
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;     

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

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值