Question

En C, quelle est la différence entre utiliser ++i et i++, et qui doit être utilisé dans le bloc d'incrémentation d'un for boucle?

Était-ce utile?

La solution

  • ++i augmentera la valeur de i, puis renvoie la valeur incrémentée.

     i = 1;
     j = ++i;
     (i is 2, j is 2)
    
  • i++ augmentera la valeur de i, mais renvoie la valeur d'origine qui i maintenu avant d’être incrémenté.

     i = 1;
     j = i++;
     (i is 2, j is 1)
    

Pour un for boucle, soit cela fonctionne. ++i semble plus courant, peut-être parce que c'est ce qui est utilisé dans K&R.

Dans tous les cas, suivez la directive « préférer ++i sur i++" et vous ne vous tromperez pas.

Il y a quelques commentaires concernant l'efficacité de ++i et i++.Dans tout compilateur de projet non étudiant, il n'y aura aucune différence de performances.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:Existe-t-il une différence de performances entre i++ et ++i en C ?

Comme Sur Freund remarques, c'est différent pour un objet C++, puisque operator++() est une fonction et le compilateur ne peut pas savoir comment optimiser la création d'un objet temporaire pour contenir la valeur intermédiaire.

Autres conseils

je++ est connu comme Incrément de publication alors que ++je est appelé Pré-incrément.

i++

i++ est un post-incrément car il incrémente ila valeur de 1 une fois l'opération terminée.

Voyons l'exemple suivant :

int i = 1, j;
j = i++;

Ici la valeur de j = 1 mais i = 2.Ici la valeur de i sera affecté à j d'abord, puis i sera incrémenté.

++i

++i est un pré-incrément car il incrémente ila valeur de 1 avant l'opération.Ça veut dire j = i; s'exécutera après i++.

Voyons l'exemple suivant :

int i = 1, j;
j = ++i;

Ici la valeur de j = 2 mais i = 2.Ici la valeur de i sera affecté à j après le i incrémentation de i.De la même manière ++i sera exécuté avant j=i;.

Pour ta question qui doit être utilisé dans le bloc d’incrémentation d’une boucle for ? la réponse est, vous pouvez en utiliser n'importe lequel.ça n'a pas d'importance.Il exécutera votre boucle for du même numéro.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 le même résultat.c'est à dire 0 1 2 3 4.

Seul compte l’endroit où vous l’utilisez.

for(i = 0; i<5;)
    printf("%d ",++i);

Dans ce cas, la sortie sera 1 2 3 4 5.

Ne vous inquiétez pas de "l'efficacité" (la vitesse, en fait) de laquelle on est le plus rapide.De nos jours, nous avons des compilateurs qui s'occupent de ces choses.Utilisez celui qui a du sens, en fonction duquel cela montre plus clairement votre intention.

++i incrémente la valeur, puis la renvoie.

i++ renvoie la valeur, puis l'incrémente.

C'est une différence subtile.

Pour une boucle for, utilisez ++i, car c'est légèrement plus rapide. i++ créera une copie supplémentaire qui sera simplement jetée.

i++:Dans ce scénario, la valeur est d'abord attribuée, puis l'incrémentation se produit.

++i:Dans ce scénario, l'incrément est d'abord effectué, puis la valeur est attribuée

Ci-dessous se trouve la visualisation de l'image et également voici une belle vidéo pratique ce qui démontre la même chose.

enter image description here

La raison ++i peut être légèrement plus rapide que i++ est-ce i++ peut nécessiter une copie locale de la valeur de i avant qu'elle ne soit incrémentée, tandis que ++i ne fait jamais.Dans certains cas, certains compilateurs l'optimiseront si possible...mais ce n'est pas toujours possible et tous les compilateurs ne le font pas.

J'essaie de ne pas trop m'appuyer sur les optimisations des compilateurs, je suivrais donc les conseils de Ryan Fox :quand je peux utiliser les deux, j'utilise ++i.

Le résultat effectif de l’utilisation de l’un ou l’autre est identique.En d’autres termes, la boucle fera exactement la même chose dans les deux cas.

En termes d'efficacité, le choix de i++ plutôt que de ++i pourrait entraîner une pénalité.En termes de spécifications du langage, l'utilisation de l'opérateur post-incrémentation 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 devez considérer deux problèmes principaux liés à la logique précédente.

  1. Les compilateurs modernes sont géniaux.Tous les bons compilateurs sont suffisamment intelligents pour se rendre compte qu'il voit un incrément entier dans une boucle for, et il optimisera les deux méthodes pour obtenir le même code efficace.Si l'utilisation du post-incrément sur le pré-incrément entraîne réellement un temps d'exécution plus lent de votre programme, alors vous utilisez un terrible compilateur.

  2. En termes de complexité temporelle opérationnelle, les deux méthodes (même si une copie est réellement effectuée) sont équivalentes.Le nombre d'instructions exécutées à l'intérieur de la boucle devrait dominer de manière significative le nombre d'opérations dans l'opération d'incrémentation.Par conséquent, dans toute boucle de taille significative, la pénalité de la méthode d’incrémentation sera massivement éclipsée par l’exécution du corps de la boucle.En d’autres termes, il vaut mieux se soucier de l’optimisation du 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émentation est plus lisible, utilisez-le.Personnellement, je préfère le post-incrémentation, mais c'est probablement parce que c'est ce qu'on m'a appris avant de connaître quoi que ce soit en optimisation.

Il s’agit d’un exemple typique d’optimisation prématurée, et des problèmes comme celui-ci peuvent potentiellement nous détourner de problèmes sérieux de conception.Cela reste cependant une bonne question à poser, car il n’y a pas d’uniformité dans l’usage ni de consensus sur les « meilleures pratiques ».

Ils incrémentent tous les deux le nombre. ++i est équivalent à i = i + 1.

i++ et ++i sont très similaires mais pas exactement les mêmes.Les deux incrémentent le nombre, mais ++i incrémente le nombre avant que l'expression actuelle ne soit évaluée, alors que i++ incrémente le nombre après l'évaluation de l'expression.

Exemple:

int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3

++i (Opération de préfixe) :Incrémente puis attribue la valeur
(par exemple): int i = 5, int b = ++iDans ce cas, 6 est d'abord attribué à b, puis incrémenté jusqu'à 7 et ainsi de suite.

i++ (Opération Postfix) :Attribue puis incrémente la valeur
(par exemple): int i = 5, int b = i++Dans ce cas, 5 est d'abord attribué à b, puis incrémenté jusqu'à 6 et ainsi de suite.

En cas de boucle : i++ est principalement utilisé car, normalement, nous utilisons la valeur de départ de i avant d'incrémenter dans la boucle for.Mais selon la logique de votre programme, cela peut varier.

++i:est pré-incrémenté, l'autre est post-incrémenté.

i++:récupère l'élément puis l'incrémente.
++i:incrémente i puis renvoie l'élément.

Exemple:

int i = 0;
printf("i: %d\n", i);
printf("i++: %d\n", i++);
printf("++i: %d\n", ++i);

Sortir:

i: 0
i++: 0
++i: 2

Je suppose que vous comprenez la différence de sémantique maintenant (bien que honnêtement, je me demande pourquoi les gens posent des questions `` ce que l'opérateur X signifie '' sur le débordement de pile plutôt que de lire, vous savez, un livre ou un tutoriel Web ou quelque chose.

Mais de toute façon, en ce qui concerne lequel utiliser, ignorez les questions de performance, qui sont peu probables même en C ++.Ceci est le principe que vous devez utiliser lorsque vous décidez lequel utiliser:

Dites ce que vous voulez dire dans le code.

Si vous n'avez pas besoin de la valeur avant incrément dans votre instruction, n'utilisez pas cette forme d'opérateur.C'est un problème mineur, mais à moins que vous ne travailliez avec un guide de style qui interdit une version en faveur de l'autre (alias un guide de style à tête osseuse), vous devez utiliser la forme qui exprime le plus exactement ce que vous essayez de faire.

QED, utilisez la version pré-incrémentée :

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 l'incrément) et
  • ++i Pré (Avant l'incrément)

    • poster si i =1 la boucle s'incrémente comme 1,2,3,4,n
    • pré si i =1 la boucle s'incrémente comme 2,3,4,5,n

i++ et ++i

Ce petit code peut aider à visualiser la différence sous un angle différent de celui des 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 la boucle

Quant à savoir lequel d'entre eux doit être utilisé dans un bloc d'incrémentation d'une boucle for, je pense que le mieux que nous puissions faire pour prendre 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 for.

Le fragment de code C suivant illustre la différence entre les opérateurs de pré- et post-incrémentation et de décrémentation :

int  i;
int  j;

Opérateurs d'incrémentation :

i = 1;
j = ++i;    // i is now 2, j is also 2
j = i++;    // i is now 3, j is 2

Pré-crément signifie incrément sur la même ligne.Post-incrément signifie incrément 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

Lorsqu’il s’agit d’opérateurs OR, AND, cela 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 le tableau

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 de la variable de pointeur

#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)
}

Prochainement:

++i et i++ fonctionne de la même manière si vous ne les écrivez pas dans une fonction.Si vous utilisez quelque chose comme function(i++) ou function(++i) vous pouvez voir la différence.

function(++i) dit d'abord incrémenter i de 1, après cela, mettre ceci i dans la fonction avec une nouvelle valeur.

function(i++) dit mettre en premier i dans la fonction après cet 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

La seule différence réside dans l'ordre des opérations entre l'incrément de la variable et la valeur renvoyée par l'opérateur.

Ce code et sa sortie expliquent la différence :

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

La sortie est :

i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1

Donc en gros ++i renvoie la valeur après son incrémentation, tandis que ++i renvoie la valeur avant qu'elle ne soit incrémentée.En fin de compte, dans les deux cas, i verra sa valeur incrémentée.

Un autre exemple:

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

Sortir:

i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2

Souvent, il n'y a aucune différence

Les différences sont évidentes lorsque la valeur renvoyée est affectée à une autre variable ou lorsque l'incrément est effectué en concaténation avec d'autres opérations où la priorité des opérations est appliquée (i++*2 est différent de ++i*2, mais (i++)*2 et (++i)*2 renvoie la même valeur) dans de nombreux cas, ils sont interchangeables.Un exemple classique est la syntaxe de la boucle for :

for(int i=0; i<10; i++)

a le même effet que

for(int i=0; i<10; ++i)

Règle à retenir

Pour ne pas faire de confusion entre les deux opérateurs j'ai adopté cette règle :

Associer le poste de l'opérateur ++ par rapport à la variable i à l'ordre du ++ opération par rapport à la mission

Dit en d'autres termes :

  • ++ avant i signifie que l'incrémentation doit être effectuée avant affectation;
  • ++ après i signifie que l'incrémentation doit être effectuée après affectation:

Vous pouvez considérer la conversion interne de cela comme un plusieurs déclarations;

// 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 actuel i valeur a = ++ i signifie a contient une valeur I incrémentée

Voici l'exemple pour comprendre la différence

int i=10;
printf("%d %d",i++,++i);

sortir: 10 12/11 11 (en fonction de l'ordre d'évaluation des arguments au printf fonction, qui varie selon les compilateurs et les architectures)

Explication:i++->i est imprimé, puis incrémenté.(Imprime 10, mais i deviendra 11)++i->i la valeur incrémente et imprime la valeur.(Imprime 12 et la valeur de i aussi 12)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top