Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einführung
2 Grundlagen der Sprachsyntax
3 Klassendesign
4 Weitere Datentypen
5 Multithreading
6 Collections und LINQ
7 Eingabe und Ausgabe
8 Anwendungen: Struktur und Installation
9 Code erstellen und debuggen
10 Einige Basisklassen
11 Windows-Anwendungen erstellen
12 Die wichtigsten Steuerelemente
13 Tastatur- und Mausereignisse
14 MDI-Anwendungen
15 Grafiken mit GDI+
16 Drucken
17 Entwickeln von Steuerelementen
18 Programmiertechniken
19 WPF – Grundlagen
20 Layoutcontainer
21 WPF-Steuerelemente
22 Konzepte von WPF
23 Datenbankverbindung mit ADO.NET
24 Datenbankabfragen mit ADO.NET
25 DataAdapter
26 Offline mit DataSet
27 Datenbanken aktualisieren
28 Stark typisierte DataSets
A Anhang: Einige Übersichten
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual Basic 2008 von Andreas Kuehnel, Stephan Leibbrandt
Das umfassende Handbuch
Buch: Visual Basic 2008

Visual Basic 2008
3., aktualisierte und erweiterte Auflage, geb., mit DVD
1.323 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1171-0
Pfeil 2 Grundlagen der Sprachsyntax
Pfeil 2.1 Konsolenanwendungen
Pfeil 2.1.1 Allgemeine Anmerkungen
Pfeil 2.1.2 Der Projekttyp »Konsolenanwendung«
Pfeil 2.1.3 Die Vorlage »Konsolenanwendung«
Pfeil 2.2 Kommentare und Anweisungen
Pfeil 2.2.1 Einfache Kommentare
Pfeil 2.2.2 Hilfekommentare
Pfeil 2.2.3 Funktionsaufrufe (Methoden)
Pfeil 2.2.4 Anweisungen
Pfeil 2.3 Programmausführung
Pfeil 2.3.1 Ausgabe mit WriteLine
Pfeil 2.3.2 Start und Test
Pfeil 2.3.3 Unterbrechung mit ReadLine
Pfeil 2.4 Projektorganisation
Pfeil 2.4.1 Namensräume und Imports
Pfeil 2.4.2 Lösungen als Hyperprojekt
Pfeil 2.4.3 Existierende Projekte hinzufügen
Pfeil 2.4.4 Neues Projekt hinzufügen
Pfeil 2.4.5 Quellcodegliederung
Pfeil 2.4.6 Refactoring
Pfeil 2.5 Variablen und Datentypen
Pfeil 2.5.1 Explizite und implizite Variablen (Option Explicit)
Pfeil 2.5.2 Typisierte und untypisierte Variablen (Option Strict)
Pfeil 2.5.3 Variablendeklaration
Pfeil 2.5.4 Einfache Datentypen
Pfeil 2.5.5 Sichtbarkeit und Lebensdauer
Pfeil 2.5.6 Initialisierung von Variablen
Pfeil 2.5.7 Datentypkonvertierung
Pfeil 2.5.8 Funktionen
Pfeil 2.5.9 Schlüsselwörter
Pfeil 2.5.10 Zusammenfassung
Pfeil 2.6 Ein- und Ausgabemethoden der Klasse »Console«
Pfeil 2.6.1 Ausgabe mit Write und WriteLine
Pfeil 2.6.2 Einlesen mit Read und ReadLine
Pfeil 2.7 Operatoren
Pfeil 2.7.1 Arithmetische Operatoren
Pfeil 2.7.2 Relationale Operatoren
Pfeil 2.7.3 Logische Operatoren
Pfeil 2.7.4 Bitweise Operatoren
Pfeil 2.7.5 Verkettungsoperator
Pfeil 2.7.6 Zuweisungsoperatoren
Pfeil 2.7.7 Operatorprioritäten
Pfeil 2.7.8 Zusammenfassung
Pfeil 2.8 Fehlerbehandlung
Pfeil 2.8.1 Ohne Fehlerbehandlung
Pfeil 2.8.2 Funktionsweise von Try/Catch/Finally
Pfeil 2.8.3 Try/Catch
Pfeil 2.8.4 Try/Catch/Finally
Pfeil 2.8.5 Try/Finally
Pfeil 2.8.6 Rethrow
Pfeil 2.8.7 Spezifische Ausnahmen und mehrere Catch-Zweige
Pfeil 2.8.8 Unstrukturierte Fehlerbehandlung
Pfeil 2.9 Kontrollstrukturen
Pfeil 2.9.1 Die If-Anweisung
Pfeil 2.9.2 Select-Case-Anweisung
Pfeil 2.9.3 Gültigkeitsbereich einer Variablendeklaration
Pfeil 2.9.4 Entscheidungsfunktionen
Pfeil 2.9.5 If-Operator
Pfeil 2.9.6 Bedingte Kompilierung
Pfeil 2.9.7 Zusammenfassung
Pfeil 2.10 Programmschleifen
Pfeil 2.10.1 Do und While
Pfeil 2.10.2 For
Pfeil 2.10.3 Gültigkeitsbereich einer Variablendeklaration
Pfeil 2.10.4 Exit und Continue
Pfeil 2.10.5 GoTo
Pfeil 2.10.6 Zusammenfassung
Pfeil 2.11 Datenfelder (Arrays)
Pfeil 2.11.1 Eindimensionale Arrays
Pfeil 2.11.2 Mehrdimensionale Arrays
Pfeil 2.11.3 Initialisierung
Pfeil 2.11.4 Arrayname und Kopien
Pfeil 2.11.5 Speicherbelegung und Redimensionierung
Pfeil 2.11.6 Jagged Arrays
Pfeil 2.11.7 Feldgröße
Pfeil 2.11.8 Zusammenfassung


Rheinwerk Computing - Zum Seitenanfang

2.5 Variablen und Datentypen Zur nächsten ÜberschriftZur vorigen Überschrift

Dateninformationen bilden die Grundlage der Datenverarbeitung und hauchen einem Programm Leben ein: Daten können anwendungsspezifisch sein, den Zustand von Objekten beschreiben, Informationen aus Datenbanken repräsentieren oder auch nur eine Netzwerkadresse. Daten bilden also gemeinhin die Basis der Gesamtfunktionalität einer Anwendung.

Praktisch jedes Programm benötigt Daten, um bestimmte Aufgaben zu erfüllen. Daten werden in Variablen vorgehalten. Dabei steht eine Variable für eine Adresse im Hauptspeicher des Rechners. Ausgehend von dieser Adresse wird eine bestimmte Anzahl von Bytes reserviert – entsprechend dem Typ des Werts. Das, was eine Variable repräsentiert, kann vielfältiger Art sein: eine einfache Zahl, eine große Fließkommazahl, ein einzelnes Zeichen, eine Zeichenkette, eine Datums- oder Zeitangabe, aber auch die Referenz auf die Startadresse eines Objekts.

Der Variablenname, auch Bezeichner genannt, dient dazu, die Speicheradresse im Programmcode mit einem Namen anzusprechen, der sich einfach merken lässt. Er ist also vom Wesen her nichts anderes als ein Synonym oder Platzhalter eines bestimmten Speicherortes. Der Speicherplatz wird von .NET automatisch verwaltet.


Rheinwerk Computing - Zum Seitenanfang

2.5.1 Explizite und implizite Variablen (Option Explicit) Zur nächsten ÜberschriftZur vorigen Überschrift

Im Gegensatz zu den meisten anderen Programmiersprachen hat man in Visual Basic die Wahl zwischen zwei verschiedenen Arten, Speicher für eine Variable zu reservieren:

  • implizit durch Zugriff auf eine Variable
  • explizit durch Deklaration einer Variablen

Schauen wir uns zuerst die implizite Art an. Da sie standardmäßig nicht erlaubt ist, muss diese Möglichkeit erst freigeschaltet werden, entweder in den Projekteigenschaften für alle Dateien des Projekts oder auf Dateiebene im Programmcode. Abbildung 2.31 zeigt die erste Variante.

Abbildung 2.31 Implizite Variablen erlauben

Die andere Alternative wird in der nächsten Anwendung gezeigt. Hier wird mit Option Explicit Off in der ersten Zeile der Zwang zur Variablendeklaration unterdrückt. In der Anwendung wird einer Variablen ein Wert zugewiesen, und es wird versucht, diesen Wert auszugeben. Da das Erfordernis abgeschaltet ist, Variablen zu deklarieren, kann der Variablen ohne vorherige Deklaration etwas zugewiesen werden. Jedoch hat sich ein Tippfehler eingeschlichen: Die beiden letzten Buchstaben sind bei der Ausgabe vertauscht. Wenn Sie, wie hier dargestellt, mit Namensräumen arbeiten, kann es erforderlich sein, den Einstiegspunkt festzulegen (siehe Abbildung 2.18).


' ...\Sprachsyntax\ImpliziteVariablen\Implizit.vb

Option Explicit Off 
Namespace Sprachsyntax 
   Module Module1 
      Sub Main() 
         Variable = 1 
         Console.WriteLine("Variable = {0}",Variabel) 
         Console.ReadLine() 
      End Sub 
   End Module 
End Namespace

Dass sich beide Bezeichner unterscheiden, interessiert den Compiler nicht im Geringsten. Er nimmt keine Notiz davon, denn die explizite Variablendeklaration ist zugunsten der impliziten deaktiviert. Was macht der Compiler nun? Ganz einfach, er interpretiert den falsch geschriebenen Variablennamen als zweite Variable, deren Inhalt dann an der Konsole entsprechend ausgegeben wird (siehe Abbildung 2.32) – er ist leer!

Abbildung 2.32 Implizite Variable

Mit Option Explicit On meldet der Compiler einen Fehler (siehe Abbildung 2.33).

Abbildung 2.33 Implizite Variablen mit »Option Explicit On«

Die Korrektur besteht darin, die Variable mit dem Schlüsselwort Dim zu deklarieren und den Tippfehler zu korrigieren.

Option Explicit On 
Namespace Sprachsyntax 
   Module Module1 
      Sub Main() 
         Dim Variable = 1 
         Console.WriteLine("Variable = {0}",Variable) 
         Console.ReadLine() 
      End Sub 
   End Module 
End Namespace

Rheinwerk Computing - Zum Seitenanfang

2.5.2 Typisierte und untypisierte Variablen (Option Strict) Zur nächsten ÜberschriftZur vorigen Überschrift

Die nächste Stufe zu einer sauberen Variablendeklaration wäre es, die Compileroption Strict auf On zu setzen, um eine explizite Typangabe für jede Variable zu erzwingen. Dies ist nicht der Standard in Visual Basic 2008, aber extrem zu empfehlen. Das nächste Listing für das Projekt UntypisierteVariablen verwendet dieselbe Variable für eine ganze Zahl und für eine Zeichenkette.


' ...\Sprachsyntax\UntypisierteVariablen\Untypisiert.vb

Option Strict Off 
Namespace Sprachsyntax 
   Module Module1 
      Sub Main() 
         Dim Variable = 1 
         Variable = "1.78" 
         Console.WriteLine("Variable = {0}",Variable) 
         Console.ReadLine() 
      End Sub 
   End Module 
End Namespace

Die Ausgabe in Abbildung 2.34 zeigt, dass durch die erste Zuweisung der Typ der Variablen implizit festgelegt wurde und spätere Zuweisungen einen Wert implizit in diesen Typ konvertieren, also in eine ganze Zahl. Wir können also mit untypisierten Variablen nur vermeiden, selbst explizit zu konvertieren. Dass eine deklarierte Variable einen fixierten Typ hat, ist nicht zu vermeiden.

Abbildung 2.34 Untypisierte Variable

Mit Option Strict On meldet der Compiler einen Fehler. Der Korrekturvorschlag (siehe Abbildung 2.35) zeigt die bisher vorgenommene automatische Konvertierung mit CInt. Er erscheint, wenn man auf den Pfeil klickt, der angezeigt wird, wenn man mit dem Mauszeiger eine Weile über dem fehlerhaften Wert verharrt.

Abbildung 2.35 Fehler bei einer untypisierten Variablen

Durch eine explizite Typangabe lassen wir uns vom Compiler bei der Arbeit helfen. Er findet automatisch Inkonsistenzen. Da wir weiterhin explizite Konvertierungen vornehmen können, ist die erzwungene Typisierung keine Einschränkung der Funktionalität. Das folgende Listing zeigt eine solche Konvertierung. Die Ausgabe ist identisch zum Programm mit untypisierten Variablen.

Option Strict On 
Namespace Sprachsyntax 
   Module Module1 
      Sub Main() 
         ' Deklaration der Variablen als ganze Zahl 
         Dim Variable As Integer = 1 
         Variable = CInt("1.78") 
         Console.WriteLine("Variable = {0}",Variable) 
         Console.ReadLine() 
      End Sub 
   End Module 
End Namespace

Hinweis
Im Gegensatz zu früheren Visual-Basic-Versionen kann der Compiler den Datentyp einer ohne Typangabe deklarierten Variablen aus der ersten Wertzuweisung ermitteln – es sei denn, der Mechanismus wurde mit Option Infer Off abgeschaltet. Eine explizite As-Klausel bei jeder Deklaration macht das Programm aber leichter lesbar und ist daher dringend zu empfehlen.



Rheinwerk Computing - Zum Seitenanfang

2.5.3 Variablendeklaration Zur nächsten ÜberschriftZur vorigen Überschrift

In den vorigen Abschnitten haben wir gesehen, wie problematisch Variablen sein können, deren Typ nicht explizit angegeben wird. Wir werden daher alle folgenden Beispiele im ganzen Buch immer mit der Compileroption

Option Strict On

übersetzen. Die damit erforderliche Variablendeklaration muss vor der ersten Wertzuweisung an die Variable erfolgen, gegebenenfalls in derselben Zeile, und setzt sich immer aus drei Informationen zusammen, eine vierte ist optional:

  • einem Modifikator, der die Lebensdauer sowie die Sichtbarkeit und somit den Zugriff auf die Variable beeinflusst
  • dem Variablennamen, auch Bezeichner genannt
  • dem Datentyp, den die Variable repräsentiert
  • einer Zuweisung des Startwerts

Die allgemeine Syntax zur Deklaration einer Variablen lautet damit wie folgt (optionale Teile stehen in eckigen Klammern):


<Modifikator> <Bezeichner> As <Datentyp> [= <Wert>]

Variablen zu deklarieren heißt, einem Bezeichner mit der As-Klausel einen bestimmten Datentyp zuzuordnen und die Art des Zugriffs festzulegen. Bisher haben wir nur Dim als Modifikator kennen gelernt. Eine Deklaration könnte beispielsweise folgendermaßen aussehen:

Dim intVar As Integer

Damit wird dem Compiler mitgeteilt, dass der Bezeichner intVar für ein Datum steht, das vom Typ einer Ganzzahl ist, genauer gesagt vom Typ Integer, die einen bestimmten Wertebereich abdecken kann. Mit

intVar = 1000

wird dieser Variablen die Zahl 1000 zugewiesen.

In einer Codezeile können durchaus mehrere Variablen deklariert werden. Außerdem kann eine Variable schon bei der Deklaration initialisiert werden, das heißt, ihr kann also ein spezifischer Startwert zugewiesen werden.

' x, y und z sind vom Typ Integer 
Public x, y, z As Integer

' x ist vom Typ Short, y vom Typ String 
Dim x As Short, y As String

' strText wird als String deklariert und sofort mit der 
' Zeichenfolge "Hallo Welt" initialisiert 
Dim strText As String = "Hallo Welt"

' die Variable iVar wird deklariert, und ihr wird das Datum 12 
' zugewiesen, dblGehalt ist vom Typ Double 
Dim iVar As Integer = 12, dblGehalt As Double

Hinweis
Für eine Variable, die einer Methode lokal zugeordnet ist, kann der Typ aus der Initialisierung vom Compiler automatisch ermittelt werden (es sei denn, Option Infer Off ist gesetzt). Zwecks besserer Lesbarkeit empfiehlt sich aber eine As-Klausel.


Variablenname

Der Variablenname (Bezeichner) kann nahezu beliebig festgelegt werden, unterliegt aber besonderen Reglementierungen:

  • Ein Bezeichner darf sich nur aus alphanumerischen Zeichen und dem Unterstrich zusammensetzen. Leerzeichen und andere Sonderzeichen wie beispielsweise #, §, $ usw. sind nicht zugelassen.
  • Ein Bezeichner muss mit einem Buchstaben oder dem Unterstrich anfangen.
  • Ein alleinstehender Unterstrich als Variablenname ist nicht zulässig.
  • Der Bezeichner muss eindeutig sein. Er darf nicht denselben Namen wie eine Prozedur, eine Klasse oder ein Objekt im gleichen »Codingabschnitt« haben (siehe Abschnitt 2.5.5, »Sichtbarkeit und Lebensdauer«).
  • Soll ein Bezeichner wie ein Schlüsselwort lauten, muss er in eckige Klammern gesetzt werden.

Für die letzte Regel soll direkt ein Beispiel angegeben werden. Wenn Sie beispielsweise – aus welchen Gründen auch immer – einer Variablen den Namen des von Visual Basic reservierten Schlüsselworts Public geben wollen, können Sie diesen Bezeichner in eckige Klammern setzen:

Dim [Public] As Integer 
[Public] = 10

Mit der Klammerung wird die Bedeutung des Schlüsselworts außer Kraft gesetzt. Ich vermeide, wenn möglich, die Verwendung von Schlüsselwörtern für eigene Variablen. Einige Beispiele sollen diese Regeln verdeutlichen:

' korrekte Variablendeklarationen 
Dim lngMyVar As Long 
Dim bResult_12 As Byte 
Dim intCarColor As Integer

' fehlerhafte Variablendeklarationen 
Dim 34M As Integer 
Dim strMessage Text As String 
Dim lngSalary%Tom as Integer

Visual Basic unterscheidet nicht zwischen der Groß- und Kleinschreibung wie viele andere Programmiersprachen. Dennoch wird der Groß-/Kleinschreibung im Texteditor Rechnung getragen. Ausschlaggebend ist die Angabe in der Deklaration. Sie können sich dies sogar zunutze machen, wenn Sie bei der Deklaration einer Variablen dem Bezeichner einen oder mehrere Großbuchstaben mit auf den Lebensweg geben, zum Beispiel:

Dim meineVariable As Integer

Wenn Sie im Laufe des weiteren Programmierens der Variablen einen Wert zuweisen und den Namen dabei nur in Kleinbuchstaben schreiben, beispielsweise

meinevariable = 10

dann wird die Entwicklungsumgebung beim Zeilenumbruch automatisch die deklarierte Schreibweise erkennen und entsprechend in

meineVariable = 10

korrigieren. Mit dieser Technik können Sie sofort erkennen, ob Sie den Namen der Variablen richtig geschrieben haben, und mögliche lästige Fehlermeldungen beim späteren Testen vermeiden.

Noch ein Hinweis zur Namensvergabe: Wählen Sie grundsätzlich beschreibende Namen, damit Ihr Code später besser lesbar wird. Einfache Bezeichner wie x oder y usw. sind wenig aussagefähig. Besser ist eine Wahl wie intFarbe, dblGehalt, strVorname usw. Nur den Zählervariablen von Schleifen werden meistens Kurznamen gegeben.

Die Bezeichner von Variablen sollten mit einem Kleinbuchstaben anfangen – im Gegensatz zu den Namen von (öffentlichen) Prozeduren und Objekten. Sie können ein Präfix benutzen, aus dem auch innerhalb einer Anweisung hervorgeht, welcher Datentyp von der Variablen beschrieben wird:

Dim intVar As Integer 
Dim strText As String

Die Verwendung eines Präfixes zusammen mit einem sinnvollen, beschreibenden Bezeichner macht den Programmcode lesbarer. Wenn Ihr Programm durch Einzüge sauber strukturiert und mit ausreichenden Kommentaren versehen ist, wird auch eine dritte Person kaum Schwierigkeiten haben, in angemessener Zeit die Programmlogik zu interpretieren.

Tabelle 2.2 enthält als Vorschlag Präfixe für Datentypen.


Tabelle 2.2 Präfixvorschläge für Datentypen

Datentyp Präfix Datentyp Präfix Datentyp Präfix

Byte

bt

Single

sng

Char

chr

Short

sh

Double

dbl

String

str

Integer

int

Decimal

dec

Date

dt

Long

lng

Boolean

bln

Object

obj


Datentyp

Mit dem Datentyp wird festgelegt, wie groß der Wertebereich der zu speichernden Dateninformation sein soll, wie viel Speicherplatz dafür reserviert werden muss und damit auch, wie dieser Speicherplatz zur Laufzeit interpretiert wird. Weiter unten in Abschnitt 2.5.4, »Einfache Datentypen«, werden alle zur Verfügung stehenden Datentypen erläutert.

Die Datentypen lassen sich in zwei Gruppen einteilen:

  • native Typen, wie beispielsweise Integer oder Decimal
  • Objekttypen

In diesem Kapitel werden Sie nur die nativen Datentypen kennenlernen, mit den anderen werden wir uns ab dem nächsten Kapitel befassen.

Eine weitere Gruppierung der Datentypen erfolgt danach, wie sie im Speicher behandelt werden. Man unterscheidet:

  • Wertetypen
  • Referenztypen

Für Wertetypen wird an der Stelle Speicher reserviert, an der sie deklariert werden. Eine Variable in einer Prozedur erhält also einen Speicherbereich innerhalb der Prozedur. Demgegenüber wird für Referenztypen einmal global Speicher reserviert, und eine Variable dieses Typs enthält nur eine Adresse auf den Speicher.

Besonders wichtig sind die Referenztypen Object und String. Während Object die Basis aller Referenztypen ist, repräsentiert String Zeichenketten. Obwohl die Begriffe Objekt, Referenztyp und Wertetyp in den folgenden Abschnitten noch öfter fallen werden, wird die genaue Erklärung erst im nächsten Kapitel erfolgen, wenn wir uns intensiv mit Klassen und Objekten beschäftigen.

Modifikatoren

Die Modifikatoren lassen sich in drei Gruppen einteilen:

  • Lebensdauer: Dim bzw. Const und Static
  • Gültigkeitsbereich: Dim und Shared bzw. Const
  • Sichtbarkeit: Public, Private, Protected und Friend

Abschnitt 2.5.5, »Sichtbarkeit und Lebensdauer«, erläutert das erste Konzept (Lebensdauer) und geht kurz auf die Sichtbarkeit ein. Diese und das Konzept der Gültigkeitsbereiche werden ausführlicher im Rahmen der Objektorientierung ab Kapitel 3, »Klassendesign«, beschrieben. Die Deklaration erlaubt in der Regel nur einen Modifikator; Ausnahmen sind zum Beispiel: Protected Friend und Dim Shared.


Rheinwerk Computing - Zum Seitenanfang

2.5.4 Einfache Datentypen Zur nächsten ÜberschriftZur vorigen Überschrift

Die .NET-Laufzeitumgebung verfolgt das Konzept der Objektorientierung nach strengen Maßstäben. Selbst einfache Datentypen werden als Objekte angesehen, die Methoden bereitstellen, um mit einer Variablen bestimmte Aktionen auszuführen. In Tabelle 2.3 sind alle nativen Datentypen sowie Object und String zusammenfassend aufgeführt.


Tabelle 2.3 Elementare Datentypen

.NET-Typ VB-Alias Typ-Postfix Literal-Postfix CLS- konform Wertebereich

Byte

Byte

ja

0 bis 255

SByte

SByte

nein

-128 ... 127

Int16

Short

S

ja

-215 … 215 – 1

UInt16

UShort

US

nein

0 … 65.535

Int32

Integer

%

I

ja

-231 … 231 – 1

UInt32

UInteger

UI

nein

0 ... 232 – 1

Int64

Long

&

L

ja

-263 … 263 – 1

UInt64

ULong

UL

nein

0 … 264 – 1

Single

Single

!

F

ja

1,4*10-45 bis 3,4*1038 (23 Bit Ziffern)

Double

Double

#

R

ja

5,0*10-324 bis 1,7*10308 (52 Bit Ziffern)

Decimal

Decimal

@

D

ja

+/-79E27 (-296 – 1 bis 296 – 1 mit Skalierungsfaktor 10-28 bis 100, d. h. 28 bis 0 Nachkommastellen)

Char

Char

C

ja

Unicode-Zeichen zwischen 0 und 65.535

Boolean

Boolean

ja

True oder False

DateTime

Date

# (auch Präfix)

1/1/1 12:0:0 – 31/12/9999 23:59:59

Object

Object

ja

Eine Variable vom Typ Object kann jeden anderen Datentyp enthalten, ist also universell.

String

String

$

ja

ca. 231 Unicode-Zeichen


In der ersten Spalte ist der Typbezeichner in der .NET-Klassenbibliothek angeführt, in der zweiten Spalte das Visual-Basic-Pseudonym, das bei der Deklaration einer Variablen dieses Typs angegeben werden kann. Welche der beiden Typen man verwendet, spielt keine Rolle. Damit sind die beiden folgenden Deklarationen der Variablen intVar absolut gleichwertig:

Dim intVar As Integer 
Dim intVar As Int32

Statt den Typ in einer As-Klausel anzugeben, kann für einige Typen auch ein Zeichen der dritten Spalte angehängt werden. Die beiden nächsten Zeilen sind daher identisch:

Dim sngVar As Single 
Dim sngVar!

.NET verfolgt nicht nur ein plattformunabhängiges Konzept, sondern auch ein sprachunabhängiges. Soll der Visual-Basic-Code mit anderen .NET-Sprachen zusammenarbeiten, muss darauf geachtet werden, dass alle Datentypen der öffentlichen Schnittstelle in diesen Sprachen bekannt sind. Der private Teil einer Anwendung verursacht keine Probleme. Alle .NET-Sprachen müssen mindestens die Typen der Common Language Specification (CLS) implementieren. Wenn ein in der fünften Spalte als nichtkonform gekennzeichneter Datentyp in der öffentlichen Schnittstelle verwendet wird, ist die Zusammenarbeit mit anderen Sprachen wahrscheinlich unmöglich. Solche Typen haben in der Schnittstelle nichts zu suchen.

Das bedeutet: Wenn eine .NET-Anwendung CLS-konform codiert wird, ist eine Garantie damit verbunden, dass jeder andere .NET-Code Zugriff auf die (öffentlichen) Komponenten der CLS-konformen Anwendung hat – unabhängig davon, in welcher Sprache sie codiert ist.

Ganzzahlige Datentypen

Visual Basic stellt acht ganzzahlige Datentypen zur Verfügung, von denen vier vorzeichenbehaftet sind. Die uns interessierenden CLS-konformen Datentypen sind:

  • Byte
  • Int16
  • Int32
  • Int64

Byte ist besonders wichtig, wenn auf binäre Daten zugegriffen wird, und speichert nur positive Zahlen und die Null. Die anderen drei Typen decken den positiven und negativen Wertebereich nahezu identisch ab.

Literale hexadezimale Zahlen (Basis = 16) erhalten das Präfix &H, oktale Zahlen (Basis = 8) das Präfix &O, und dezimale Zahlen schreibt man ohne Präfix. Die folgenden Zahlen beschreiben beide dieselbe Dezimalzahl, nämlich 225, zuerst in hexadezimaler, danach in oktaler Schreibweise:

Dim intHex As Integer = &HE1 
Dim intOct As Integer = &O341

Um bei der Division zweier Zahlen eine ganze Zahl zu erhalten, muss der richtige Operator verwendet werden (siehe auch Abschnitt 2.7.1, »Arithmetische Operatoren«).

Dim fliess As Integer = 2/3  'Compilerfehler!! 
Dim ganz   As Integer = 2\3

Fließkommazahlen

Single, Double und Decimal sind die drei Typen, mit denen unter Visual Basic Fließkommazahlen dargestellt werden können. Sie beschreiben nicht nur unterschiedliche Wertebereiche, sondern auch – was noch viel wichtiger ist – unterschiedliche Genauigkeiten. Ein Single reserviert 23 Bit für Ziffern, ein Double 52 und ein Decimal 96. Also sind 223 -1=8.388.607, 252 -1=4.503.599.627.370.495 und 296 -1=79.228.162.514.264.337.593.543.950.336 die größten speicherbaren Ziffernfolgen mit 7, 16 und 29 Stellen und liegen zwischen 0 und 1. Die Vorfaktoren 2-2^7+2 1.2*10-38 bis 22^7 3.4*1038 , 2-2^11+2 2.2*10-308 bis 22^11 1.8*10308 und 10-28 bis 1 legen die Größe der Zahlen fest.

Die kleinsten positiven Zahlen werden dadurch erreicht, dass die Bits der Ziffernfolgen die Größe der Zahl mitbestimmen. Für ein Single zum Beispiel existiert zwischen 2-126-23 und 2-125-23 keine Zahl, und erst ab 2-126 aufwärts ist die Darstellung wieder kontinuierlich.

Das folgende Codefragment demonstriert die Genauigkeit, die mit einem Single erreicht werden kann:


' ...\Sprachsyntax\Zahlen\Fliesskomma.vb

Namespace Sprachsyntax 
  Module Fliesskomma 
    ... 
    Sub Genauigkeit() 
      Dim x As Single = 0.8388608 
      Dim y As Single = 0.83886081 
      Console.WriteLine("x=y {0}", x = y) ' True 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Es werden zunächst zwei Variablen vom Typ Single deklariert, und danach wird beiden ein Wert zugewiesen, der sich nur an der letzten Nachkommastelle unterscheidet. In der Ausgabe werden beide Zahlen verglichen.

Ein Lauf des Programms behauptet, beide Werte wären gleich. Diese offensichtliche Falschaussage ist darauf zurückzuführen, dass ein Single-Typ nicht in der Lage ist, alle hier angegebenen Nachkommastellen exakt zu interpretieren – er ist schlichtweg überfordert. Für Berechnungen, die eine höhere Genauigkeit erfordern, ist dieser Datentyp daher weniger gut geeignet.

Wir können dieser Stolperfalle leicht entgehen, indem wir die Zahlenliterale kennzeichnen. Ohne Kennzeichnung wird

  • ein ganzzahliges Literal als Integer interpretiert und
  • ein Literal vom Typ einer Dezimalzahl als Double.

Setzen wir ein »F« hinter die Zahl, kennzeichnen wir sie als Single. Sobald wir die Zeile verlassen, wird

0.83886081F

automatisch in

0.8388608F

eingekürzt, da die letzte 1 vom Datentyp Single sowieso nicht erfasst wird. Wir sehen also schon bei der Eingabe, ob alles wie gewünscht läuft. In Abschnitt 2.5.7, »Datentypkonvertierung«, gehen wir näher auf die Thematik ein.

Bei einem Double tritt das gleiche Problem erst bei einer größeren Stellenzahl auf. Dieser Datentyp bietet sich also für genauere Rechnungen an. Der Vorteil eines größeren Wertebereichs ist meistens nur zweitrangig, da ein Single mit 1038 bereits extrem große Werte speichern kann.

Die Genauigkeit, die hier betrachtet wird, bezieht sich auf die Anzahl der Stellen einer Zahl, unabhängig davon, wo das Komma steht. Wenn wir den vorigen Test mit einem um 2 Positionen nach rechts verschobenen Komma wiederholen, ergibt sich dieselbe Ausgabe.


' ...\Sprachsyntax\Zahlen\Fliesskomma.vb

Namespace Sprachsyntax 
  Module Fliesskomma 
    ... 
    Sub Komma() 
      Dim x As Single = 83.88608 
      Dim y As Single = 83.886081 
      Console.WriteLine("x=y {0}", x = y) ' True 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Reicht die Stellenzahl von Double nicht, kann man noch auf Decimal zurückgreifen. Der Typ hat 28 signifikante Stellen, die sich alle direkt vor oder hinter dem Komma befinden (ein Skalierungsfaktor 10x ist unnötig). Da wir hier immer die Compileroption Strict auf On setzen, müssen wir ein Decimal-Zahlenliteral mit »D« kennzeichnen, da eine ungekennzeichnete Fließkommazahl als Double angesehen wird und nicht alle Double in Decimal hineinpassen, zum Beispiel:

decA = 0.123D

Decimal wird meist im Finanzsektor verwendet, da man mit diesem Datentyp riesige Beträge handhaben kann, ohne auch nur einen Cent zu verlieren. Da Rechnungen mit Decimal nicht direkt von der Hardware durchgeführt werden, sondern in eine spezielle Ganzzahlarithmetik übersetzt werden, sind sie deutlich langsamer als solche mit Double.


Hinweis
Beachten Sie, dass der ganzzahlige Anteil einer Fließkommazahl grundsätzlich immer durch einen Punkt vom Nachkommaanteil getrennt wird. Diese Regel gilt auch dann, wenn Sie in der spezifischen Ländereinstellung auf Systemebene ein Komma als Trennzeichen eingestellt haben. Lediglich auf Zeichenketten mit Anführungszeichen, wie zum Beispiel »2,58«, haben diese Einstellungen Einfluss, und zwar sowohl beim Einlesen als auch beim Rausschreiben.


Zeichenbasierte Datentypen

Intern wird jedes Zeichen als eine Zahl dargestellt. Die Übersetzungstabelle zwischen Zeichen und Zahlen wird Zeichensatz genannt. Zu DOS-Zeiten war der ASCII-Zeichensatz üblich, in Windows wird der ANSI-Zeichensatz eingesetzt. Beide können maximal 256 verschiedene Zeichen gleichzeitig verwalten und beanspruchen 1 Byte Speicherplatz. Im Rahmen der Internationalisierung wurde es nötig, mehr Zeichen zu erlauben. .NET benutzt daher für Zeichen den Typ Char, der 2 Byte belegt und in Unicode kodiert ist. Damit sind 65.536 verschiedene Zeichen direkt nutzbar. Wenn nötig, erlauben sogenannte Surrogate, drei oder vier Char als ein Zeichen zu interpretieren. Sie sollten sich daher bei der Verarbeitung nichtwestlicher Sprachen keinesfalls darauf verlassen, dass ein Zeichen immer durch einen einzigen Char repräsentiert wird. Zwecks Kompatibilität sind die ersten 128 Zeichen aller Zeichensätze identisch. Sie enthalten alle Zeichen, die für Visual Basic benötigt werden.

Da hier immer Option Strict eingeschaltet ist (On), muss die Zuweisung eines Zeichens an die Char-Variable umgewandelt werden. Entweder wird das Typkennzeichen c angehängt oder die Konvertierungsfunktion CChar benutzt (nur das erste Zeichen wird konvertiert). Eine Umwandlung aus dem Zeichencode ist auch möglich:


' ...\Sprachsyntax\Zeichen\Zeichen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Buchstaben 
    ... 
    Sub Initialisierung() 
      Dim a As Char = "A"c 
      Dim b As Char = CChar("AB") 
      Dim c As Char = ChrW(65) 
      Console.WriteLine("abc {0}{1}{2}",a,b,c) ' AAA 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Um eine Zeichenkette, die sich aus keinem oder bis zu maximal ungefähr 231 Einzelzeichen zusammensetzt, zu speichern oder zu bearbeiten, deklarieren Sie eine Variable vom Datentyp String. Die Einzelzeichen werden dabei wie ein Char-Typ als Unicode-Zeichen der Größe 16 Bit behandelt. Zeichenketten werden grundsätzlich in Anführungsstriche gesetzt (normale doppelte oder die Unicode-Zeichen 0x201C und 0x201D). Ein Zugriff auf einzelne Buchstaben ist über einen Index in runden Klammern möglich. Der erste Buchstabe hat die Nummer null.


' ...\Sprachsyntax\Zeichen\Zeichen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Buchstaben 
    ... 
    Sub Zeichenketten() 
      Dim a As String = "Text" 
      Dim b As Char = a(1) 
      Console.WriteLine("a-b {0}-{1}", a, b) ' Text-e 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Hinweis
Anders als in vielen anderen Programmiersprachen wird ein Anführungszeichen innerhalb einer Zeichenkette nicht durch \" dargestellt, sondern durch ein verdoppeltes Zeichen: "".


Logischer Datentyp

Variablen vom Typ Boolean können nur die Zustände True oder False beschreiben.

In vielen Programmiersprachen wird False numerisch mit 0 beschrieben, True durch alle Werte, die von 0 abweichen. .NET ist hier sehr viel strenger. Hier ist True nicht 1 und auch nicht 67, sondern ganz schlicht True. Aus diesem Grund ist auch die folgende Anweisung falsch, die so in anderen Programmiersprachen durchaus möglich ist:

Dim myBool As Boolean = 2 'Compilerfehler!!

Das beeinflusst Bedingungsprüfungen, wie Sie später noch sehen werden. Eine explizite Konvertierung zu ganzzahligen Typen ist möglich (False entspricht 0, True setzt alle Bits, eine Zahl ungleich 0 ergibt True).

Datumsangaben

Der Datentyp Date speichert Datumsangaben. Datumsliterale werden in Lattenzäune eingeschlossen. Jahresangaben müssen 4 Stellen haben, gegebenenfalls mit führenden Nullen. Der Monat wird vor dem Tag angegeben. Ohne AM und PM hat ein Tag 24 Stunden. Ein fehlender Tag wird als 1/1/1 angenommen, eine fehlende Zeit mit Mitternacht (12AM). Fehlende Minuten oder Sekunden werden als 0 angenommen.

Dim d As Date 
d = # 12/13/2007 4:22:58PM # ' vollständiges Datum 
d = # 12/13/2007 #           ' wird ergänzt durch 12:00:00AM 
d = # 16:22:58 #             ' wird ergänzt durch 1/1/1

Native Datentypen als Objekte

Egal, was wir in .NET betrachten, immer ist es ein Objekt. Damit dies möglich ist, lassen sich alle Datentypen auf einen Typ namens Object zurückführen. Da er für alles stehen kann, darf man auch darin speichern, was man will. Im folgenden Codefragment ist es einmal eine Zahl, dann ein Text:

Dim x As Object 
x = 1.23 
x = x + 1 
x = "irgendwas"

Wie ist das mit einem festen Typsystem in .NET zu vereinbaren, das für gleiche Datentypen auch immer gleichen Speicherplatz reserviert? In x werden nicht direkt Daten gespeichert, sondern ein Zeiger auf diese Daten. Dieser 4 Byte große Zeiger ist natürlich unabhängig davon, worauf er gerade zeigt. Interessant wird dieses Konzept besonders dadurch, dass zur Laufzeit des Programms .NET dafür sorgt, dass sich das Objekt »richtig« verhält. Im obigen Beispiel wird zu x eine Zahl addiert, ohne dass wir uns speziell Gedanken machen müssen, welchen Typ x gerade hat. Dieses Konzept wird uns in ausgebauter Form noch bei der Definition von Klassen begegnen, und zwar unter dem Begriff Polymorphie.

Das funktioniert selbst für die bisher betrachteten einfachen Datentypen. Selbst so etwas wie eine Zahl wird, bei Bedarf, automatisch in ein Objekt umgewandelt. Diese Umwandlung erfolgt komplett automatisch und wird Boxing genannt.

Eine einfache ganze Zahl vom Typ Integer soll so etwas Komplexes wie ein Objekt sein? Wenn Sie, wie in Abbildung 2.36, eine entsprechende Variable vereinbaren und in der nächsten Zeile nach dem Namen einen Punkt tippen, klappt eine Liste mit Methoden und Eigenschaften des Objekts Integer auf, auf die man direkt Zugriff hat. Sollte die Liste nicht auto-matisch erscheinen, drücken Sie Taste Strg + Taste Leertaste . Diese kontextsensitive Hilfe wird IntelliSense genannt.

Abbildung 2.36 IntelliSense-Liste einer Integervariablen


Hinweis
Wenn Sie eine Auswahl in der IntelliSense-Liste mit Taste Strg + Taste Enter oder Taste Tabulator bestätigen, wird kein Zeilenvorschub an die Auswahl angehängt.


Sie können sich dieser Funktionalitäten bedienen. Wenn Sie beispielsweise wissen wollen, wo die Ober- bzw. Untergrenze des Integers liegt, könnten Sie dies mit dem folgenden Codefragment abfragen:

Sub Main() 
  Dim intV As Integer 
  Console.WriteLine("Integer(min) = {0}", intV.MinValue) 
  Console.WriteLine("Integer(max) = {0}", intV.MaxValue) 
  Console.ReadLine() 
End Sub

Beachten Sie bitte hierbei, dass Sie in syntaktisch gleicher Weise, wie Sie die Methode WriteLine der Klasse Console mittels Punktnotation aufrufen, auch auf die Ober- und Untergrenze des Typs Integer zugreifen: Zuerst wird der Objektname angegeben, der in unserem Beispiel intV lautet, danach folgt, durch einen Punkt abgetrennt, die Methode bzw. Eigenschaft (in unserem Fall handelt es sich um eine Eigenschaft). An der Konsole wird danach Folgendes angezeigt:

Integer(min) = –2147483648 
Integer(max) = 2147483647

Rheinwerk Computing - Zum Seitenanfang

2.5.5 Sichtbarkeit und Lebensdauer Zur nächsten ÜberschriftZur vorigen Überschrift

Grundsätzlich können Variablen

  • innerhalb einer Prozedur eines Moduls oder
  • auf der Ebene des Moduls

deklariert werden. Im folgenden Codefragment entspricht procVar dem ersten und modVar dem zweiten Fall.

Module Variablenart 
  Dim modVar As Integer 
  Sub proc() 
    Dim procVar As Integer 
  End Sub 
End Module

Da Prozedurvariablen nur innerhalb derselben Prozedur verwendet werden können, werden sie auch lokale Variablen genannt. Im Gegensatz dazu werden Variablen außerhalb von Prozeduren, aber innerhalb eines Moduls globale Variablen genannt. (Außerhalb jeglichen Moduls können keine Variablen deklariert oder verwendet werden.)

Sichtbarkeit

Bezüglich des Zugriffs auf eine Variable können wir zwei Fälle unterscheiden:

  • Sie ist erreichbar.
  • Sie ist sichtbar.

Der erste Fall liegt vor, wenn es syntaktisch möglich ist, eine Variable anzusprechen. Zum Beispiel ist es nicht möglich, von außerhalb auf eine Prozedurvariable zugreifen. Demgegenüber ist der zweite Fall bei Zugriffen auf Modulvariablen über Modulgrenzen hinweg interessant. Hierbei gibt es vier Ebenen der Beschränkung, von denen die vorletzte erst verständlich werden wird, nachdem wir das Konzept der Klassen besprochen haben.

  • Public: Es liegen keine Beschränkungen vor.
  • Friend: Die Variable ist nur innerhalb der Anwendung sichtbar.
  • Protected: Die Variable ist nur für »Kinder« eines Moduls sichtbar.
  • Private: Die Variable ist nur von innerhalb desselben Moduls sichtbar (Dim hat denselben Effekt).

Hinweis
Module (und andere Typen), die sich direkt unterhalb eines Namensraums befinden, dürfen nur Public oder Friend sein, wobei keine Angabe gleichbedeutend mit Friend ist. Die Sichtbarkeit des Programmeinstiegspunkts (meist Main) ist bedeutungslos.


Wenn zum Beispiel eine Modulvariable als Private gekennzeichnet ist, kann nicht von einem anderen Modul auf sie zugegriffen werden, da sie von dort aus nicht sichtbar ist. Innerhalb desselben Moduls ist sie sichtbar und der Zugriff ist möglich.

Es gilt als guter Programmierstil, einer Variablen nur die Sichtbarkeit zuzugestehen, die sie im Code auch tatsächlich benötigt. Dahinter verbirgt sich die Absicht, eine nicht zulässige, unkontrollierte Manipulation auszuschließen. Außerdem müssen Sie auch bedenken, dass globale Variablen dauerhaft Speicherressourcen verbrauchen, was trotz der guten Ausstattung moderner Rechner in großen Anwendungen durchaus ein gewichtiges Argument sein kann.

Das folgende Listing zeigt die verschiedenen Fälle, wobei Unmögliches und Unerlaubtes auskommentiert ist.


' ...\Sprachsyntax\Sichtbarkeit\Sichtbarkeit.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Sichtbarkeit 
    Public pub As Integer = 1 
    Friend frn As Integer = 2 
    Private priv As Integer = 3 
    Sub fun() 
      Dim proc As Integer = 5 
    End Sub

    Sub Main() 
      Dim proc As Integer = 4 
      Console.WriteLine("öffentlich {0}", pub) 
      Console.WriteLine("Freund {0}", frn) 
      Console.WriteLine("privat {0}", priv) 
      Console.WriteLine("Prozedur {0}", proc) 
      ' Console.WriteLine("andere Prozedur {0}", fun.proc) 
      Console.WriteLine("öffentlich Fremd {0}", Fremd.pub) 
      Console.WriteLine("Freund Fremd {0}", Fremd.frn) 
      ' Console.WriteLine("privat Fremd {0}", Fremd.priv) 
      Console.ReadLine() 
    End Sub 
  End Module

  Module Fremd 
    Public pub As Integer = 5 
    Friend frn As Integer = 6 
    Private priv As Integer = 7 
  End Module 
End Namespace

Bitte beachten Sie, dass die Kennzeichnung als Public, Friend oder Private nur auf Modulebene möglich ist. Prozedurvariablen sind effektiv noch privater als Private.

Ein weiterer Aspekt der Sichtbarkeit betrifft nur Module und nicht andere Datentypen, wie zum Beispiel Klassen. Bei Modulen wird eine Definition außer im Modul selbst noch im umgebenden Namensraum zugänglich gemacht, sodass man sie auch ohne Qualifizierung in anderen Modulen (oder Klassen) verwenden kann. Der Wert dieses Konzepts scheint mir fragwürdig, da man so nicht direkt sehen kann, wo etwas herkommt, das man benutzt. Das nächste Codefragment zeigt, dass die Methode Gefunden() mit oder ohne Qualifizierung verwendet werden kann.


' ...\Sprachsyntax\Qualifizierung\Qualifizierung.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Anderswo 
    Public Wert As Integer 
  End Module

  Module Qualifizierung 
    Sub Main() 
      Console.WriteLine(Anderswo.Wert) 
      Console.WriteLine(Wert) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Der Effekt ist der gleiche, der sich durch das folgende Codefragment ergeben würde (das man so selbst nicht schreiben darf):

Namespace Sprachsyntax 
  Public Wert As Integer 
  ... 
End Namespace

Hinweis
Elemente, die Module von Object übernimmt, müssen qualifiziert werden (Equals und ReferenceEquals).


Lebensdauer

Variablen können maximal so lange erhalten bleiben, wie

  • ein Prozeduraufruf dauert oder
  • das sie umgebende Modul existiert.

Nach ihrer Lebensdauer werden sie zerstört, und der Speicherplatz wird automatisch freigegeben.

Alle mit Dim gekennzeichneten Prozedurvariablen gehören zur ersten Gruppe; die Variablen auf Modulebene und alle mit Static gekennzeichneten Prozedurvariablen gehören zur zweiten. Die letzte Art Variable erinnert sich an den Wert, den sie beim letzten Prozeduraufruf hatte. Schauen wir uns dazu die folgende Anwendung an. Sie enthält eine Modulvariable glob, eine normale Prozedurvariable dyn und eine speziell mit Static gekennzeichnete Variable stat. In der Einstiegsprozedur Main() wird die Prozedur Zugriff() dreimal aufgerufen. In ihr werden alle drei Variablen um eins erhöht und ausgegeben.


' ...\Sprachsyntax\Lebensdauer\Lebensdauer.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Lebensdauer

    Dim glob As Integer

    Sub Zugriff() 
      Dim dyn As Integer 
      Static stat As Integer 
      dyn = dyn + 1 
      stat = stat + 1 : glob = glob + 1 
      Console.Write("dyn {0} ", dyn) 
      Console.WriteLine("stat/glob {0}/{1}", stat, glob) 
    End Sub

    Sub Main() 
      Zugriff() : Zugriff() : Zugriff() 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe des Programms sieht so aus:

dyn 1 stat/glob 1/1 
dyn 1 stat/glob 2/2 
dyn 1 stat/glob 3/3

Sie zeigt, dass nur die normale Prozedurvariable dyn bei jedem Aufruf der Prozedur neu initialisiert wird. Die beiden anderen behalten ihren Wert.

Es gibt Situationen, da ist es nicht wünschenswert, dass der Inhalt einer Variablen verloren geht. Angenommen, Sie möchten feststellen, wie oft eine Prozedur während der Laufzeit des Programms ausgeführt wird. Ob Sie dann eine mit Static gekennzeichnete Prozedurvariable verwenden oder eine private Modulvariable, ist oft Geschmackssache.


Hinweis
Static-Variablen haben die gleiche Bindung wie die Methode (Objekt oder Klasse).


Die Kennzeichnung mit Const verhindert jede Änderung einer Variablen nach deren Initialisierung. Vom Effekt her ist dies eine schreibgeschützte Static-Variable.

Const stat As Integer = 2

Hinweis
Der Wert der Konstanten muss zur Compilezeit bekannt sein. Für Laufzeitkonstanten auf Modulebene wird ReadOnly verwendet.


Überdeckte Variablen

Variablen müssen eindeutig benannt sein. Entweder müssen unterschiedliche Namen gewählt werden, oder einer der folgenden Bereiche ist verschieden:

  • Namensraum
  • Modul
  • Prozedur

Auf verschiedenen Hierarchieebenen sind gleichnamige Variablen erlaubt. Im folgenden Codefragment ist die »gleiche« Variable auf Prozedur- und auf Modulebene definiert:

Module Module1 
  Public intVar As Integer 
  Sub Main() 
    Dim intVar As Integer 
    ... 
  End Sub 
End Module

Für Namen gilt ein Lokalitätsprinzip: Eine Prozedurvariable verdeckt eine Variable im Modul. In Main() wird also die Prozedurvariable verwendet. Die Modulvariable ist von der Prozedur aus über einen qualifizierenden Namen zu erreichen.

Module1.intVar

Der vollqualifizierte Name enthält, durch einen Punkt getrennt, den Namensraum (oder die Namenshierarchie), den Modulnamen und den Namen der Variable.


<Namensraum>.<Modulname>.<Variablenbezeichner>

Ein Sonderfall ergibt sich für den Fall, das das Modul den Namen eines Wurzelnamensraums trägt. Das folgende Codefragment zeigt, dass dann dem Ganzen noch Global vorangestellt werden muss.

Module System 
  Sub Main() 
    Global.System.Console.ReadLine() 
  End Sub 
End Module

Rheinwerk Computing - Zum Seitenanfang

2.5.6 Initialisierung von Variablen Zur nächsten ÜberschriftZur vorigen Überschrift

Bei jeder Deklaration einer Variablen, ob in einer Prozedur oder einem Modul, wird diese mit einer datentypabhängigen »Null« initialisiert (siehe Tabelle 2.4).


Tabelle 2.4 Initialisierungen von Datentypen

Datentypen Initialisierung

Short, Integer, Long, Single, Double, Decimal, Byte

0

String

Leerstring ""

Boolean

False

Object

Nothing


Diese Vorbelegung kann durch eine explizite Angabe überschrieben werden:

Public intNewVar As Integer = 9 
Dim strMeldung As String = "Visual Studio"

Hinweis
Jede Initialisierung erfordert eine eigene As-Klausel. Fehler bei der Initialisierung einer Static-Variablen setzt diese auf den Standardwert.



Rheinwerk Computing - Zum Seitenanfang

2.5.7 Datentypkonvertierung Zur nächsten ÜberschriftZur vorigen Überschrift

Jede Kombination von Daten verschiedenen Typs, zum Beispiel die Addition einer ganzen Zahl und einer Fließkommazahl, wirft die Frage auf, wie die verschiedenen Typen kombiniert werden sollen. Häufig werden dabei Konvertierungen notwendig, die in zwei Gruppen eingeteilt werden können:

  • implizite Konvertierung: Sie erfolgt automatisch durch den Compiler.
  • explizite Konvertierung: Sie erfolgt durch den Programmierer.

Implizite Konvertierung

Die erste Art ist nur dann sinnvoll, wenn dabei keine Daten verloren gehen. Damit dies funktioniert, muss der Typ, in den konvertiert werden soll, in der Lage sein, alle möglichen Werte des Ausgangstyps aufzunehmen. Zahlen lassen sich wie folgt ohne wesentlichen Datenverlust ineinander umwandeln.


Decimal

Byte

Short

Integer

Long

Single

Double


Die Umwandlungen erfolgen transparent, wie das folgende Codefragment zeigt:

Dim sh As Short = 2367 
  Dim ln As Long = sh 
Dim ch As Char = "A"c 
  Dim st As String = ch

Hinweis
Die Größe einer Zahl bleibt bei einer impliziten Konvertierung in jedem Fall erhalten. Bei der Konvertierung von Long in eine Fließkommazahl kann es zu einem Genauigkeitsverlust kommen.


Das folgende Codefragment zeigt eine Umwandlung mit Genauigkeitsverlust:


' ...\Sprachsyntax\Konvertierungen\Konvertierungen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Konvertierungen 
    ... 
    Sub Genauigkeit() 
      Dim longVar As Long = 1234567890123456789 
      Dim singleVar As Single = longVar 
      Dim doubleVar As Double = longVar 
      Console.WriteLine("long {0}", longVar) 
      Console.WriteLine("double-single {0}", doubleVar – singleVar) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe des Programms zeigt, dass der Single- und Double-Wert in den ersten 9 Stellen übereinstimmt (longVar hat 19 Stellen, die Differenz 11). Dies ist durch die kleinere Genauigkeit eines Single bedingt.

long 1234567890123456789 
double-single –49427152640

Hinweis
Sind an einer mathematischen Operation oder einer Vergleichsoperation Operanden mehrerer Datentypen beteiligt, so werden erst alle implizit auf den »größten« Typ konvertiert, und erst dann wird die Operation ausgeführt. Dieser »größte« Typ ist auch der Ergebnistyp der Operation.


Dies ist der Grund, warum im letzten Beispiel ein Vergleich einer Long- und einer Double-Variablen immer True ergeben würde.


Hinweis
Benutzerdefinierte verlustlose (erweiternde) Konvertierungsoperatoren werden implizit vom Compiler genutzt wie eingebaute (siehe Abschnitt 3.11, »Benutzerdefinierte Operatoren«). Mit der nicht empfehlenswerten Einstellung Option Strict Off und bei der For Each-Schleife (siehe Abschnitt 2.10.2, »For«) werden auch einengende Konvertierungen implizit verwendet (wenn keine erweiternde passt).


Explizite Konvertierung

Jeder Programmierer kennt sein eigenes Werk besser als jeder Compiler. Insbesondere hat ein Compiler keine Möglichkeit, konkrete Werte des Programms zu kennen. Der Entwickler weiß jedoch um seine Programmlogik und kann explizite Konvertierungen erzwingen, die im Allgemeinen nicht möglich sind – frei nach dem Motto: »Compiler vertraue mir, ich bin der Ingenieur« (hoffentlich …).

Es gibt eine Reihe von speziellen Konvertierungsfunktionen in Visual Basic: CShort, CInt, CLng, CDec, CSng, CDbl, CBool, CByte, CChar und CStr. Einfacher zu merken ist jedoch die einzelne Funktion CType, die neben dem zu konvertierenden Ausdruck noch den Zieldatentyp entgegennimmt und alle speziellen Konvertierer umfasst. Im folgenden Codefragment passt der konkrete Wert der Long-Variablen in ein Integer, und die Zuweisung ist daher sinnvoll.

Dim lng As Long, int As Integer 
lng = 122 
int = CType(lng, Integer)

CType berücksichtigt alle definierten Konvertierungen, um zum Zieltyp zu gelangen (inklusive benutzerdefinierte). Demgegenüber fordert DirectCast, dass die Variable ohne Umwege vom angegebenen Typ ist. Es ist daher schneller, erfordert aber eine größere Disziplin des Programmierers, um einen Laufzeitfehler zu vermeiden. Unumgänglich ist diese Funktion in eigenen Konvertierungsfunktionen, um zu vermeiden, dass die Konvertierungsfunktion sich selbst aufruft. Dies setzt sich dann beliebig fort. Man nennt dies eine infinite Rekursion.


Hinweis
DirectCast unterstützt nur native Datentypen.


Ein Irrtum über die eigene Programmlogik kann leicht zu einem Laufzeitfehler führen. Das folgende Codefragment führt zu einer OverflowException-Ausnahme. Da wir in der Prozedur den Fehler nicht abfangen, hält der Debugger an der Zeile an, die die ungültige Konvertierung enthält. In einem solchen Fall kann das Programm nicht sinnvoll fortgesetzt werden, und es empfiehlt sich ein Abbruch über den Menüpunkt DebuggenDebuggen beenden.


' ...\Sprachsyntax\Konvertierungen\Konvertierungen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Konvertierungen 
    ... 
    'unzulaessige Umwandlung 
    Sub Overflow() 
      Dim int As Integer = 256 
      Dim bt As Byte = CType(int, Byte) 
    End Sub 
  End Module 
End Namespace

Nicht immer ist es sofort offensichtlich, dass eine explizite Konvertierung gebraucht wird. Abbildung 2.37 zeigt einen solchen Fall.

Abbildung 2.37 Automatische Operandenumwandlung

Dies liegt an dem folgenden Prinzip:


Der Standardtyp für ganze Zahlen ist Integer, für Fließkommazahlen Double. Bei der Kombination von Daten, die einen »kleineren« Typ haben, konvertiert der Compiler implizit zu diesen Standardtypen.


Dadurch wird shortVar in shortVar + 3 in einen Integer umgewandelt, da die Zahl 3 ein Integer ist. Das Ergebnis der Addition ist daher vom Typ Integer und passt nicht in jedem Fall in den Datentyp von shortVar. Die Lösung besteht wieder in einer expliziten Konvertierung.


' ...\Sprachsyntax\Konvertierungen\Konvertierungen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Konvertierungen 
    ... 
    Sub Explizit() 
      Dim shortVar As Short = 782 
      'Standardtypen sind Integer und Double 
      shortVar = CType(shortVar + 3, Short) 
      Console.WriteLine("shortVar {0}", shortVar) 
      ... 
    End Sub 
  End Module 
End Namespace

Im Gegensatz zu CType vermeidet TryCast eine Ausnahme, wenn die Konvertierung nicht möglich ist. Das Scheitern wird durch den Wert Nothing angezeigt. Damit ist TryCast nur auf Referenztypen anwendbar, nicht auf Zahlen. Im folgenden Codefragment erzeugt die erste Konvertierung den Wert Nothing, die zweite den gewünschten Wert.


' ...\Sprachsyntax\Konvertierungen\Konvertierungen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Konvertierungen 
    ... 
    Sub Versuch() 
      Dim var As Object = Console.Out 
      Dim st As String = TryCast(var, String) 
      Console.WriteLine("Object als String {0}", st) 
      var = "123" 
      st = TryCast(var, String) 
      Console.WriteLine("String als String {0}", st) 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

In der Ausgabe wird Nothing als Leerstring gezeigt und ist nicht sichtbar.

Object als String 
String als String 123

Die bisher vorgestellten expliziten Konvertierungen haben den Nachteil, dass sie nur in Visual Basic zur Verfügung stehen. Will man sprachunabhängig bleiben, um mit der für alle .NET-Sprachen verwendeten Spezifikation (Common Language Specification – CLS) konform zu sein, verwendet man die Funktionalität des Convert-Moduls. Das folgende Codefragment zeigt die Konvertierung zu einem Integer:


' ...\Sprachsyntax\Konvertierungen\Konvertierungen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Konvertierungen 
    ... 
    Sub Explizit() 
      ... 
      Dim von As Single, nach As Integer 
      von = 7.5 
      nach = CType(von, Integer) 
      Console.WriteLine("von-nach {0}-{1}", von,nach) '7.5-8 
      nach = Convert.ToInt32(von) 
      Console.WriteLine("von-nach {0}-{1}", von,nach) '7.5-8 
      Console.ReadLine() 
    End Sub 
  End Module 
End Namespace

Die Ausgabe zeigt einerseits, dass sich CType und Convert gleich verhalten, und andererseits, dass bei der Konvertierung zu ganzen Zahlen gegebenenfalls gerundet wird.

von-nach 7.5-8 
von-nach 7.5-8

Das Convert-Modul enthält eine Menge Konvertierungsfunktionen, die alle ToX heißen und nach Eingabe des Punkts nach Convert von IntelliSense gelistet werden (siehe Abbildung 2.36). Das X hinter dem To steht für einen Zahlendatentyp des .NET Frameworks. Da Short, Integer und Long nur in Visual Basic zu finden sind, werden die korrespondierenden Typen Int16, Int32 und Int64 verwendet (die Zahl steht für die Bitbreite des Typs).


Hinweis
Die Notwendigkeit der hier gezeigten expliziten Konvertierungen ist durch die Compileroption Strict On bedingt. Lassen Sie sich vom Compiler bei der Fehlersuche helfen, und lassen Sie den Schalter auf On. Er ist keine Einschränkung, sondern erfordert an nur wenigen Stellen etwas Tipparbeit.


Ermittlung des Datentyps

Bei diesen ganzen Möglichkeiten zur Konvertierung mögen Sie sich fragen, wie ein Programm den Datentyp eines Ausdrucks selbst ermitteln kann, um zum Beispiel Problemen bei der Konvertierung vorzubeugen. Visual Basic stellt dazu zwei Mechanismen bereit:

  • statisch: GetType(Typname)
  • dynamisch: <Ausdruck>.GetType()

Die erste Variante wird meist zum Vergleich mit der zweiten gebraucht. Das Codefragment

Dim i As Integer 
Console.WriteLine("Variablentyp: {0}", i.GetType()) 
Console.WriteLine("Typ: {0}", GetType(Int32))

liefert folgende Ausgabe:

Variablentyp: System.Int32 
Typ: System.Int32

Zeichenketten

Oft liegen Eingaben für ein Programm in Textform vor, zum Beispiel bei einer konkreten Benutzereingabe oder einer Textdatei. Wenn diese Texte Zahlen repräsentieren sollen, müssen diese vor ihrer Verwendung noch umgewandelt werden. Hierzu haben die Zahlentypen wie Single eine Methode namens Parse.

Dim sin As Single = Single.Parse("8.619")

Alle Typen können mit der Methode ToString in eine Zeichenkette umgewandelt werden. Exakt diesen Mechanismus nutzt WriteLine, um Daten beliebigen Typs auszugeben. Das folgende Codefragment zeigt, dass dies selbst für einfache Zahlen zutrifft:

Console.WriteLine("2.89 als Text {0}", (2.89).ToString())

Hinweis
Ob von Parse und ToString ein Komma oder ein Punkt verwendet wird, hängt von den Ländereinstellungen ab. Der aktuelle Wert steht in System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator.


Die Tatsache, dass wirklich alle Typen in eine Zeichenkette umgewandelt werden können, erlaubt es, beliebige Daten in einem String zu kombinieren. Dazu wird der &-Operator verwendet. Damit haben wir in WriteLine eine Alternative zur {0}-Notation. Die beiden nächsten Zeilen zeigen dies. Die Ausgabe beider Zeilen ist identisch.

Console.WriteLine("Pi {0}", 3.1515) 
Console.WriteLine("Pi " & 3.1515)

Hinweis
Der &-Operator verbindet Zeichenketten und Daten direkt miteinander, wenn der Datentyp den &-Operator definiert, wie zum Beispiel bei Zahlen, Date, Char und String. Für andere Datentypen muss deren ToString()-Methode aufgerufen werden.



Rheinwerk Computing - Zum Seitenanfang

2.5.8 Funktionen Zur nächsten ÜberschriftZur vorigen Überschrift

Visual Basic bietet auch die Möglichkeit, Routinen zu schreiben, die etwas zurückgeben. Auf Modulebene werden sie Funktionen genannt, als Wert einer Variablen λ-Ausdruck (Funktionsobjekt). Letztere werden in Abschnitt 3.9.5 »Funktionsobjekte: λ-Ausdrücke (Function)« besprochen.

Funktionen

Bisher haben wir nur Methoden betrachtet, die mit Sub deklariert werden und keinen Wert zurückliefern. Im Gegensatz dazu liefern mit Function deklarierte Methoden ein Ergebnis zurück. Dazu muss auch der Ergebnistyp in einer As-Klausel angegeben werden. Das folgende Programm zeigt eine eigene Funktion ohne Argumente namens Konstante(), die eine ganze Zahl zurückgibt. Diese Zahl ist vom Typ Byte, der Rückgabetyp der Funktion ist aber Integer. Da eine Konvertierung immer ohne Datenverlust möglich ist, nimmt der Compiler die Umwandlung automatisch vor. In dem WriteLine-Befehl verwenden wir unsere Funktion genau so wie eine beliebige in .NET eingebaute Funktion.


' ...\Sprachsyntax\Funktionen\Funktionen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Funktionen 
    Sub Main() 
      Console.WriteLine("konst/10: {0}", Konstante() / 10) 
      Console.ReadLine() 
    End Sub

    Function Konstante() As Integer 
      Dim konst As Byte = 127 
      Return konst 
    End Function

  End Module 
End Namespace

Die Deklaration des Rückgabetyps ist völlig unabhängig davon, ob eine Funktion Argumente hat oder nicht. Bei der Besprechung von Wert- und Referenztypen im Rahmen der Objektorientierung werden wir Funktionen mit Parametern selbst erstellen.

Eine Alternative zur Verwendung von Return am Ende der Funktion ist die Zuweisung eines Wertes an den Funktionsnamen. Das folgende Codefragment zeigt obige Konstantenfunktion in dieser Variante:


' ...\Sprachsyntax\Funktionen\Funktionen.vb

Option Strict On 
Namespace Sprachsyntax 
  Module Funktionen 
    ... 
    Function Konstante2() As Integer 
      Konstante2 = 127 
    End Function 
  End Module 
End Namespace

Hinweis
Wird eine Funktion ohne explizites Return und ohne explizite Zuweisung an einen Funktionsnamen beendet, gibt sie eine typangepasste Null zurück (siehe Abschnitt 2.5.6, »Initialisierung von Variablen«).


Main

Der Haupteinstiegspunkt einer Anwendung (das, womit begonnen wird) darf die folgenden vier Formen annehmen:

Sub Main() 
Sub Main(args As String) 
Function Main() As Integer 
Function Main(args As String) As Integer

Die optionalen Argumente enthalten die Kommandozeilenparameter, mit denen die Anwendung gestartet wurde. Wird ein Wert zurückgegeben, wird dieser an den Prozess weitergereicht, der das Programm gestartet hat.


Rheinwerk Computing - Zum Seitenanfang

2.5.9 Schlüsselwörter Zur nächsten ÜberschriftZur vorigen Überschrift

Visual Basic 2008 reserviert einige Schlüsselwörter (siehe Tabelle 2.5). Soll eine Variable wie eines dieser Wörter heißen, muss sie in eckige Klammern gesetzt werden.


Tabelle 2.5 Schlüsselwortgruppen

Kontext Schlüsselwörter

Kommentar

REM

Compiler

On, Option

Namensraum

Global, Imports, Namespace

Vordefiniert

Exit, False, GetType, Me, MyBase, MyClass, Nothing, Object, Stop, True

Primitive

Boolean, Byte, Char, Date, Decimal, Double, Integer, Long, SByte, Short, Single, String, UInteger, ULong, UShort

Datentyp

AddressOf, As, Delegate, Class, Enum, Interface, Module, Of, Structure, With

Konvertierung

CBool, CByte, CChar, CDate, CDbl, CDec, CInt, CLng, CObj, CSByte, CShort, CSng, CStr, CType, CUInt, CULng, CUShort, DirectCast, TryCast

Operator

And, AndAlso, Is, IsNot, Like, Mod, New, Not, Or, OrElse, TypeOf, Xor

Ressourcen

Erase, ReDim, Using

Flusskontrolle

Case, Continue, Do, Each, Else, ElseIf, End, For, GoTo, If, In, Loop, Next, Select, Step, Then, To, While

Fehler

Catch, Finally, Throw, Try, When

Funktion

Call, Function, Get, Operator, Property, Return, Set, Sub

Externe Funktion

Alias, Declare, Lib

Ereignis

AddHandler, Event, RaiseEvent, RemoveHandler

Modifikator

ByRef, ByVal, Const, Default, Dim, Friend, Handles, Implements, Inherits, MustInherit, MustOverride, Narrowing, NotInheritable, NotOverridable, Optional, Overloads, Overridable, Overrides, ParamArray, Partial, Private, Protected, Public, ReadOnly, Shadows, Shared, Static, Widening, WithEvents, WriteOnly

Objektzugriff

SyncLock, Using, With

Veraltet

EndIf, Error, GoSub, Let, Resume, Variant, Wend



Hinweise
Stop löst eine Debuggerausnahme aus, während Exit das Programm sofort beendet (Finally-Zweige werden nicht ausgeführt). Ein Funktionsaufruf, dem Call vorangestellt wird, verwirft den Rückgabewert.



Rheinwerk Computing - Zum Seitenanfang

2.5.10 Zusammenfassung topZur vorigen Überschrift

  • Standardmäßig müssen Variablen deklariert werden. Dies kann durch den Schalter Option Explicit Off umgangen werden (implizite Deklaration vom Typ Object). Dies ist nicht zu empfehlen.
  • Der Schalter Option Strict On sollte immer explizit gesetzt werden, damit der Compiler die Typkonsistenz prüfen kann und wir das nicht machen müssen.
  • Eine Anweisung wird durch einen Zeilenvorschub oder einen Doppelpunkt beendet.
  • Eine lange Anweisung kann durch einen Unterstrich auf zwei Zeilen aufgeteilt werden. Vor dem Unterstrich muss ein Leerzeichen stehen, und der Umbruch kann nicht mitten in einer Zeichenfolge erfolgen.
  • Kommentare werden mit einem Hochkomma eingeleitet und gehen bis zum Zeilenende.
  • Jede Quellcodedatei kann ein oder mehrere Module enthalten. Die Modulnamen müssen innerhalb des Projekts eindeutig sein.
  • Für den Programmcode jeder Quellcodedatei wird in der Entwicklungsumgebung ein eigener Texteditor bereitgestellt.
  • Die Common Language Runtime (CLR) unterscheidet native Datentypen und klassenbasierte Objekte. Ein weiteres Unterscheidungskriterium sind Wertetypen und Referenztypen.
  • Ganzzahlige Literale werden als Integer interpretiert, Literale mit Dezimaltrennzeichen als Double.
  • Die Zeitspanne, über die hinweg eine Variable ihre Gültigkeit behält, wird als die Lebensdauer bezeichnet. Die Sichtbarkeit einer Variablen bestimmt, von welchen Stellen des Programmcodes auf deren Inhalt zugegriffen werden kann.
  • Lokale Variablen sind innerhalb einer Prozedur deklariert und nur in dieser sichtbar. Sie können nur als Dim oder Static deklariert werden.
  • Globale Variablen sind außerhalb jeglicher Prozedurdefinition deklariert. Ihre Sichtbarkeit hängt vom Sichtbarkeitsmodifikator ab (z. B. Private oder Public).
  • Wird bei einer Operation das Datum eines bestimmten Typs in ein Datum eines größeren Typs umgewandelt, wird von impliziter Konvertierung gesprochen. Implizite Konvertierungen werden vom Compiler automatisch vorgenommen.
  • Bei der expliziten Konvertierung muss der Wertebereich des Zieldatentyps groß genug sein, um das übergebene Datum aufzunehmen. Ansonsten wird eine Ausnahme ausgelöst.
  • Eine explizite Konvertierung kann sowohl mit sprachspezifischen Konvertierungsfunktionen als auch mit den Methoden der Klasse Convert ausgeführt werden.


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual Basic 2008
Visual Basic 2008
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Visual Basic 2012






 Visual Basic 2012


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de