++i 和 i++ 有什么区别?
-
09-06-2019 - |
题
在C中,使用和使用有什么区别 ++i
和 i++
, ,并且应该在 a 的增量块中使用 for
环形?
解决方案
++i
将增加i
, ,然后返回增加的值。i = 1; j = ++i; (i is 2, j is 2)
i++
将增加i
, ,但返回原始值i
在增加之前保持。i = 1; j = i++; (i is 2, j is 1)
为一个 for
循环,两者都有效。 ++i
似乎更常见,也许是因为这就是使用的 凯瑞.
无论如何,请遵循“首选 ++i
超过 i++
“你不会出错的。
有一些关于效率的评论 ++i
和 i++
. 。在任何非学生项目编译器中,不会有性能差异。您可以通过查看生成的代码来验证这一点,这些代码是相同的。
效率问题很有趣......这是我尝试回答:C 中 i++ 和 ++i 之间有性能差异吗?
作为 论弗罗因德 注意,对于 C++ 对象来说这是不同的,因为 operator++()
是一个函数,编译器无法知道如何优化临时对象的创建来保存中间值。
其他提示
i ++ 称为后期增量,而 ++ i 称为预增量。
<强> <代码> i ++在代码> 强>
i ++
是后递增的,因为它在操作结束后将 i
的值递增1。
让我们看看以下示例:
int i = 1, j;
j = i++;
此处 j = 1
的值,但 i = 2
。此处 i
的值将首先分配给 j
,然后 i
将递增。
++ i
++ i
是预增量,因为它在操作之前将 i
的值增加1。
这意味着 j = i;
将在 i ++
之后执行。
让我们看看以下示例:
int i = 1, j;
j = ++i;
此处 j = 2
的值,但 i = 2
。在 i
的 i
增加之后, i
的值将被分配给 j
。
类似地, ++ i
将在 j = i;
之前执行。
对于你的问题哪个应该在for循环的增量块中使用?答案是,你可以使用任何一个......没关系。它将执行你的for循环相同的no。时间。
for(i=0; i<5; i++)
printf("%d ",i);
和
for(i=0; i<5; ++i)
printf("%d ",i);
两个循环都会产生相同的输出。即 0 1 2 3 4
。
只关注你使用它的地方。
for(i = 0; i<5;)
printf("%d ",++i);
在这种情况下,输出将是 1 2 3 4 5
。
请不要担心“效率”。 (速度,真的)哪一个更快。这些天我们有编译器来处理这些事情。使用任何有意义的使用,在此基础上更清楚地显示您的意图。
++ i
递增值,然后返回它。
i ++
返回值,然后递增它。
这是一个微妙的区别。
对于for循环,使用 ++ i
,因为它稍微快一些。 i ++
将创建一个被丢弃的额外副本。
++ i
的原因比 i ++
略快, i ++
可能需要本地副本在增加之前i的值,而 ++ i
从不这样做。在某些情况下,如果可能的话,一些编译器会对其进行优化...但并非总是可行,并非所有编译器都这样做。
我尽量不要太依赖编译器的优化,所以我会遵循Ryan Fox的建议:当我可以使用两者时,我使用 ++ i
。
使用任何一种的有效结果是相同的。换句话说,循环在两个实例中都会做同样的事情。
在效率方面,选择i ++ over ++ i可能会受到惩罚。就语言规范而言,使用后增量运算符应该创建运算符所作用的值的额外副本。这可能是额外操作的来源。
但是,您应该考虑前面逻辑的两个主要问题。
-
现代编译器很棒。所有优秀的编译器都足够聪明,可以意识到它在for循环中看到了整数增量,并且它会将两种方法优化为相同的高效代码。如果使用后增量超过预增量实际上会导致程序运行时间变慢,那么您使用的是可怕的编译器。
-
就操作时间复杂性而言,这两种方法(即使实际执行副本)也是等效的。在循环内执行的指令数应该显着地增加增量操作中的操作数。因此,在任何有效大小的循环中,增量方法的代价将被循环体的执行大大掩盖。换句话说,你最好不要担心在循环中优化代码而不是增量。
醇>
在我看来,整个问题简单归结为一种风格偏好。如果您认为预增量更具可读性,那么请使用它。就个人而言,我更喜欢后加入,但这可能是因为在我对优化有所了解之前,这就是我所教授的内容。
这是过早优化的典型例子,这样的问题有可能让我们分散设计中的严重问题。然而,问题仍然是一个很好的问题,因为在“最佳实践”中没有统一的使用或共识。
他们都增加了数字。 ++ i
等同于 i = i + 1
。
i ++
和 ++ i
非常相似但不完全相同。两者都递增数字,但 ++ i
在计算当前表达式之前递增数字,而 i ++
在表达式求值之后递增数字。
示例:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
++ i
(前缀操作):递增然后分配值
(例如): int i = 5
, int b = ++ i
在这种情况下,首先将6分配给b,然后增加到7,依此类推。
i ++
(后缀操作):分配然后递增值
(例如): int i = 5
, int b = i ++
在这种情况下,首先将5分配给b,然后增加到6,依此类推。
包含for循环: i ++
主要用于,因为通常我们在递增for循环之前使用 i
的起始值。但是根据你的程序逻辑,它可能会有所不同。
++ i
:是预增量,另一个是后增量。
i ++
:获取元素,然后递增它。
++ i
:递增i然后返回元素。
示例:
int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);
输出:
i: 0
i++: 0
++i: 2
我假设你现在理解语义上的差异(虽然说实话,我想知道为什么 人们问堆栈溢出而不是阅读时“运营商X意味着什么”的问题, 你知道,书或网络教程或其他东西。
但无论如何,就使用哪一个而言,忽略性能问题 即使在C ++中也不太重要。这是您在决定时应该使用的原则 使用哪个:
说出你在代码中的意思。
如果您的语句中不需要value-before-increment,请不要使用该运算符的形式。这是一个小问题,但除非你正在使用一个禁止一个的风格指南 你应该使用的版本支持另一个(也就是一个骨头式的指南) 最准确地表达你想要做的事情的形式。
QED,使用预增量版本:
for (int i = 0; i != X; ++i) ...
下面这个简单的C ++代码可以理解差异:
int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
主要区别是
- 我++帖子(增量后) 和
++i 预(增量前)
- 发布如果
i =1
循环增量如下1,2,3,4,n
- 预如果
i =1
循环增量如下2,3,4,5,n
i ++和++ i
这个小代码可能有助于从与已发布的答案不同的角度可视化差异:
int i = 10, j = 10;
printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);
printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);
结果是:
//Remember that the values are i = 10, and j = 10
i is 10
i++ is 10 //Assigns (print out), then increments
i is 11
j is 10
++j is 11 //Increments, then assigns (print out)
j is 11
注意前后情况。
for loop
至于哪一个应该在for循环的增量块中使用,我认为我们做出决定的最佳方法是使用一个很好的例子:
int i, j;
for (i = 0; i <= 3; i++)
printf (" > iteration #%i", i);
printf ("\n");
for (j = 0; j <= 3; ++j)
printf (" > iteration #%i", j);
结果是:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
我不了解你,但我认为它的用法没有任何差别,至少在for循环中是这样。
以下C代码片段说明了前后增量和减量运算符之间的区别:
int i;
int j;
增量运算符:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
预先创建意味着在同一行上增加。后增量意味着在行执行后增加。
int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.
int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes
当OR,AND运算符出现时,它变得更有趣。
int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}
int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}
数组
System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12
jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13
mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13
for (int val: a) {
System.out.print(" " +val); //55, 13, 15, 20, 25
}
在C ++后期/指针变量的预增量
#include <iostream>
using namespace std;
int main() {
int x=10;
int* p = &x;
std::cout<<"address = "<<p<<"\n"; //prints address of x
std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
std::cout<<"address = "<<&x<<"\n"; //prints address of x
std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}
不久:
如果您不在函数中编写它们, ++ i
和 i ++
的工作方式相同。如果您使用 function(i ++)
或 function(++ i)
之类的东西,您可以看到差异。
function(++ i)
表示首先将i递增1,之后将此 i
放入具有新值的函数中。
function(i ++)
表示在增量 i
之后将第一个 i
放入函数中。
int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now
唯一的区别是变量增量和运算符返回值之间的运算顺序。
此代码及其输出解释了其中的差异:
#include<stdio.h>
int main(int argc, char* argv[])
{
unsigned int i=0, a;
a = i++;
printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
i=0;
a = ++i;
printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}
输出是:
i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1
所以基本上 ++i
返回增加后的值,而 ++i
返回增加之前的值。最后,在这两种情况下 i
其价值将会增加。
另一个例子:
#include<stdio.h>
int main ()
int i=0;
int a = i++*2;
printf("i=0, i++*2=%d\n", a);
i=0;
a = ++i * 2;
printf("i=0, ++i*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
return 0;
}
输出:
i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2
很多时候并没有什么区别
当返回值分配给另一个变量时,或者当与应用运算优先级的其他运算串联执行增量时,差异很明显(i++*2
不同于 ++i*2
, , 但 (i++)*2
和 (++i)*2
返回相同的值)在许多情况下它们是可以互换的。一个经典的例子是 for 循环语法:
for(int i=0; i<10; i++)
具有相同的效果
for(int i=0; i<10; ++i)
要记住的规则
为了不混淆这两个运算符,我采用了以下规则:
关联操作者的位置 ++
相对于变量 i
的顺序 ++
与分配相关的操作
换句话说:
++
前i
表示必须进行增量 前 任务;++
后i
表示必须进行增量 后 任务:
您可以将其内部转换为多个语句;
// case 1 :
i++;
/* you can think as,
* i;
* i= i+1;
*/
// case 2
++i;
/* you can think as,
* i = i+i;
* i;
*/
a = i ++表示包含当前i值 a = ++ i表示包含递增的i值
以下是了解差异的示例
int i=10;
printf("%d %d",i++,++i);
输出: 10 12/11 11
(取决于 printf
函数参数的评估顺序,它在编译器和架构之间有所不同)
说明:
打印 i ++
- &gt; i
,然后递增。 (打印10,但 i
将变为11)
++ i
- &gt; i
值递增并打印该值。 (打印12, i
的值也是12)