Quelle est la différence entre ++i et i++?
En C, quelle est la différence entre l'utilisation de ++i
et i++
, et qui devraient être utilisés dans l'incrémentation d'un for
boucle?
20 réponses
-
++i
va augmenter la valeur dei
, puis retourner la valeur incrémentée.i = 1; j = ++i; (i is 2, j is 2)
-
i++
augmentera la valeur dei
, mais rendra la valeur originale quei
tenu avant d'être incrémenté.i = 1; j = i++; (i is 2, j is 1)
Pour un for
en boucle, que ce soit des œuvres. ++i
semble plus commun, peut-être parce que c'est ce qui est utilisé dans K&R .
dans tous les cas, suivez la ligne directrice "prefer ++i
plutôt que i++
" et vous ne vous tromperez pas.
il y a quelques commentaires concernant l'efficacité de ++i
et i++
. Dans tout compilateur non étudiant, il n'y aura pas de différence de performance. Vous pouvez le vérifier en regardant le code généré qui sera identique.
la question de l'efficacité est intéressante... voici ma tentative de réponse: y a-t-il une différence de performance entre i++ et ++i en C?
comme sur Freund notes, c'est différent pour un objet C++, car operator++()
est une fonction et le compilateur ne peut pas savoir optimiser la création d'un objet temporaire pour tenir la valeur intermédiaire.
i++ est connu comme Post-Incrément , alors que ++i est appelé Pré Incrémentation.
i++
i++
est post-incrémentation, car il incrémente i
's valeur par 1 après l'opération est terminée.
permet de voir l'exemple suivant:
int i = 1, j;
j = i++;
ici valeur de j = 1
mais i = 2
. Ici, la valeur de i
est attribué à j
d'abord, puis i
sera incrémenté.
++i
++i
est pré incrément parce qu'il augmente la valeur de i
de 1 avant l'opération.
Il signifie j = i;
s'exécutera après i++
.
Permet de voir l'exemple suivant:
int i = 1, j;
j = ++i;
ici valeur de j = 2
mais i = 2
. Ici, la valeur i
sera attribuée à j
après i
incrément de i
.
De même, ++i
sera exécuté avant j=i;
.
pour votre question qui doit être utilisé dans le bloc incrémentation d'une boucle for? la réponse est, vous pouvez utiliser n'importe lequel.. n'a pas d'importance. Il exécutera votre boucle for même pas. de fois.
for(i=0; i<5; i++)
printf("%d ",i);
et
for(i=0; i<5; ++i)
printf("%d ",i);
les deux boucles produiront la même sortie. c'est à dire 0 1 2 3 4
.
cela n'a d'importance que là où vous l'utilisez.
for(i = 0; i<5;)
printf("%d ",++i);
Dans ce cas, la sortie sera 1 2 3 4 5
.
s'il vous Plaît ne vous inquiétez pas à propos de "l'efficacité" (vitesse, vraiment), dont l'un est plus rapide. Nous avons des compilateurs de nos jours qui s'occupent de ces choses. Utilisez celui qui est le plus sensé à utiliser, sur la base de laquelle plus clairement montre votre intention.
++i
incrémente la valeur, puis la retourne.
i++
renvoie la valeur, puis l'incrémente.
C'est une différence subtile.
pour une boucle, utilisez ++i
, car c'est un peu plus rapide. i++
va créer une copie supplémentaire qui est jetée.
i++: - dans ce scénario d'abord la valeur est assignée et puis l'incrément se produit.
++i: - dans ce scénario d'abord l'incrément est fait et puis la valeur est assignée
ci-dessous est la visualisation d'image et aussi Voici une belle vidéo pratique ( http://www.youtube.com/watch?v=lrtcfgbUXm4 ) qui démontre la même chose.
la raison pour laquelle ++i
peut est légèrement plus rapide que i++
est que i++
peut exiger une copie locale de la valeur de i avant qu'elle soit incrémentée, tandis que ++i
ne le fait jamais. Dans certains cas, certains compilateurs optimiser loin si possible... mais ce n'est pas toujours possible, et tous les compilateurs ne le font pas.
j'essaie de ne pas trop compter sur les optimisations des compilateurs, donc je suivrais le Conseil de Ryan Fox: quand je peux utiliser les deux, je utilisez ++i
.
le résultat effectif de l'utilisation de l'un ou l'autre est identique. En d'autres termes, la boucle va faire exactement la même chose dans les deux cas.
en termes d'efficacité, il pourrait y avoir une pénalité à choisir i++ au lieu de ++I. En termes de spécification de la langue, l'utilisation de l'opérateur post-incrément devrait créer une copie supplémentaire de la valeur sur laquelle l'opérateur agit. Cela pourrait être une source d'opérations supplémentaires.
cependant, vous devriez considérer deux principaux problèmes avec la logique précédente.
-
les compilateurs modernes sont grands. Tous les bons compilateurs sont assez intelligents pour réaliser qu'il voit un accroissement entier dans une For-boucle, et il permettra d'optimiser les deux méthodes pour le même code efficace. Si l'utilisation de post-increment over pre-increment fait réellement que votre programme a un temps d'exécution plus lent, alors vous utilisez un compilateur terrible .
-
en termes de temps opérationnel-complexité, les deux méthodes (même si une copie est effectivement réalisée) sont équivalentes. Le nombre d'instructions exécutées à l'intérieur de la boucle doit dominer le nombre d'opérations de l'opération d'incrémentation de manière significative. Par conséquent, dans toute boucle de taille significative, la pénalité de la méthode d'incrément sera massivement éclipsée par l'exécution du corps de boucle. En d'autres termes, vous êtes beaucoup mieux de vous soucier d'optimiser le code dans la boucle plutôt que de l'incrément.
à mon avis, toute la question se résume simplement à une préférence de style. Si vous pensez que le pré-incrément est plus lisible, alors utilisez-le. Personnellement, je préfère le post-incrément, mais c'est probablement parce que c'était ce que j'ai appris avant que je ne sache quoi que ce soit sur l'optimisation.
il s'agit d'un exemple par excellence d'optimisation prématurée, et des questions comme celle-ci ont le potentiel de distrayez-nous des problèmes de design. C'est une bonne question à se poser, cependant, parce qu'il n'y a pas d'uniformité d'usage ou de consensus dans les "meilleures pratiques"."
ils augmentent tous les deux le nombre. ++i est équivalent à i = i + 1.
i++ et ++i sont très semblables, mais pas exactement le même. Les deux incrémenter le nombre, mais ++j'incrémente le nombre avant l'expression courante est effectuée, alors que i++ incrémente le nombre après l'expression est évaluée.
exemple:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
++i est pré-incrément l'autre est post-incrément
i++: obtient l'élément puis l'incrémente.
++i: incréments i et renvoie l'élément
exemple:
int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);
sortie:
i: 0
i++: 0
++i: 2
++i( opération de préfixe): incréments et attribue ensuite la valeur
(eg): int i = 5, int b = ++i
Dans ce cas, 6 est d'abord assigné à b, puis à 7 et ainsi de suite.
i++ (Postfix operation): attribue et incrémente la valeur
(eg): int i = 5, int b = i++
Dans ce cas, 5 est assigné à b d'abord et puis incréments à 6 et ainsi de suite.
incrément de pour boucle: i++ est principalement utilisé parce que, normalement nous utilisons la valeur de départ de i avant d'incrémenter pour boucle.Mais selon la logique de votre programme, cela peut varier.
je suppose que vous comprenez la différence dans la sémantique maintenant (bien que honnêtement je me demande pourquoi les gens se posent des questions sur le débordement de la pile plutôt que de lire: "qu'est-ce que l'opérateur X veut dire?", tu sais, un livre ou un tutoriel sur le web ou quelque chose comme ça.
mais en tout cas, en ce qui concerne celui à utiliser, ignorer les questions de performance, qui sont peu probable important même en C++. C'est le principe que vous devez utiliser lorsque vous décidez à utiliser:
dites ce que vous voulez dire par code.
Si vous n'avez pas besoin de la valeur avant incrémentation dans votre déclaration, ne pas utiliser cette forme de l'opérateur. C'est un problème mineur, mais à moins que vous ne travailliez avec un guide de style qui en interdit un version en faveur de l'autre (aka un os à tête de guide de style), vous devez utiliser la forme qui exprime le plus exactement ce que vous essayez de faire.
QED, utiliser la version de pré-incrément:
for (int i = 0; i != X; ++i) ...
la différence peut être comprise par ce simple code C++ ci-dessous:
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;
la principale différence est
"
- I++ Post ( après incrément ) et
++je l'ai Pré ( Avant d'Incrémenter )
- post if
i =1
les incréments de boucle comme1,2,3,4,n
- pré si
i =1
la boucle incrémente comme2,3,4,5,n
sous peu : ++i et i++ fonctionne de la même façon si vous ne les écrivez pas dans une fonction. Si vous utilisez quelque chose comme fonction de(i++) ou la fonction(++i) vous pouvez voir la différence.
fonction (++i) dit premier incrément i par 1, Après cela mettez ce i dans la fonction avec une nouvelle valeur.
La fonction(i++) dit mettre d'abord i dans la fonction après que l'incrément i par 1.
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
prémélange: incrément sur la même ligne. Post-increment signifie increment après l'exécution de la ligne.
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
quand il est livré avec ou, et les opérateurs, il devient plus intéressant.
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
}
Dans La Gamme
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
}
En C++ post/pré-incrémentation du pointeur de la variable
#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)
}
le fragment de code C suivant illustre la différence entre les opérateurs de pré-incrément et de post-incrément et de décrément:
int i; int j;
/ / opérateurs D'incréments
i = 1;
j = ++i; // i est maintenant de 2, j en est 2
j = i++; // i est maintenant 3, j est 2
i++ et ++i
ce petit code peut aider à visualiser la différence d'un angle différent que les réponses déjà publiées:
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);
le résultat est:
//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
faites attention aux situations avant et après.
pour boucle
pour laquelle l'un d'eux doit être utilisé dans une incrémentation bloc de une boucle for, je pense que le mieux que nous pouvons faire pour rendre une décision est d'utiliser un bon exemple:
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);
le résultat est:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
Je ne sais pas pour vous, mais je ne vois aucune différence dans son utilisation, du moins dans une boucle.
vous pouvez penser à la conversion interne de cela comme un déclarations multiples ;
// case 1 :
i++;
/* you can think as,
* i;
* i= i+1;
*/
// case 2
++i;
/* you can think as,
* i = i+i;
* i;
*/
a = i++ signifie A contient la valeur courante de i a = ++i signifie A contient incremented I value
Voici l'exemple pour comprendre la différence
int i=10;
printf("%d %d",i++,++i);
sortie: 10 12/11 11
(en fonction de l'ordre d'évaluation des arguments de la fonction printf
, qui varie selon les compilateurs et les architectures)
explication:
i++
- > i
est imprimé, puis incréments. (Imprime 10, mais i
deviendra 11)
++i
- > i
incrémente la valeur et imprime la valeur. (Empreintes 12, et le valeur de i
aussi 12)