Benutzer mit den meisten Antworten
Verkettung von Strings

Frage
-
Hallo,
ich habe eine Frage zum Thema Verkettung von zwei strings. Vor kurzem schrieb ich in der Schule einen Test, in dem eine Aufgabe dran kam, welche folgendermaßen gestellt war:
"Programmieren sie ein "HelloWorld"-Programm. Deklarieren und verwenden Sie eine globale Variable. Nach dem Drücken der Tab-Taste soll der Wert der Variable in einer TextBox mit der Bezeichnung "txtAusgabe" ausgegeben werden. Weitere Eingaben soll das Programm verketten."
Es gab eine Eingabe- und AusgabeTextBox!
In meinem Programm sah es nun folgendermaßen aus:
void txtEingabeLeave(object sender, EventArgs e) { GlobaleVariable = txtEingabe.Text; txtAusgabe.Text = txtAusgabe.Text + GlobaleVariable; }
Mein Lehrer hätte es gerne so:
void txtEingabeLeave(object sender, EventArgs e) { GlobaleVariable = GlobaleVariable + txtEingabe.Text; txtAusgabe.Text = GlobaleVariable; }
Gibt es einen wirklichen Unterschied zwischen den beiden Varianten? Wenn ja welchen?
Er hat die ganze Zeit argumentiert das ich mit meinem Code das Steuerelement txtAusgabe "missbrauche" und ich damit schnell an Grenzen kommen würde. Er konnte mir leider keine Antwort geben an welche Grenzen.
Mfg Petzi
Antworten
-
Hallo Peter,
aus der Aussage Nach dem Drücken der Tab-Taste soll der Wert der Variable in einer TextBox mit der Bezeichnung "txtAusgabe" ausgegeben werden. Weitere Eingaben soll das Programm verketten." kann ich das beim besten Willen nicht herleiten, welchen Zustand GlobaleVariable haben soll - siehe auch meine parallel entstandene Antwort.
Was voraussetzt, Petzi hat die Aufgabenstellung richtig wiedergegeben.
Auf der anderen Seite wissen wir, die es länger praktizieren, wie schwer es ist, eine Aufgabenstellung exakt ohne Widersprüche zu formulieren - und auch wie gerne Aufgabenstellungen von ihren Auftraggebern "nachgebessert" werden, wenn sie ihrer Meinung nach falsch implementiert wurden.
Beides sollte in einem Programmierunterricht vermieden werden, da es für keine Seite hilfreich ist.
Gruß Elmar
- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 11:46
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:24
-
Hi,
"globale" Variable speichern den Inhalt auch nach der Abarbeitung einer Methode, so dass beim nächsten Aufruf der Methode dieser Wert wieder bereitsteht. In Deiner Variante wird nach jedem Durchlauf nur der letzte Wert aus der TextBox gespeichert. In der Aufgabe steht aber, dass verkettet werden soll. Also muss zunächst der alte Wert mit dem TextBox-Inhalt verkettet und gemerkt (gespeichert) werden und dann das Ergebnis der Verkettung angezeigt werden. Somit hat Dein Lehrer Recht. Bei Deiner Variante benötigst Du keine globale Variable. Also sollte bei einer Aufgabenstellung jedes Wort hinterfragt werden und überlegt werden, warum da so gefordert sein könnte. Ein Programmierer hat es bei Aufgabenstellungen meist mit Nicht-Programmierern zu tun und deren Beschreibung muss sehr genau analysiert werden.Den Unterschied zwischen Deiner Variante und der des Lehrers kannst Du ganz einfach über mehrere Durchläufe testen. Ändere dazu jedes Mal den Inhalt der TextBox und verlasse die TextBox.
--
Peter
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 07:25
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
-
Hi,
mit nachfolgendem Code siehst Du den signifikanten Unterschied. Die "globale" Variable hat die Aufgabe, einen Wert zwischen den Aufrufen der Methoden zwischen zu speichern.using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form4 : Form { public Form4() { InitializeComponent(); } string GlobaleVariable; string GlobaleVariable2; TextBox txtEingabe; TextBox txtAusgabe; TextBox txtEingabe2; TextBox txtAusgabe2; Label lbl1; protected override void OnLoad(EventArgs e) { base.OnLoad(e); txtEingabe = new TextBox() { Top = 10, Left = 10 }; txtAusgabe = new TextBox() { Top = 10, Left = 150 }; txtEingabe2 = new TextBox() { Top = 40, Left = 10 }; txtAusgabe2 = new TextBox() { Top = 40, Left = 150 }; lbl1 = new Label() { Top = 70, Left = 10 }; Button btn1 = new Button() { Top = 100, Left = 10, Text = "Drück mich" }; this.Controls.AddRange(new Control[] { btn1, txtAusgabe, txtEingabe, txtAusgabe2, txtEingabe2, lbl1 }); txtEingabe.Leave += txtEingabe_Leave; txtEingabe2.Leave += txtEingabe2_Leave; } void txtEingabe_Leave(object sender, EventArgs e) { GlobaleVariable = txtEingabe.Text; txtAusgabe.Text = txtAusgabe.Text + GlobaleVariable; lbl1.Text = string.Format("Variante 1: {0}", GlobaleVariable); } void txtEingabe2_Leave(object sender, EventArgs e) { GlobaleVariable2 = txtEingabe2.Text + GlobaleVariable2; txtAusgabe2.Text = GlobaleVariable2; lbl1.Text = string.Format("Variante 2: {0}", GlobaleVariable2); } } }
--
Peter
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 08:30
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
-
Hallo Petzi,
Es gibt keinen Unterschied, was das Anzeige angeht. Der einzige Unterschied besteht darin, welchen Wert GlobaleVariable beim Verlassen enthält - bei Dir die letzte Eingabe, bei der Variante des Lehrer den kombinierten Wert. Falls das nicht exakt so spezifiziert wurde, sind die Grenzen, die er nebulös verkündet, von ihm selbst gesetzt. Aus dem gezeigten Abschnitt lässt sich nicht herleiten, welche weitere Verwendung GlobaleVariable haben soll (siehe auch unten).
Globale Variablen vermeidet man in der (objektorientierten) Programmierung, wo immer es geht. Man wird immer den geringstmöglichen Sichtbarkeit- und Geltungsbereich verwenden, und hier wäre eine Klassen-Variable (Feld) hinreichend. (Sollte GlobaleVariable auf Klassenebene - nicht statisch - definiert sein, so wäre sie falsch benannt.)
Die Aussage, man könne ein "Steuerelement missbrauchen" trifft nicht zu. Ein Steuerelement ist zuerst eine Klasse wie jede andere. Jede Klasse sollte so entworfen sein, dass ihre Verwendung keine Probleme verursacht, und u. a. das Prinzip der Kapselung beachtet wird. Und so ist die Verwendung der Text-Eigenschaft eines Steuerelements hier ebenso möglich wie die Verwendung einer zusätzlichen Variable oder Eigenschaft.
Der Weg, den der Lehrer aufzeigt, ist nur mit freundlicher Unterstützung der String.Concat Methode lauffähig, die Nullwerte durch String.Empty ersetzt und beim Verketten (+) von zwei String-Variablen verwendet wird. In anderen Programmiersprachen kann sie Fehler verursachen, wenn GlobaleVariable nicht initialisiert ist. Es verletzt die Regel, dass man Seiteneffekte beim Programmieren vermeidet. Deine Variante vermeidet dies, auch wenn Du es vermutlich nicht bemerkt hast, denn die Text-Eigenschaft stellt hier sicher, dass kein Null-Wert geliefert wird (was ebenfalls spezifisch für die Umgebung ist).
Wobei die Variable zum Erreichen des Ergebnisses (Anzeige des verketteten Eingaben) nicht notwendig wäre und nur durch die Aufgabenstellung eingeführt wird. Eine Zeile
txtAusgabe.Text = txtAusgabe.Text + txtEingabe.Text
hätte es auch getan.
Was nebenbei die zusätzliche Komplexität durch die Einführung einer weiteren Variablen vermeidet. Deren Verwendung muss dokumentiert und nachverfolgt werden und erhöht (in komplexeren Programmen) den Aufwand und verringert die Wartbarkeit. Zudem erhöht sie den Speicherbedarf, die Zahl der Anweisungen und verringert dadurch die Effizienz.
Für die Implementation einer Rückgängig (Undo) Funktionalität wäre ein Stapel (Stack) und der Einsatz des Memento Musters angemessen. Wobei diese Aufgabe über den derzeit behandelten Unterrichtsstoff hinausgehen dürfte.
Gruß Elmar
P. S.: Klopf Dir nicht zu kräftig auf die Schulter und bedenke, auch Dein Lehrer hat (vermutlich) keine 30 Jahre programmiert ;)
- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 11:46
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
Alle Antworten
-
Hi,
"globale" Variable speichern den Inhalt auch nach der Abarbeitung einer Methode, so dass beim nächsten Aufruf der Methode dieser Wert wieder bereitsteht. In Deiner Variante wird nach jedem Durchlauf nur der letzte Wert aus der TextBox gespeichert. In der Aufgabe steht aber, dass verkettet werden soll. Also muss zunächst der alte Wert mit dem TextBox-Inhalt verkettet und gemerkt (gespeichert) werden und dann das Ergebnis der Verkettung angezeigt werden. Somit hat Dein Lehrer Recht. Bei Deiner Variante benötigst Du keine globale Variable. Also sollte bei einer Aufgabenstellung jedes Wort hinterfragt werden und überlegt werden, warum da so gefordert sein könnte. Ein Programmierer hat es bei Aufgabenstellungen meist mit Nicht-Programmierern zu tun und deren Beschreibung muss sehr genau analysiert werden.Den Unterschied zwischen Deiner Variante und der des Lehrers kannst Du ganz einfach über mehrere Durchläufe testen. Ändere dazu jedes Mal den Inhalt der TextBox und verlasse die TextBox.
--
Peter
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 07:25
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
-
Danke für deine Antwort.
Ich glaube da ging jetzt aber was bei unter. Meine Variante führt zum gleichen Ergebnis wie die meines Lehrers. Die globale Variable sollte nur erstellt werden, weil er wissen wollte ob wir damit umgehen können. Für die reine Funktion hätte es eine Lokale Variable ebenfalls getan oder sogar komplett ohne.
z.B. so:
void txtEingabeLeave(object sender, EventArgs e) { txtAusgabe.Text = txtAusgabe.Text + txtEingabe.Text; }
Was eventuell noch für das Verständnis der Aufgabenstellung hilft:
https://www dropbox.com/s/pqjat5rvld77ofh/TestAufgabe.JPG?dl=0
(Sorry für den Link, kann derzeit leider keine Bilder Uploaden)
So in etwa sah die Aufgabe aus. Ich habe hier bereits meine Lösung hinein geschrieben.
Es geht als rein darum, dass er behauptet, dass ich mit meiner Variante schnell an Grenzen komme. Teste ich das ganze aber funktioniert es einwandfrei. Was möchte er mir also mitteilen.
Laut seiner Variante frage ich bei jedem Tab den Inhalt der Variable und der EingabeTextBox ab und überspeicher die Variable.
In meiner Variante Frage ich einfach den Inhalt der AusgabeTextBox und meiner Variable ab und überspeicher die AusgabeTextBox.
Ergebnis: Beide Programme machen das gleiche.
Aber seine Worte waren: "Steuerelemente dürfen so nicht missbraucht werden." Es handle sich dabei nicht um richtiges programmieren und ich komme schnell an die Grenzen des Programms...
-
Hi,
mit nachfolgendem Code siehst Du den signifikanten Unterschied. Die "globale" Variable hat die Aufgabe, einen Wert zwischen den Aufrufen der Methoden zwischen zu speichern.using System; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form4 : Form { public Form4() { InitializeComponent(); } string GlobaleVariable; string GlobaleVariable2; TextBox txtEingabe; TextBox txtAusgabe; TextBox txtEingabe2; TextBox txtAusgabe2; Label lbl1; protected override void OnLoad(EventArgs e) { base.OnLoad(e); txtEingabe = new TextBox() { Top = 10, Left = 10 }; txtAusgabe = new TextBox() { Top = 10, Left = 150 }; txtEingabe2 = new TextBox() { Top = 40, Left = 10 }; txtAusgabe2 = new TextBox() { Top = 40, Left = 150 }; lbl1 = new Label() { Top = 70, Left = 10 }; Button btn1 = new Button() { Top = 100, Left = 10, Text = "Drück mich" }; this.Controls.AddRange(new Control[] { btn1, txtAusgabe, txtEingabe, txtAusgabe2, txtEingabe2, lbl1 }); txtEingabe.Leave += txtEingabe_Leave; txtEingabe2.Leave += txtEingabe2_Leave; } void txtEingabe_Leave(object sender, EventArgs e) { GlobaleVariable = txtEingabe.Text; txtAusgabe.Text = txtAusgabe.Text + GlobaleVariable; lbl1.Text = string.Format("Variante 1: {0}", GlobaleVariable); } void txtEingabe2_Leave(object sender, EventArgs e) { GlobaleVariable2 = txtEingabe2.Text + GlobaleVariable2; txtAusgabe2.Text = GlobaleVariable2; lbl1.Text = string.Format("Variante 2: {0}", GlobaleVariable2); } } }
--
Peter
Meine Homepage mit Tipps und Tricks- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 08:30
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
-
Hallo Petzi,
Es gibt keinen Unterschied, was das Anzeige angeht. Der einzige Unterschied besteht darin, welchen Wert GlobaleVariable beim Verlassen enthält - bei Dir die letzte Eingabe, bei der Variante des Lehrer den kombinierten Wert. Falls das nicht exakt so spezifiziert wurde, sind die Grenzen, die er nebulös verkündet, von ihm selbst gesetzt. Aus dem gezeigten Abschnitt lässt sich nicht herleiten, welche weitere Verwendung GlobaleVariable haben soll (siehe auch unten).
Globale Variablen vermeidet man in der (objektorientierten) Programmierung, wo immer es geht. Man wird immer den geringstmöglichen Sichtbarkeit- und Geltungsbereich verwenden, und hier wäre eine Klassen-Variable (Feld) hinreichend. (Sollte GlobaleVariable auf Klassenebene - nicht statisch - definiert sein, so wäre sie falsch benannt.)
Die Aussage, man könne ein "Steuerelement missbrauchen" trifft nicht zu. Ein Steuerelement ist zuerst eine Klasse wie jede andere. Jede Klasse sollte so entworfen sein, dass ihre Verwendung keine Probleme verursacht, und u. a. das Prinzip der Kapselung beachtet wird. Und so ist die Verwendung der Text-Eigenschaft eines Steuerelements hier ebenso möglich wie die Verwendung einer zusätzlichen Variable oder Eigenschaft.
Der Weg, den der Lehrer aufzeigt, ist nur mit freundlicher Unterstützung der String.Concat Methode lauffähig, die Nullwerte durch String.Empty ersetzt und beim Verketten (+) von zwei String-Variablen verwendet wird. In anderen Programmiersprachen kann sie Fehler verursachen, wenn GlobaleVariable nicht initialisiert ist. Es verletzt die Regel, dass man Seiteneffekte beim Programmieren vermeidet. Deine Variante vermeidet dies, auch wenn Du es vermutlich nicht bemerkt hast, denn die Text-Eigenschaft stellt hier sicher, dass kein Null-Wert geliefert wird (was ebenfalls spezifisch für die Umgebung ist).
Wobei die Variable zum Erreichen des Ergebnisses (Anzeige des verketteten Eingaben) nicht notwendig wäre und nur durch die Aufgabenstellung eingeführt wird. Eine Zeile
txtAusgabe.Text = txtAusgabe.Text + txtEingabe.Text
hätte es auch getan.
Was nebenbei die zusätzliche Komplexität durch die Einführung einer weiteren Variablen vermeidet. Deren Verwendung muss dokumentiert und nachverfolgt werden und erhöht (in komplexeren Programmen) den Aufwand und verringert die Wartbarkeit. Zudem erhöht sie den Speicherbedarf, die Zahl der Anweisungen und verringert dadurch die Effizienz.
Für die Implementation einer Rückgängig (Undo) Funktionalität wäre ein Stapel (Stack) und der Einsatz des Memento Musters angemessen. Wobei diese Aufgabe über den derzeit behandelten Unterrichtsstoff hinausgehen dürfte.
Gruß Elmar
P. S.: Klopf Dir nicht zu kräftig auf die Schulter und bedenke, auch Dein Lehrer hat (vermutlich) keine 30 Jahre programmiert ;)
- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 11:46
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:23
-
Hallo Peter,
aus der Aussage Nach dem Drücken der Tab-Taste soll der Wert der Variable in einer TextBox mit der Bezeichnung "txtAusgabe" ausgegeben werden. Weitere Eingaben soll das Programm verketten." kann ich das beim besten Willen nicht herleiten, welchen Zustand GlobaleVariable haben soll - siehe auch meine parallel entstandene Antwort.
Was voraussetzt, Petzi hat die Aufgabenstellung richtig wiedergegeben.
Auf der anderen Seite wissen wir, die es länger praktizieren, wie schwer es ist, eine Aufgabenstellung exakt ohne Widersprüche zu formulieren - und auch wie gerne Aufgabenstellungen von ihren Auftraggebern "nachgebessert" werden, wenn sie ihrer Meinung nach falsch implementiert wurden.
Beides sollte in einem Programmierunterricht vermieden werden, da es für keine Seite hilfreich ist.
Gruß Elmar
- Als Antwort vorgeschlagen Aleksander Chalabashiev Freitag, 7. November 2014 11:46
- Als Antwort markiert Aleksander Chalabashiev Dienstag, 11. November 2014 07:24
-
Habe den Beitrag von Elmar überlesen. Trifft aber genau auf das was ich meine.
Zudem bin ich jetzt wieder etwas schlauer geworden.
Es ist richtig, dass ich meine Lösung nicht bewusst gewählt habe, um ausschließen zu können das mein string einen Null-Wert aufweist. Aber das ist ja nicht das Problem gewesen.
Eine Frage hätte ich noch.
Ist es richtig, dass es beim Ablauf des Programms länger dauert um Inhalte von Steuerelementen abzufragen als von Variablen?
Merkbar kann man auf jeden Fall ausschließen bei den heutigen Rechnerleistungen aber prinzipiell frage ich mich das.
Dankeschön
- Bearbeitet PetziBaer_69 Freitag, 7. November 2014 09:49
-
Hi,
natürlich sind Zuweisungen von Werten zu skalaren Variablen vom Wertetyp schneller als Zuweisungen an Innereien in komplexeren Objekten wie Steuerelementen. Dieser Unterschied liegt aber im Mikrosekundenbereich und ist vernachlässigbar gegenüber den Vorteilen einer objektorientierten Programmierung. In Deinem Fall ist die Verkettung von Zeichenketten um ein Vielfaches aufwändiger, da Zeichenketten vom Referenztyp sind und beim Verketten die Inhalte im Speicher (Heap) kopiert werden müssen.--
Peter