Die Addition in C# [] (Die Addition in C#), Lektion, Seite 723355
https://www.purl.org/stefan_ram/pub/addition_csharp (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C#-Kurs

Die Addition »… + …« in C♯ 

Einführendes Beispiel

In C♯  kann auch eine Summe in der gewohnten Schreibweise als Ausdruck verwendet werden. Die Addition wird mit dem Pluszeichen »+« geschrieben.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 1 ); }}
global::System.Console.Out
2

Syntax

Wir erweitern das Syntaxdiagramm für Ausdrücke um den Additionsoperator »+«.

Neue, erweiterte Syntax
Ausdruck
.----------.
---.----------->| Literal |---------------------------.---->
| '----------' |
| .-. .----------. |
'--->( - )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. |
'--->( + )-->| Ausdruck |---------------------------'
| '-' '----------' |
| .-. .----------. .-. |
'--->( ( )-->| Ausdruck |-->( ) )-------------------'
| '-' '----------' '-' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( / )-->| Ausdruck |----'
| '----------' '-' '----------' |
| .----------. .-. .----------. |
'----------->| Ausdruck |-->( + )-->| Ausdruck |----'
'----------' '-' '----------'

Die Addition wird mit dem Pluszeichen »+« geschrieben. Sind A  und a  zwei Ausdrücke, so ist A +a  wieder ein Ausdruck, die Summe  von A  und a. Dabei wird A  auch Augend  und a  Addend  genannt. (Diese vereinfachte Syntax bringt die Priorität und Assoziativität der Addition nicht richtig zum Ausdruck. Diese beiden werden daher weiter unten separat erklärt.)

Typanforderungen

Der Augend und der Addend kann jeden der bisher vorgestellten Typen haben.

Typ

Ist der Typ des einen Operanden »string«, so wird der Wert des anderen Operand in diesen Typ gewandelt, und das Ergebnis der Addition hat den Typ »string«. Andernfalls gilt: Ist der Typ des einen Operanden »double«, so wird der Wert des anderen Operand nach »double« gewandelt, und der Typ des gesamten Ausdrucks hat den Typ »double«. Sonst hat der gesamte Ausdruck den Typ »int«.

Typregeln für den Fall, daß ein Operand den Typ »string« hat

string  + … → string 
+ string string 

Typregeln für den Fall, daß kein  Operand den Typ »string« hat

double  + … → double 
+ double double 
int  + int int 

Wert

Bei der Auswertung einer Addition werden beide Operanden ausgewertet. Der Wert eines Additionsausdrucks mit einer Zeichenkette ist die Verkettung (Hintereinanderschreibung) der Zeichenketten (Zeichenfolgen) der beiden Operanden (Beispiele dazu folgen weiter unten). Der Wert eines Additionsausdrucks mit numerischen Operanden ist die Summe dieser Operanden.

Numerische Operanden

Wir betrachten zunächst numerische  Operandenausdrücke. Bei diesen erfolgt die Typangleichung so wie bei der Division, nur daß es hier weniger Überraschungen mit Nachkommastellen gibt, weil die Addition zweier ganzzahliger  Werte auch in der Mathematik keine Nachkommastellen ergibt.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 1 ); }}
global::System.Console.Out
2
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 1.0 ); }}
global::System.Console.Out
2
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.0 + 1 ); }}
global::System.Console.Out
2
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.0 + 1.0 ); }}
global::System.Console.Out
2

Zeichenfolgenaddition

Der Operator »+« ist wie der zuvor vorgestellte Operation »/« polymorph und hat sogar noch eine zusätzliche „Überladung“ (d.h.: Bedeutung) für den Typ »string«. Falls beide Operanden Zeichenfolgen sind, so bedeutet dieser Operator die Schreibung der rechten Zeichenfolgen hinter die linke (also eine Hintereinanderschreibung / Verkettung in der gegebenen Reihenfolge).

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( "1." + "2.a" ); }}
global::System.Console.Out
1.2.a

Zeichenfolgenaddition mit Zahlen

Bei Ausdrücken der Signatur int +string, string +int, double +string  oder string +double  wird, wie schon oben festgehalten, der jeweils andere Operandenwert auch nach string  gewandelt  (also in eine Darstellung als Zeichenfolge umgewandelt) und anschließend eine Verkettung  der beiden Zeichenfolgen vorgenommen.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 2 + "3a" ); }}
global::System.Console.Out
23a
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( "2" + 3 ); }}
global::System.Console.Out
23
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 2 + "x" ); }}
global::System.Console.Out
2x
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 3.0 + "x" ); }}
global::System.Console.Out
3x

Zeichenfolgendarstellung

Die Addition des leeren Textes zu einer Zahl wird manchmal verwendet, um diese als Zeichenfolge darzustellen (in eine Zeichenfolge umzuwandeln). Später werden im Kurs auch noch Fälle gezeigt werden, in denen solch eine Umwandlung nützlich ist.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( "" + 2 ); }}
global::System.Console.Out
2
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 2 + "" ); }}
global::System.Console.Out
2

An den obenstehenden Programmbeispielen kann man aber noch nicht erkennen, daß wirklich etwas umgewandelt wurde. Das folgende Programm zeigt aber deutlich, daß »( 2 + "" )« ein string ist, weil bei der folgenden Addition von »3« eine Verkettung und keine arithmetische Summierung vorgenommen wird.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( ( 2 + "" )+ 3 ); }}
transcript
23

Zum Vergleich mit dem vorigen Programm zeigt das folgende Programm die arithmetische Summierung.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( ( 2 + 0 )+ 3 ); }}
global::System.Console.Out
5

Gelegentlich wird die Wandlung in eine Zeichenfolge mit »+ ""« als „unverständlich“ kritisiert. Es wird behauptet, daß ein Leser eines Programms an »+ ""« die Absicht des Programmierers, etwas in eine Zeichenfolge zu wandeln, nicht erkennen könne. Diese Kritik ist allerdings nicht berechtigt. Falls ein C♯ -Programmierer die Bedeutung von »+ ""« nicht kennt, dann liegt dies daran, daß er seine Ausbildung noch nicht beendet hat – aber man kann schlecht verlangen, Programme für Leser schreiben, welche die Programmiersprache noch gar nicht kennen. Falls ein C♯ -Programmierer die Bedeutung von »+ ""« aber kennt, dann ist es ihm auch klar, daß damit eine Umwandlung in eine Zeichenfolge beabsichtigt ist, denn warum sollte jemand »+ ""« sonst verwenden?

Polymorphie

An diesem Operator kann man die Bedeutung des Wortes Polymorphie  besonders gut erklären, weil hier offensichtlich zwei ganz verschiedene Operationen in Abhängigkeit vom Typ der Operanden ausgeführt werden: die arithmetische Summierung und die Zeichenfolgenverkettung.

Arithmetische Summierung
123 + 456
Zeichenfolgenverkettung
"a" + "b"

Ohne  Polymorphie würde man für die Zeichenfolgenverkettung einen anderen  Operator verwenden (wie beispielsweise »&« oder ».«).

Die Polymorphie ist in diesem Falle umstritten, da man es in Frage stellen kann, ob man das Verketten von Zeichenketten als eine Art von „Addition“ ansehen darf. Falls dem nicht so wäre, dann wäre es falsch oder schlechter Stil, das Additionszeichen »+« dafür mitzuverwenden. Jedoch könnte man dies dann nur den Gestaltern der Programmiersprache vorwerfen, nicht aber ihren Benutzern (also den Programmierern). Deswegen sollte sich der Leser durch diese Bedenken nicht davon abhalten lassen, die Verkettung mit dem Pluszeichen »+« jederzeit zu verwenden, wenn sie ihm als nützlich erscheint.

Die Kritiker sehen in dem mathematischen Symbol »+« ein Zeichen, das für eine kommutative  Operation steht, eine Operation also, bei der die Reihenfolge der Operanden auch vertauscht werden kann, ohne das Ergebnis (die Summe) zu ändern. Sie sagen, daß das Summenzeichen für die Zeichenfolgenverkettung nicht  verwendet werden sollte, weil diese nicht kommutativ ist. Dabei übersehen sie aber, daß man das Symbol »+« auch in der Mathematik manchmal für nicht-kommutative  Operationen (in Monoiden) verwendet. Außerdem ist die Polymorphie mit ihrer „metaphorischen Verwendung“ von Verben ein wichtige Eckpfeiler der objektorientierten Programmierung (wie später im Kurs behandelt werden wird), und daher paßt es zu einer objektorientierten Programmiersprache, diese auch bei Operatoren zu verwenden. Schließlich gibt es in der Praxis keine Probleme mit dieser Überladung des +-Operators.

Linksassoziativität

Ohne Klammerung wird bei einer Addition der Form » + + « zuerst die am weitesten links  stehende Summe auswertet. (Dabei stehen die Ellipsen »« für Literale, Klammerausdrücke oder Quotienten.)

In dem folgenden Programmbeispiel wird daher zuerst eine numerische Summe  berechnet und erst danach eine Zeichenfolgenverbindung  vorgenommen.

In der folgenden Darstellung der bei der Auswertung eines Ausdrucks erfolgenden Operationen, gehört zu jeder Operation ein nach rechts weisender Pfeil. Der von der Operation ausgewertete Teilausdruck ist durch einen waagerechten Strich über ihm gekennzeichnet.

Operationen bei der Auswertung von »1 + 2 + "4"«:

Operation arithmetische Summierung von »1« und »2«, Ergebnis »3«.
_____
1 + 2 + "4" →
3 + "4"
Operation Wandlung von »3« in die Zeichenfolge »"3"« und Verkettung von »"3"« und »"4"«, Ergebnis »34«.
_______
3 + "4" →
"34"
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 2 + "4" ); }}
global::System.Console.Out
34

Operationen bei der Auswertung von »"1" + 2 + 4«

Operation Wandlung von »2« in die Zeichenfolge »"2"« und Verkettung von »"1"« und »"2"«, Ergebnis: »"12"«.
_______
"1" + 2 + 4 →
"12" + 4
Operation Wandlung von »4« in die Zeichenfolge »"4"« und Verkettung von »"12"« und »"4"«, Ergebnis: »"124"«.
________
"12" + 4 →
"124"
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( "1" + 2 + 4 ); }}
global::System.Console.Out
124

Das folgende Programmbeispiel zeigt eine Kombination aller drei Typen »int«, »double« und »string«.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 2.0 + "a" ); }}
global::System.Console.Out
3a

Das folgende Programmbeispiel zeigt, daß die Addition der leeren Zeichenfolge »""« einen Text nicht verändert, so wie die Addition von »0« eine Zahl nicht verändert.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( ">" + "" + "<" ); }}
global::System.Console.Out
><
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1 + 0 + 1 ); }}
global::System.Console.Out
2

Priorität

Die Priorität  der Addition ist kleiner  als die der Division. Das heißt, daß ein Ausdruck, der ein Literal oder ein Klammerausdruck ist und direkt zwischen einem »+« und einem »/« steht, zu dem »/« gezählt wird.

Operationen bei der Auswertung von »2 + 4.0/2«.

Operation Wandlung von »2« in »2.0« und Division von »4.0« durch »2.0«, Ergebnis: »2.0«.
     _____
2 + 4.0/2 →
2 + 2.0
Operation Wandlung von »2« in »2.0« und Addition von »2.0« und »2.0«, Ergebnis: »4.0«.
________
2 + 2.0 →
4.0
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 2 + 4.0/2 ); }}
global::System.Console.Out
4

Um eine spezielle gewünschte Zusammenfassung  zu erreichen, können Ausdruckklammern  verwendet werden.

Operationen bei der Auswertung von »( 2 + 4.0 )/2«.

Operation Wandlung von »2« in »2.0« und Addition von »2.0« und »4.0«, Ergebnis: »6.0«.
___________
( 2 + 4.0 )/2 →
6.0 /2
Operation Wandlung von »2« in »2.0« und Division von »6.« durch »2.0«, Ergebnis: »3.0«.
_____
6.0/2 →
3.0
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( ( 2 + 4.0 )/ 2 ); }}
global::System.Console.Out
3

Vorzeichen  haben eine höhere Priorität als die Addition:

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( -3 + 9 ); }}
global::System.Console.Out
6
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( -( 3 + 9 ) ); }}
global::System.Console.Out
-12

In der folgenden Tabelle haben die Operatoren eine höhere Priorität, die weiter oben stehen.

Priorität der bisher behandelten Operatoren
()                   Eingeklammerter Ausdruck
+ - Unaere vorangestellte Operatoren
/ Division
+ Addition

Formatierung

Leeraum kann frei verwendet werden, um Ausdrücke übersichtlich zu schreiben.

Beispiele
2+4.0/2

2 + 4.0/2

2 + 4.0 / 2
Beispiele
(2+4.0)/2

( 2 + 4.0 )/ 2

( 2 + 4.0 ) / 2
Beispiel eines Ausdrucks, der über 3 Zeilen geht
( 2 + 4.0 ) 
/
2

»decimal« und »string«

Die Verkettung einer Zeichenfolge mit einem decimal-Wert ist möglich.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( "3" + 3m ); }}
global::System.Console.Out
33
Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 3m + "3" ); }}
global::System.Console.Out
33

decimal-Additionen

Bei Additionen mit decimal-Ausdrücken sind dieselben Kombinationen von Typen erlaubt wie zuvor bei Divisionen beschrieben. Bei nicht zu großen Werten ist die Skalierung der Summe das Maximum der Skalierungen der Operanden.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 1.000m + 1.00m ); }}
global::System.Console.Out
2.000

Bei großen Summen können hintere Stellen mit Werten unter 1 ungenau sein.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 12345678901234567890m + 0.12345678901234567890m ); }}
global::System.Console.Out
12345678901234567890.123456789

Numerische Überläufe

Summen können so groß werden, daß sie mit ihrem Typ nicht mehr darstellbar sind. In dem folgenden Beispiel sind die einzelnen Summanden als int-Werte darstellbar. Die Summe hat nach den Typregeln ebenfalls den Typ »int«, ist aber nicht mehr als int-Wert darstellbar, da sie dafür zu groß ist.

Program.cs
public static class Program
{ public static void Main()
{ global::System.Console.WriteLine
( 2147483647 + 2147483647 ); }}
global::System.Console.Out
Program.cs(4,7): error CS0220: The operation overflows at compile time in checked mode
global::System.Console.Out (übersetzt)
Program.cs(4,7): Fehler CS0220: Ueberlauf bei Uebersetzung in pruefendem Modus

Eine Web-Suche nach »Compiler Error« gefolgt von der Fehlerkennung, also beispielsweise nach »Compiler Error CS0220«, liefert weitere Informationen zu jener Kennung.

Die Abstraktion des unsichtbaren Implementation (black box ) *

Der Operator »+« wird in der Regel nur dadurch beschrieben, welches Ergebnis  er liefert. Die Technik, wie  der Operator »+« es erreicht, das richtige Ergebnis zu „finden“ wird verborgen. Dadurch wird der Verwender dieses Operators davon entlastet, sich über die Details der Umsetzung Gedanken machen zu müssen.

Man kann dies mit einer Maschine wie beispielsweise einem Fahrstuhl vergleichen: Der Bediener muß nur wissen, welche Wirkung die einzelnen Knöpfe haben (er muß also nur die Oberfläche zur Bedienung kennen), aber nicht, wie die Technik das im einzelnen realisiert. Das Innere der Maschine ist für den Benutzer nicht sichtbar (abstrahiert).

Die Umsetzung von Funktionen wird Implementation  (hier wäre dies also die „Implementation der Addition“) genannt. Die Implementation wird in der Programmierung oft verborgen.

Diese Abstraktion der „unsichtbaren Implementation“ (black box ) ist eine der wichtigsten Techniken, die in der Programmierung zur Beherrschung der Komplexität großer Programm eingesetzt wird.

Übungsfragen

?   Ausdrücke

Welcher der folgenden Ausdrücke hat denselben Wert wie »1 / 2+3«?

»1/( 2+3 )«   Anton
»( 1/2 )+ 3«  Berta

?   Ausdrücke

Welche Werte haben die folgenden Ausdrücke jeweils?

A »1/2.0 + 1/2«
B »1/( 1.0 + 1 )«
C »1 +( 9 + "C" )«
D »1 + 5 + "A"«

/   Bezeichnung eines Ausdrucks

Würden Sie den Ausdruck »2 + 4/2« als eine Summe oder als einen Quotienten bezeichnen? Begründen Sie ihre Wahl!

?   Verständnis von Fachbegriffen

Welchen Wert hat der Ausdruck »12/4+2«?

Angenommen die Addition hätte keine niedrigere Priorität als die Division, sondern eine höhere. Welchen Wert hätte dann der Ausdruck »12/4+2«?

Übungsaufgaben

/   Terme

Die in der Mathematik vorkommenden Schreibweisen für Werte werden Terme genannt. In C♯  verwendet man keine Terme. Die Ausdrücke von C♯  haben aber Ähnlichkeit mit Termen. Viele Terme lassen sich auch als Ausdruck schreiben und umgekehrt.

Schreiben Sie möglichst kurze Ausdrücke für die folgenden Terme, ohne vorher irgendwelche Teile der Terme im Kopf auszurechnen. Die Werte der Ausdrücke sollten den mathematischen Werten der vorgegebenen Terme möglichst nahe kommen, also den Werten, die man in der Grundschule als Werte der Terme ansehen würde.

Term (Ein Halb plus drei Viertel, erwartete Ausgabe zirka »1.25«)
 1       3
--- + ---
2 4
Term (Drei plus Vier im Zähler und Fünf plus Sechs im Nenner, erwartete Ausgabe zirka »0.6363636363636364«)
  3 + 4
---------
5 + 6

Falls beim Lösen der zweiten Übungsaufgabe die Lösung der ersten Übungsaufgabe noch aufbewahrt werden soll, so ist es am besten, die Lösung der ersten Übungsaufgabe in eine extra Textdatei zu kopieren, damit die Lösung der zweiten Übungsaufgabe übersichtlich bleibt. Es spricht aber auch nichts dagegen, wenn beim Lösen der zweiten Übungsaufgabe die Lösung der ersten Übungsaufgabe wieder verloren geht.

/   Beschriftung einer Ausgabe

Berechnen Sie mit C♯  die Summe 2+3 (diese soll nicht im Kopf ausgerechnet werden) und geben Sie das Ergebnis dann mit dem Text »2 + 3 = « (acht Zeichen) davor und dem Text ».« (ein Zeichen) dahinter aus.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723355 stefan_ram:723355 Die Addition in C# Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723355, slrprddef723355, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/addition_csharp