Öka och minska operatörer

Inkrement- och dekrementoperatorer är unära operatorer som adderar eller subtraherar en till eller från deras operand .

De implementeras vanligtvis i imperativa programmeringsspråk . C- liknande språk har två versioner (för- och efter-) av varje operator med lite olika semantik.

I språk som syntaktiskt härrör från B (inklusive C och dess olika derivator), skrivs inkrementoperatorn som ++ och dekrementoperatorn skrivs som -- . Flera andra språk använder funktionerna inc(x) och dec(x).

Inkrementoperatorn ökar, och dekrementeringsoperatorn minskar, värdet på dess operand med 1. Operanden måste ha en aritmetisk eller pekardatatyp och måste referera till ett modifierbart dataobjekt . Pekarvärden ökas (eller minskas) med ett belopp som gör att de pekar på nästa (eller föregående) element intill i minnet.

På språk som stöder båda versionerna av operatörerna:

  • Operatörerna pre -increment och pre -decrement ökar (eller minskar) sin operand med 1, och värdet på uttrycket är det resulterande ökade (eller minskade) värdet.
  • Operatörerna post -increment och post -decrement ökar (eller minskar) värdet på sin operand med 1, men värdet på uttrycket är operandens värde före inkrementeringen (eller dekrementeringen).

På språk där ökning/minskning inte är ett uttryck (t.ex. Go ), behövs bara en version (i fallet Go, endast postoperatorer).

Eftersom operatorn inkrement/minska ändrar sin operand kan användning av en sådan operand mer än en gång inom samma uttryck ge odefinierade resultat. Till exempel i uttryck som x - ++x är det inte klart i vilken sekvens subtraktions- och inkrementoperationerna ska utföras. Sådana uttryck åberopar i allmänhet odefinierat beteende och bör undvikas.

På språk med inskrivna pekare som C, stegoperatorn stegar pekaren till nästa objekt av den typen - ökar värdet på pekaren med storleken på den typen. När en pekare (av rätt typ) pekar på något objekt i en array, gör ökningen (eller minskningen) att pekaren pekar på "nästa" (eller "föregående") objekt i den arrayen. När en pekare har en typ av pekare-till-heltal, ökar den pekaren att den pekar till nästa heltal (normalt ökar det med 4 byte). När en pekare har en typ pekare-till-anställd, ökar den pekaren att den pekar till nästa "anställd" - om storleken på anställds struktur är 106 byte, ökar den pekaren med 106 byte.

Exempel

Följande C-kodfragment illustrerar skillnaden mellan operatorerna före och efter inkrement och dekrement:

 
 



  
      


  
      



  
      


  
       int  x  ;  int  y  ;  // Ökningsoperatorer  // Pre-inkrement: x ökas med 1, sedan tilldelas y värdet x  x  =  1  ;  y  =  ++  x  ;  // x är nu 2, y är också 2  // Efterökning: y tilldelas värdet x, sedan ökas x med 1  x  =  1  ;  y  =  x  ++  ;  // y är 1, x är nu 2  // Dekrementerande operatorer  // Pre-decrement: x minskas med 1, sedan tilldelas y värdet x  x  =  1  ;  y  =  --  x  ;  // x är nu 0, y är också 0  // Efterdekrementering: y tilldelas värdet x, sedan minskas x med 1  x  =  1  ;  y  =  x  --  ;  // y är 1, x är nu 0 

På språk som saknar dessa operatorer kräver motsvarande resultat en extra kodrad:


  
      
        


  
        
       # Förökning: y = ++x  x  =  1  x  =  x  +  1  # x är nu 2 (kan skrivas som "x += 1" i Python)  y  =  x  # y är också 2  # Efterökning: y = x++  x  =  1  y  =  x  # y är 1  x  =  x  +  1  # x är nu 2 


Operatören efter inkrementering används vanligtvis med array- subscripts. Till exempel:


    

        
              0

       
              
                            
     
 // Summa elementen i en array  float  sum_elements  (  float  arr  [],  int  n  )  {  float  summa  =  0.0  ;  int  i  =  ;  medan  (  i  <  n  )  summa  +=  arr  [  i  ++  ];  // Efterökning av i, vilket steg  // genom n element i matrisen  returnerar  summan  ;  } 

Operatorn efter inkrement används också ofta med pekare :


      

       0        
             
                           
 // Kopiera en array till en annan  void  copy_array  (  float  *  src  ,  float  *  dst  ,  int  n  )  {  while  (  n  --  >  )  // Loop som räknar ner från n till noll  *  dst  ++  =  *  src  ++  ;  // Kopierar element *(src) till *(dst),  // ökar sedan båda pekarna  } 

Observera att dessa exempel även fungerar i andra C-liknande språk, som C++ , Java och C# .

  • Inkrementoperator kan demonstreras med ett exempel:
     
     
    
           
          
            
         0
     #include  <stdio.h>  int  main  ()  {  int  c  =  2  ;  printf  (  "%d  \n  "  ,  c  ++  );  // denna sats visar 2, sedan ökas c med 1 till 3.  printf  (  "%d"  ,  ++  c  );  // denna sats ökar c med 1, sedan visas c.  återvända  ;  } 
    
    • Produktion:
      
       2  4 
      

Stödspråk

Följande lista, även om den inte är komplett eller heltäckande, listar några av de stora programmeringsspråken som stöder ++ / -- inkrement/minska operatorer.

(Apples Swift stödde en gång dessa operatörer, men stödet togs bort från och med version 3.)

Pascal , Delphi , Modula-2 och Oberon tillhandahåller samma funktioner, men de kallas inc(x) och dec(x).

Särskilt Python och Rust stöder inte dessa operatörer.

Historia

Konceptet introducerades i programmeringsspråket B cirka 1969 av Ken Thompson .

Thompson gick ett steg längre genom att uppfinna operatorerna ++ och --, som ökar eller minskar; deras prefix- eller postfixposition avgör om ändringen sker före eller efter notering av operandens värde. De var inte i de tidigaste versionerna av B, men dök upp längs vägen. Människor gissar ofta att de skapades för att använda auto-inkrement och auto-decrement adresslägen som tillhandahålls av DEC PDP-11 där C och Unix först blev populära. Detta är historiskt omöjligt, eftersom det inte fanns någon PDP-11 när B utvecklades. PDP-7 hade dock några "auto-inkrementerande" minnesceller, med egenskapen att en indirekt minnesreferens genom dem ökade cellen. Denna funktion föreslog förmodligen sådana operatörer för Thompson; generaliseringen att göra dem till både prefix och postfix var hans egen. Faktum är att de automatiska inkrementcellerna inte användes direkt i implementeringen av operatörerna, och en starkare motivation för innovationen var förmodligen hans observation att översättningen av ++x var mindre än den för x=x+1.

Se även