C语言 ++i和i++

今天范了个很小的错误,导致从队列中获取的值不正确,排查了很长时间才找到错误原因.
为吸取教训,现记录如下:

1 错误的代码

item = arg->queue.queues[++arg->queue.tail];

平常写for(int i =0; i < 100;++i)习惯了,所以获取队列值时也顺手写成++arg->queue.tail.

2 正确的代码

item = arg->queue.queues[arg->queue.tail++];

3 注意事项

演示代码

/*
*	array[++index]	++在前表示先index = index+1,然后再从数组index的位置获取值
*	array[index++]	++在后表示先从数组index的位置获取值,然后再index = index+1
*	 i=1; y=i++;  等效于:i=1; y=i; i=i+1; 则执行完后 y=1; i=2;
*    i=1; y=++i;  等效于:i=1; i=i+1; y=i; 则执行完后 y=2; i=2;
*/
#include <stdio.h>
#include <stdlib.h>
int main() {
	int queues[4] = {1,2,3,4};
	int index=0;
	//假设期望获取的值为1,也就是queues[0]的值,
	//正确的用法,打印的值为1
	fprintf(stdout,"%d\n",queues[index++]);
	//错误的用法,打印的值为2
	index=0;
	fprintf(stdout,"%d\n",queues[++index]);
	 return (EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
    int n = 0, i = 0;
    fprintf(stdout, "%d\n", n = i++);
    fprintf(stdout, "%d\n", n = ++i);
    fprintf(stdout, "%d\n", i++);
    fprintf(stdout, "%d\n", i);
    return (EXIT_SUCCESS);
}
/*
0
2
2
3
*/

4 使用技巧

根据这一特性,我们可以在c++中使用这一技巧删除容器中的元素(在我早期的博文中使用过).


#include <iostream>
#include <set>
int main(int argc, char** argv) {
    std::set<int> container;
    container.insert(1);
    container.insert(2);
    container.insert(3);
    container.insert(4);
    container.insert(5);
    container.insert(6);
    
    for (std::set<int>::iterator it = container.begin(); it != container.end();) {
        if (3 == (*it)) {
        	/*
		    *	删除项值为3的元素
		    *	根据3节说明的特性,先执行了erase(it)方法,然后再执行 it = it +1
		    */
            container.erase(it++);/* Really smart! */ 
        } else {
            ++it;
        }
    }
	//如不改变容器的内容请使用const_iterator
    for (std::set<int>::const_iterator it = container.begin(); it != container.end();++it)
        std::cout << *it << std::endl;

    return 0;
}


<think>好的,用户问的是C语言中前缀自增++i后缀自增i++的区别及使用场景。首先,我需要回忆两者的基本区别。根据引用[1],i++++i都是自增运算符,区别在于返回的值执行顺序不同。前缀++i是先加1再返回值,而后缀i++是先返回原值再加1。这一点需要详细说明。 接下来,用户可能想知道具体的例子,比如在表达式中的表现。比如,当i=5时,a=++ia=i++的结果分别是多少。这时候可以举例子说明,a=++i的话,a会是6,i也是6;而a=i++的话,a是5,i变成6。这能直观展示两者的差异。 然后,要考虑使用场景。根据引用[3],自增运算符的操作数必须是变量,所以需要提到这点。另外,在循环结构中,比如for循环,通常使用i++,因为只需要递增,不需要返回值。而在需要先递增再使用的情况下,比如数组索引或者表达式计算中,用++i可能更高效,尤其是在C++中涉及对象时,但C语言中可能差异不大,但习惯上还是推荐++i。 还要注意可能的错误用法,比如在同一个表达式中多次使用同一变量的自增,比如i = i++,这会导致未定义行为,需要提醒用户避免这种情况。 此外,用户可能对性能差异感兴趣,特别是在循环中的使用。可以解释在C语言中,对于内置类型,i++++i的性能可能相同,但习惯上++i更优,尤其是在C++中,但对于C语言来说,可能影响不大,不过还是推荐++i以避免潜在问题。 最后,需要总结两者的区别,强调返回值执行顺序的不同,并给出使用建议,比如在循环中的选择,以及在需要表达式值时的选择。同时,提醒用户避免复杂的表达式中的使用,以免引发未定义行为。</think>### C语言中前缀自增(++i)后缀自增(i++)的区别及使用场景 #### 1. **核心区别** - **前缀自增 `++i`**: 先对变量 `i` 执行加1操作,**然后返回新值**。 示例:若 `i = 5`,则 `a = ++i` 的结果为 `a = 6`,`i = 6`。 - **后缀自增 `i++`**: 先返回变量 `i` 的原始值,**再对 `i` 执行加1操作**。 示例:若 `i = 5`,则 `a = i++` 的结果为 `a = 5`,`i = 6`。 #### 2. **语法要求** - 自增运算符的操作数必须是变量(如 `int i`),不能是常量或表达式(如 `5++` 或 `(i+1)++` 是非法的)[^3]。 #### 3. **使用场景分析** - **`++i` 的典型场景**: - 需要**先更新变量再使用其值**时。 例如:`array[++index] = value;`(先将 `index` 加1,再作为下标赋值)。 - 在循环中,若循环体不需要原值时,`++i` 可能更高效(尤其在C++中涉及对象时,但C语言中差异可忽略)。 - **`i++` 的典型场景**: - 需要**使用原值后再更新变量**时。 例如:`result = i++;`(将 `i` 的原值赋给 `result`,再自增)。 - 常见的 `for` 循环中,仅需递增操作: ```c for (int i = 0; i < 10; i++) { ... } ``` #### 4. **性能差异(C语言视角)** - 对于基本数据类型(如 `int`),现代编译器会优化 `i++` `++i` 的性能,两者效率相同。 - 在涉及复杂表达式时,推荐使用 `++i`,避免因临时值产生潜在开销(更重要的习惯性规范)。 #### 5. **易错点与注意事项** - **避免在同一个表达式中多次修改同一变量**: 例如 `int j = i++ + ++i;` 会导致未定义行为[^2]。 - **避免依赖副作用的复杂表达式**: 如 `printf("%d, %d", i, i++);` 的结果可能因编译器不同而不同。 #### 代码示例 ```c int i = 5; int a = ++i; // a=6, i=6 int b = i++; // b=6, i=7 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kmblack1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值