Modulo %

Der Modulo-Operator führt eine Restwert-Division zweier Elemente aus. Dieser Operator ist nur für Integer-Typen zulässig und entspricht der Berechnung des Restwertes einer Division.






1
0
6
#include <stdio.h>

int main(){
  int a = 20;
  int b = 7;
  printf("%d\n",  10 % 3);
  printf("%d\n",  10 % 2);
  printf("%d\n",  a % b);
  return 0;
}

Siehe auch Divisions-Operator /

Details

Der Modulo-Operator erwartet zwei Operanden als rvalues und wird von links nach rechts abgearbeitet. Der Rückgabewert ist ein rvalue und stets ein Integer-Typ.

Der Operator ist zulässig für Integer-Typen sowie den bool-Typ. Boolsche Werte werden als Integer-Werte aufgefasst. Der Modulo-Operator ist für Fliesskomma-Typen nicht zulässig. Der Compiler meldet einen Fehler wie invalid operands to binary %.

Die Modulo-Berechnung ergibt in C grundsätzlich nur mit positiven Werten sinnvolle Ergebnisse. Wenn der zweite Operand negativ ist, so wird dieses Vorzeichen von C schlichtweg ignoriert. Wenn der erste Operand negativ ist, so wird die Berechnung ausgeführt, als ob der Operand positiv wäre und schlussendlich dem Resultat das Vorzeichen wieder angehängt.

6
-6
-6
  printf("%d\n",   20 % -7);
  printf("%d\n",  -20 %  7);
  printf("%d\n",  -20 % -7);

Um somit auch mit negativen Werten korrekte Resultate zu erhalten, ist eine Addition des Modulo-Operanden mit anschliessender erneuter Modulo-Operation notwendig. Dies funktioniert auch mit positiven Werten.

1
6
  printf("%d\n", ((-20 % 7) + 7) % 7);
  printf("%d\n", (( 20 % 7) + 7) % 7);

Überladen des Operators

Der Modulo-Operator hat grundsätzlich die semantische Bedeutung einer Modulo-Operation im mathematischem Sinne. Allerdings gibt es Klassen, die eine andere Semantik definieren, beispielsweise das Unterteilen von Strings in gleich grosse Teilstrings. Auch weitere, ähnliche Anwendungen des Modulo-Operators wären denkbar, allerdings wird dieser Operator selten für Überladungen verwendet, da die Semantik oftmals nicht direkt ersichtlich ist.

Die Prototypen für das Überladen des Modulo-Operators sind die folgenden (Einschränkungen und Erläuterungen siehe Überladen von Operatoren):

inside class


outside class
Type operator %(Type);
Type operator %(Type) const;

Type operator %(Type, Type);

Im folgenden Beispiel werden zwei Klassen präsentiert für einen zweidimensionalen Vektor und eine zweidimensionale quadratische Matrix. Der überladene Modulo-Operator der Matrix gibt hier den gewünschten Kolonnenvektor zurück.
























1.000000, 2.000000
3.000000, 4.000000

Vector 0: 1.000000, 3.000000

Vector 1: 2.000000, 4.000000
#include <cstdio>

class Vector2{
  float a[2];
public:
  Vector2(float x, float y){a[0]=x; a[1]=y;}
  void print(){printf("%f, %f\n", a[0], a[1]);}
};

class Matrix22{
  float a[4];
public:
  Matrix22(float d1, float d2, float d3, float d4){
    a[0]=d1; a[1]=d2; a[2]=d3; a[3]=d4;
  }
  void print(){printf("%f, %f\n%f, %f\n",
                      a[0], a[1], a[2], a[3]);}
  
  Vector2 operator %(int i) const {
    return Vector2(a[0 + i], a[2 + i]);
  }
};

int main(){
  Matrix22 m(1, 2, 3, 4);
  m.print();
  printf("Vector 0: ");
  (m % 0).print();
  printf("Vector 1: ");
  (m % 1).print();
  return 0;
}