自增大总结:i=(i++)+(++i)另i=?

本文通过一段C语言代码示例,详细解析了自增运算符(++i与i++)在表达式中的工作原理及顺序。通过观察源代码及其对应的汇编指令,揭示了在复合表达式中自增运算符的行为特点。

源代码:

#include <stdio.h>

int main()
{
  int i = 1, j = 1, k;

  i = (i++) + (++i);
  printf("i=%d /n", i);

  k = (j++) + (++j);
  printf("j=%d, k=%d/n", j, k);
}

执行结果:

i=5
j=3, k=4


关键的汇编码片段:

 movl $0x1,0xfffffff0(%ebp)
 movl $0x1,0xfffffff4(%ebp)
 addl $0x1,0xfffffff0(%ebp)
 mov 0xfffffff0(%ebp),%eax
 add %eax,0xfffffff0(%ebp)
 addl $0x1,0xfffffff0(%ebp)
 mov 0xfffffff0(%ebp),%eax
 mov %eax,0x4(%esp)
 movl $0x8048500,(%esp)
 call 80482f8 <printf@plt>
 addl $0x1,0xfffffff4(%ebp)
 mov 0xfffffff4(%ebp),%eax
 add 0xfffffff4(%ebp),%eax
 mov %eax,0xfffffff8(%ebp)
 addl $0x1,0xfffffff4(%ebp)
 mov 0xfffffff8(%ebp),%eax
 mov %eax,0x8(%esp)
 mov 0xfffffff4(%ebp),%eax
 mov %eax,0x4(%esp)
 movl $0x8048507,(%esp)
 call 80482f8 <printf@plt>

发现,先执行++i,最后执行i++。

i = (i++) + (i++),i是不是等于2(0+0,接着i两次自加)
j = (i++) + (i++),j是不是等于0 (i没自加前把值赋给了j)

<think> 我们有一个表达式:i = (i + 1) % 4 这个表达式通常用于循环中,特别是需要循环遍历一个固定范围(例如0,1,2,3)时。 步骤分解: 1. 首先计算 i + 1:将当前 i 的值加1。 2. 然后取模运算(% 4):将上一步的结果对4取模(即除以4取余数)。 3. 将结果赋值给 i。 取模运算的特性:结果的范围是0到3(因为对4取模,余数只能是0,1,2,3)。 例如,假设初始 i=0: 第一次:i = (0+1)%4 = 1%4 = 1 第二次:i = (1+1)%4 = 2%4 = 2 第三次:i = (2+1)%4 = 3%4 = 3 第四次:i = (3+1)%4 = 4%4 = 0 第五次:i = (0+1)%4 = 1 如此循环... 所以,这个表达式的作用是让 i 在0,1,2,3之间循环递增。 常见的应用场景: 1. 循环访问数组的四个元素(例如,一个环形缓冲区,有四个位置)。 2. 状态机中循环切换状态(四种状态)。 3. 在图形学中循环颜色或方向等。 注意:这里取模运算保证了当i+1等于4时,会回到0,从而实现循环。 外,如果i的初始值不在0-3范围内,那么第一次计算后也会进入0-3的循环。例如,如果i=5: 第一次:i = (5+1)%4 = 6%4 = 2 然后进入循环:2,3,0,1,2,... 因此,无论i的初始值是什么,执行一次这个表达式后,i的值就会落在0到3之间,并且之后会在这个范围内循环。 与自增运算符(++i 或 i++)的区别: 这个表达式不是简单的自增,而是自增后取模,所以不会一直增大,而是在0-3之间循环。 所以,代码 'i = (i + 1) % 4' 的含义是:将i的值循环递增1,并在达到3之后重置为0(即模4循环)。 用途:常用于需要循环访问固定数量(4个)的选项或状态的场景。 </think> ### 代码 `i = (i + 1) % 4` 的含义及用途 #### 1. **核心含义** - **数学表达式**:$ i = (i + 1) \mod 4 $ - **作用**: 将变量 `i` 的值循环递增 1,但限定在范围 `0` 到 `3` 之间(即模 4 的余数范围)。 #### 2. **运行逻辑** 假设 `i` 的初始值为 `k`,执行过程如下: 1. 计算 `i + 1` 2. 对结果取模 4:$(i + 1) \mod 4$ 3. 将结果赋值给 `i` **循环示例**(初始值 $i=0$): ``` i=0 → (0+1)%4 = 1 i=1 → (1+1)%4 = 2 i=2 → (2+1)%4 = 3 i=3 → (3+1)%4 = 0 // 重置为0,形成循环 ``` #### 3. **关键特性** - **循环边界**:结果始终在 $ \{0, 1, 2, 3\} $ 内循环,不会超过 3。 - **重置机制**:当 `i=3` 时,执行后 `i=0`,实现周期性重置。 #### 4. **典型用途** 1. **循环遍历有限集合** 例如轮询 4 个设备状态: ```c int i = 0; while (1) { check_device(i); // 检查设备0/1/2/3 i = (i + 1) % 4; // 切换到下一个设备 } ``` 2. **环形缓冲区(Circular Buffer)** 控制读写指针在固定大小的缓冲区中循环移动: ```c #define BUFFER_SIZE 4 int buffer[BUFFER_SIZE]; int index = 0; void add_data(int data) { buffer[index] = data; index = (index + 1) % BUFFER_SIZE; // 指针循环移动 } ``` 3. **状态机切换** 在 4 个状态间循环切换: ```c enum { STATE_A, STATE_B, STATE_C, STATE_D } state = STATE_A; void next_state() { state = (state + 1) % 4; // 切换到下一个状态(A→B→C→D→A...) } ``` 4. **周期性任务调度** 每 4 次循环执行一次特定操作: ```c for (int i = 0; i < 100; i++) { if (i % 4 == 0) { // 等价于 (i % 4) 的判断 run_periodic_task(); } } ``` #### 5. **与自增运算符的区别** - `i = (i + 1) % 4`:**循环递增**,值域限定在 `[0,3]`。 - `i++` / `++i`:**单向递增**,值域无限制(除非额外约束)[^1][^2][^3]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值