Przedmowa... 11 Rozdział 1. Wprowadzenie... 13



Podobne dokumenty
Wykład 3 Składnia języka C# (cz. 2)

Podstawy programowania. Podstawy C# Tablice

Języki i metodyka programowania. Język C# pętle, sterowanie, wyjątki

C# 6.0 : kompletny przewodnik dla praktyków / Mark Michaelis, Eric Lippert. Gliwice, cop Spis treści

Rozdział 4 KLASY, OBIEKTY, METODY

Jeśli chcesz łatwo i szybko opanować podstawy C++, sięgnij po tę książkę.

1 Podstawy c++ w pigułce.

Strona główna. Strona tytułowa. Programowanie. Spis treści. Sobera Jolanta Strona 1 z 26. Powrót. Full Screen. Zamknij.

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Wykład 4. Klasa List Kolejki Stosy Słowniki

Myśl w języku Python! : nauka programowania / Allen B. Downey. Gliwice, cop Spis treści

Uwagi dotyczące notacji kodu! Moduły. Struktura modułu. Procedury. Opcje modułu (niektóre)

Wykład 4: Klasy i Metody

Wykład 5 Okna MDI i SDI, dziedziczenie

Obszar statyczny dane dostępne w dowolnym momencie podczas pracy programu (wprowadzone słowem kluczowym static),

Wykład 8: klasy cz. 4

Programowanie Komputerów

2. Tablice. Tablice jednowymiarowe - wektory. Algorytmy i Struktury Danych

Konstruktory. Streszczenie Celem wykładu jest zaprezentowanie konstruktorów w Javie, syntaktyki oraz zalet ich stosowania. Czas wykładu 45 minut.

Programowanie strukturalne i obiektowe : podręcznik do nauki zawodu technik informatyk / Adam Majczak. Gliwice, cop

Spis treści. 1 Java T M

Niezwykłe tablice Poznane typy danych pozwalają przechowywać pojedyncze liczby. Dzięki tablicom zgromadzimy wiele wartości w jednym miejscu.

Spis treści WSTĘP CZĘŚĆ I. PASCAL WPROWADZENIE DO PROGRAMOWANIA STRUKTURALNEGO. Rozdział 1. Wybór i instalacja kompilatora języka Pascal

1 Podstawy c++ w pigułce.

JAVA. Platforma JSE: Środowiska programistyczne dla języka Java. Wstęp do programowania w języku obiektowym. Opracował: Andrzej Nowak

Rozdzia l 3. Laboratorium 3. danych zawierajac

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Microsoft Visual C : praktyczne przykłady / Mariusz Owczarek. Gliwice, cop Spis treści

TOPIT Załącznik nr 3 Programowanie aplikacji internetowych

Podstawy programowania. Wprowadzenie

Tablice. Jones Stygar na tropie zmiennych

Wprowadzenie do języka Java

Podstawy programowania skrót z wykładów:

Microsoft IT Academy kurs programowania

JĘZYKI PROGRAMOWANIA Z PROGRAMOWANIEM OBIEKTOWYM. Wykład 6

Programowanie obiektowe. Literatura: Autor: dr inŝ. Zofia Kruczkiewicz

Obiekt klasy jest definiowany poprzez jej składniki. Składnikami są różne zmienne oraz funkcje. Składniki opisują rzeczywisty stan obiektu.

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

W powyższym kodzie utworzono wyliczenie dni tygodnia.

Podstawy języka C++ Maciej Trzebiński. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. Praktyki studenckie na LHC IVedycja,2016r.

Podstawy Programowania C++

Kiedy potrzebne. Struktura (rekord) Struktura w języku C# Tablice struktur. struktura, kolekcja

IMIĘ i NAZWISKO: Pytania i (przykładowe) Odpowiedzi

Język JAVA podstawy. Wykład 3, część 3. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Lab 9 Podstawy Programowania

Deklaracja struktury w C++

PHP: bloki kodu, tablice, obiekty i formularze

MATERIAŁY DO ZAJĘĆ I. Podstawowe pojęcia. Algorytm. Spis treści Przepis

Materiał Typy zmiennych Instrukcje warunkowe Pętle Tablice statyczne Wskaźniki Tablice dynamiczne Referencje Funkcje

Część 4 życie programu

Zasady programowania Dokumentacja

Operatory cd. Relacyjne: ==!= < > <= >= bool b; int i =10, j =20; dzielenie całkowitych wynik jest całkowity! Łączenie tekstu: + string s = "Ala ma ";

Programowanie w środowiskach graficznych. Wykład 3 Język C#

Informacje ogólne. Karol Trybulec p-programowanie.pl 1. 2 // cialo klasy. class osoba { string imie; string nazwisko; int wiek; int wzrost;

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

Swift (pol. jerzyk) nowy język programowania zaprezentowany latem 2014 r. (prace od 2010 r.)

Program szkoleniowy. 24 h dydaktycznych (18 h zegarowych) NAZWA SZCZEGÓŁY CZAS

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 3. Karol Tarnowski A-1 p.

Wskaźnik może wskazywać na jakąś zmienną, strukturę, tablicę a nawet funkcję. Oto podstawowe operatory niezbędne do operowania wskaźnikami:

Języki i techniki programowania Ćwiczenia 2

Wykład 2 Składnia języka C# (cz. 1)

KOTLIN. Język programowania dla Androida

C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów. C++ - przeciążanie operatorów

Wprowadzenie do programowania

PHP 5 język obiektowy

Podczas dziedziczenia obiekt klasy pochodnej może być wskazywany przez wskaźnik typu klasy bazowej.

Java - tablice, konstruktory, dziedziczenie i hermetyzacja

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Tablice (jedno i wielowymiarowe), łańcuchy znaków

Język ludzki kod maszynowy

1 Atrybuty i metody klasowe

Programowanie obiektowe

Lekcja 1. Składnia języka zmienne i podstawowe instrukcje PHP. Do wyświetlania tekstu służy instrukcja echo echo Hello world ;

1. Nagłówek funkcji: int funkcja(void); wskazuje na to, że ta funkcja. 2. Schemat blokowy przedstawia algorytm obliczania

Instrukcja laboratoryjna cz.3

Klasy cd. Struktury Interfejsy Wyjątki

Języki skryptowe w programie Plans

Aplikacje w środowisku Java

Smarty PHP. Leksykon kieszonkowy

Programowanie MorphX Ax

PLAN WYNIKOWY PROGRAMOWANIE APLIKACJI INTERNETOWYCH. KL IV TI 6 godziny tygodniowo (6x15 tygodni =90 godzin ),

Laboratorium 1 - Programowanie proceduralne i obiektowe

Programowanie obiektowe

Narzędzia 2. dr inż. Tadeusz Jeleniewski

Podstawy języka C++ Maciej Trzebiński. Praktyki studenckie na LHC IFJ PAN. Instytut Fizyki Jądrowej Polskiej Akademii Nauk. M. Trzebiński C++ 1/16

Podstawy Programowania Podstawowa składnia języka C++

Informatyka I. Wykład 4. Tablice. Dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Metodyka programowania. Podstawy C#

C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy. C++ - klasy INNE SPOSOBY INICJALIZACJI SKŁADOWYCH OBIEKTU

Java EE produkcja oprogramowania

Podstawy programowania (1)

Kurs WWW. Paweł Rajba.

Pętle. for, while, do... while, foreach. Materiał pomocniczy do kursu Podstawy programowania Autor: Grzegorz Góralski ggoralski.

1. Które składowe klasa posiada zawsze, niezależnie od tego czy je zdefiniujemy, czy nie?

Szablony klas, zastosowanie szablonów w programach

Zofia Kruczkiewicz, Programowanie obiektowe - java, wykład 2 1

Klasy abstrakcyjne i interfejsy

I - Microsoft Visual Studio C++

Klasy. dr Anna Łazińska, WMiI UŁ Podstawy języka Java 1 / 13

Transkrypt:

Spis treści Przedmowa... 11 Rozdział 1. Wprowadzenie... 13 Czym jest programowanie...13 Mnogość języków programowania...14 Edytory kodu...15 Kompilatory...15 Mity związane z programowaniem...16 Języki programowania...17 Asembler...18 Fortran...19 C...19 C++...19 Perl...20 PHP...20 Turbo Pascal...20 Java...21 Język maszynowy...21 Działanie kompilatorów...22 Tworzenie kodu źródłowego...22 Prekompilacja...23 Kompilacja do kodu Asemblera...23 Optymalizacja kodu...23 Asemblacja...23 Konsolidacja...24 Języki interpretowane...24 Język C#...24 Instalacja środowiska...24 Jak się uczyć...25 Nie ucz się na pamięć!...25 Początkowe trudności...25 Pomoc systemowa...25 Praktyka...26 Pierwsza aplikacja...26 Kompilacja i uruchamianie...26 Komponenty...28 Piszemy kod...29 Zapisywanie projektu...29 Podsumowanie...30

4 Wstęp do programowania w języku C# Rozdział 2. Podstawy platformy.net... 31 Interfejs programistyczny...32 API systemu Windows...32 Wizja.NET...33 Składniki platformy.net...34 Konkluzja...37 C# a.net...37 Rodzaje aplikacji...38 Aplikacje konsolowe...38 Windows Forms...38 Formularze Web Forms...38 Składniki.NET Framework...39 Usługi sieciowe...39 Niezależność...40 Uniwersalność...40 Podsumowanie...41 Rozdział 3. Podstawy języka C#... 43 Podstawowa składnia...43 Najprostszy program...45 Jak kompilatory czytają kod...45 Wielkość znaków...45 Program musi posiadać metodę Main...46 Średnik kończy instrukcję...46 Program musi posiadać klasę...47 Wcięcia, odstępy...47 Słowa kluczowe...47 Symbole...47 Komentarze...48 Podzespoły, metody, klasy...49 Funkcje...49 Metody...50 Klasy...50 Przestrzenie nazw...51 Operator kropki...51 Słowo kluczowe using...52 Zmienne...53 Deklarowanie zmiennych...53 Przydział danych...54 Typy danych...55 Restrykcje w nazewnictwie...55 Stałe...56 Operacje na konsoli...57 Metody klasy Console...58 Właściwości klasy Console...58 Operatory...59 Operatory porównania...60 Operatory arytmetyczne...60 Operator inkrementacji oraz dekrementacji...61 Operatory logiczne...62 Operatory bitowe...62 Operatory przypisania...63 Inne operatory...63

Spis treści 5 Instrukcje warunkowe...63 Instrukcja if...64 Słowo kluczowe else...68 Instrukcja else if...69 Instrukcja switch...70 Pętle...73 Pętla while...73 Pętla do-while...75 Pętla for...76 Instrukcja break...77 Instrukcja continue...78 Operator warunkowy...79 Konwersja danych...80 Rzutowanie...81 Przykładowa aplikacja...81 Dyrektywy preprocesora...83 Deklarowanie symboli...84 Instrukcje warunkowe...84 Błędy i ostrzeżenia...85 Podsumowanie...86 Rozdział 4. Przegląd.NET Framework... 87 Środowisko CLR...87 Kod pośredni IL...88 Kod zarządzany i niezarządzany...89 Moduł zarządzany...89 Podzespoły...90 Działanie CLR...90 System CTS...91 Specyfikacja CLS...92 Biblioteka klas...93 Moduły, przestrzenie nazw...93 Wieloznaczność...95 Główne przestrzenie nazw...96 Podsumowanie...97 Rozdział 5. Programowanie obiektowe... 99 Na czym polega programowanie obiektowe...99 Podstawowy kod formularza WinForms...101 Moduł Form1.Designer.cs...103 Generowanie kodu...104 Ukrywanie kodu...105 Programowanie zdarzeniowe...106 Generowanie zdarzeń...106 Obsługa zdarzeń...110 Klasy...110 Składnia klasy...110 Do czego służą klasy...111 Instancja klasy...112 Klasy zagnieżdżone...114 Pola...114

6 Wstęp do programowania w języku C# Metody...115 Zwracana wartość...116 Parametry metod...116 Przeciążanie metod...118 Przekazywanie parametrów...119 Dziedziczenie...122 Klasa domyślna...123 Hermetyzacja...123 Modyfikatory dostępu...123 Sekcja private...124 Sekcja public...125 Sekcja protected...126 Sekcja internal...127 Konstruktor...127 Pola tylko do odczytu...128 Destruktor...129 Właściwości...129 Modyfikatory dostępu...132 Elementy statyczne...132 Metody statyczne...133 Klasy statyczne...134 Polimorfizm...135 Ukrywanie elementów klas...135 Słowo kluczowe base...137 Metody wirtualne...139 Przedefiniowanie metod...140 Elementy abstrakcyjne...141 Elementy zaplombowane...142.net Framework Class Library...142 Przestrzenie nazw...143 Klasa System.Object...143 Opakowywanie typów...145 Interfejsy...146 Implementacja wielu interfejsów...147 Typy wyliczeniowe...148 Wartości elementów...149 Struktury...150 Konstruktory struktur...152 Operatory is i as...154 Przeładowanie operatorów...155 Słowo kluczowe operator...156 Dzielenie klas...158 Podsumowanie...158 Rozdział 6. Delegaty i zdarzenia... 159 Delegaty...159 Tworzenie delegatów...160 Użycie delegatów...161 Funkcje zwrotne...163 Delegaty złożone...165 Metody anonimowe...165 Zdarzenia...166 Podsumowanie...169

Spis treści 7 Rozdział 7. Tablice i kolekcje... 171 Czym są tablice...171 Deklarowanie tablic...172 Indeks...172 Inicjalizacja danych...173 Tablice wielowymiarowe...173 Pętla foreach...174 Pętla foreach a tablice wielowymiarowe...176 Tablice tablic...177 Tablice struktur...177 Parametr args w metodzie Main()...178 Klasa System.Array...179 Metody klasy...180 Słowo kluczowe params...185 Przykład gra kółko i krzyżyk...186 Zasady gry...186 Specyfikacja klasy...186 Ustawienie symbolu na planszy...190 Sprawdzenie wygranej...191 Interfejs aplikacji...196 Mechanizm indeksowania...201 Indeksy łańcuchowe...203 Kolekcje...204 Interfejsy System.Collections...204 Stosy...206 Kolejki...208 Klasa ArrayList...209 Listy...209 Typy generyczne...210 Korzystanie z list...212 Słowniki...214 Przykładowy program...215 Podsumowanie...217 Rozdział 8. Obsługa wyjątków... 219 Czym są wyjątki...220 Obsługa wyjątków...220 Blok finally...221 Zagnieżdżanie wyjątków...222 Klasa System.Exception...223 Selektywna obsługa wyjątków...223 Wywoływanie wyjątków...224 Własne klasy wyjątków...224 Deklarowanie własnej klasy...225 Przykładowa aplikacja...226 Przepełnienia zmiennych...229 Podsumowanie...230 Rozdział 9. Łańcuchy w C#... 231 Typ System.String...231 Unicode w łańcuchach...232 Niezmienność łańcuchów...232 Konstruktory klasy...233 Operacje na łańcuchach...234

8 Wstęp do programowania w języku C# Łańcuchy w WinForms...239 Klasa StringBuilder...241 Metody klasy StringBuilder...242 Zastosowanie klasy StringBuilder...242 Formatowanie łańcuchów...244 Specyfikatory formatów...246 Własne specyfikatory formatowania...248 Specyfikatory typów wyliczeniowych...249 Typ System.Char...250 Podsumowanie...251 Rozdział 10. Biblioteka Windows Forms... 253 Podzespół System.Windows.Forms...253 Okno Object Browser...254 Przestrzeń System.Windows.Forms...254 Podstawowe klasy...255 System.ComponentModel.Component...256 System.Windows.Forms.Control...256 System.Windows.Forms.Application...256 Przykład działania...261 Przygotowanie klasy...261 Projektowanie interfejsu...261 Rozwiązania programistyczne...262 Technika przeciągnij i upuść...266 Tworzenie menu...270 Właściwości menu...271 Ikony dla menu...271 Skróty klawiaturowe...274 Menu podręczne...274 Paski narzędziowe...275 Pasek statusu...276 Zakładki...276 Kontrolki tekstowe...277 Komponent RichTextBox...280 Okna dialogowe...281 Właściwości okien dialogowych...282 Aplikacja edytor tekstów...283 Tworzenie nowego formularza...284 Podsumowanie...285 Rozdział 11. Podzespoły.NET... 287 Czym jest COM...287 Kontrolka w rozumieniu COM...288 Odrobinę historii...288 ActiveX...288 DCOM...289 Podstawowy podzespół...289 Deasembler.NET...289 Komponenty.NET...291 Przygotowanie komponentu w Delphi...291 Przygotowanie komponentu C#...293 Zalety stosowania podzespołów...295 Budowa podzespołu...296 Atrybuty podzespołu...297

Spis treści 9 Mechanizm refleksji...298 Funkcja GetType...299 Klasa System.Type...300 Ładowanie podzespołu...301 Przykład działania program Reflection...301 Własne atrybuty...306 Aplikacje.NET Framework SDK...311 Global Assembly Cache Tool...311 WinCV...313 Narzędzie konfiguracji.net Framework...313 PEVerify narzędzie weryfikacji...314.net a COM...314 PInvoke...316 Użycie funkcji Win32 API...316 Użycie atrybutu DLLImport...318 Podsumowanie...319 Rozdział 12. Pliki i obsługa strumieni... 321 Czym są strumienie...321 Klasy przestrzeni System.IO...322 Operacje na katalogach...322 Tworzenie i usuwanie katalogów...322 Kopiowanie i przenoszenie...323 Odczytywanie informacji o katalogu...325 Obsługa plików...326 Tworzenie i usuwanie plików...327 Kopiowanie i przenoszenie plików...328 Odczytywanie informacji o pliku...328 Strumienie...330 Obsługa plików tekstowych...330 Operacje na danych binarnych...334 Serializacja...335 Formaty zapisu danych...335 Przykład serializacji...336 Podsumowanie...337 Rozdział 13. Obsługa formatu XML... 339 Niezależność XML...340 XHTML...340 Budowa dokumentu...340 Prolog...341 Znaczniki...341 Atrybuty...343 Podstawowa terminologia...344 Węzeł główny...345 Komentarze...345 Przestrzenie nazw...345 Składnia przestrzeni nazw...346 Przestrzenie nazw i atrybuty...346 DTD...347 Deklaracja elementu...347 Deklaracja atrybutu...349 DTD w osobnym pliku...350 Encje tekstowe...350

10 Wstęp do programowania w języku C# XSD...351 Nagłówek XSD...352 Elementy XSD...353 Typy danych...353 Typy proste...353 XML a bazy danych...356 XSL...357 DOM...357 SAX...358 Korzystanie z System.XML...359 Ładowanie pliku XML...359 Odczyt dowolnego elementu...360 Odczyt wartości atrybutów...362 Tworzenie pliku XML...364 Dokumentacja XML...369 Podsumowanie...371 Skorowidz... 373

Rozdział 7. Tablice i kolekcje Omówiliśmy już sporą część tego, co oferuje język C#. Powiedzieliśmy sobie o najważniejszym programowaniu obiektowym, które może przysporzyć najwięcej kłopotów początkującemu programiście. Nie zaprezentowałem do tej pory bardzo ważnego elementu wielu języków programowania, a mianowicie obsługi tablic. Jest to bardzo wygodna funkcja języka programowania; przekonasz się o tym podczas pisania przykładowej aplikacji podsumowującej dotychczasową wiedzę o języku C#. Będzie to znana i lubiana gra kółko i krzyżyk. O tym jednak pod koniec tego rozdziału. Nie przedłużając, spieszę z wyjaśnieniem, czym są tablice Czym są tablice Wyobraź sobie, że w swojej aplikacji musisz przechować wiele zmiennych tego samego typu. Dla przykładu, niech będą to dni tygodnia typu string. Proste? Owszem, wystarczy zadeklarować siedem zmiennych typu string: string pon, wt, śr, czw, pt, so, nd; Teraz do tych zmiennych należy przypisać wartość: pon = "Poniedziałek"; wt = "Wtorek"; // itd Teraz wyobraź sobie sytuację, w której musisz zadeklarować 12 zmiennych oznaczających nazwy miesięcy. Nieco uciążliwe? Owszem. Do tego celu najlepiej użyć tablic, które służą do grupowania wielu elementów tego samego typu. Osobiście z tablic korzystam bardzo często, jest to znakomity, czytelny sposób na przechowywanie dużej ilości danych. Przejdźmy jednak do rzeczy. W C# istnieje możliwość deklaracji zmiennej, która przechowywać będzie wiele danych. Tak w skrócie i uproszczeniu możemy powiedzieć o tablicach.

172 Wstęp do programowania w języku C# Deklarowanie tablic Tablice deklaruje się podobnie jak zwykłe zmienne. Jedyną różnicą jest zastosowanie nawiasów kwadratowych: typ[] Nazwa; W miejsce typ należy podać typ danych elementów tablicowych (np. int, string), a w miejsce nazwa nazwę zmiennej tablicowej. Przykładowo: int[] Foo; W tym miejscu zadeklarowaliśmy tablicę Foo, która może przechowywać elementy typu int. Przed użyciem takiej tablicy należy zadeklarować, z ilu elementów ma się ona składać. W tym celu korzystamy ze znanego nam operatora new: Foo = new int[5]; Taka konstrukcja oznacza zadeklarowanie w pamięci komputera miejsca dla pięciu elementów tablicy Foo. Przypisywanie danych do poszczególnych elementów odbywa się również przy pomocy symboli nawiasów kwadratowych: int[] Foo; Foo = new int[5]; Foo[0] = 100; Foo[1] = 1000; Foo[2] = 10000; Foo[3] = 100000; Foo[4] = 1000000; Console.WriteLine(Foo[4]); Możliwy jest również skrótowy zapis deklaracji tablic, podobny do tego znanego z tworzenia obiektów: int[] Foo = new int[5]; Indeks Tablica składa się z elementów. Każdemu z nich przypisany jest tzw. indeks, dzięki któremu odwołujemy się do konkretnego elementu tablicy. Ów indeks ma postać liczby i wpisujemy go w nawiasach kwadratowych, tak jak to zaprezentowano w poprzednim przykładzie. Spójrz na kolejny przykład: char[] Foo = new char[5]; Foo[0] = 'H'; Foo[1] = 'e'; Foo[2] = 'l'; Foo[3] = 'l'; Foo[4] = 'o';

Rozdział 7. Tablice i kolekcje 173 Indeksy numerowane są od zera do N 1, gdzie N to ilość elementów tablicy. Aby lepiej to zrozumieć, spójrz na tabelę 7.1. Tabela 7.1. Prezentacja zależności indeksów elementów Indeks 0 1 2 3 4 Wartość H e l l o Należy uważać, aby nie odwołać się do elementu, który nie istnieje! Jeżeli zadeklarowaliśmy tablicę 5-elementową i odwołujemy się do szóstego elementu (poprzez indeks nr 5), kompilator C# nie zareaguje! Błąd zostanie wyświetlony dopiero po uruchomieniu programu. Inicjalizacja danych Po utworzeniu tablicy każdemu elementowi przypisywana jest domyślna wartość. Np. w przypadku typu int jest to cyfra 0. Programista po zadeklarowaniu takiej tablicy ma możliwość przypisania wartości dla konkretnego elementu. Istnieje możliwość przypisania wartości dla konkretnego elementu już przy deklarowaniu tablicy. Należy wówczas wypisać wartości w klamrach: char[] Foo = new char[5] 'H', 'e', 'l', 'l', 'o'; Console.WriteLine(Foo[4]); Język C# dopuszcza uproszczony zapis takiego kodu wystarczy pominąć ilość elementów tablicy: char[] Foo = 'H', 'e', 'l', 'l', 'o'; Kompilator oblicza rozmiar takiej tablicy po ilości elementów uporządkowanych pomiędzy klamrami. Tablice wielowymiarowe C# umożliwia także deklarowanie tzw. tablic wielowymiarowych. Przykładowo, poniższy kod tworzy tablicę 7 2 (7 kolumn i 2 wiersze): string[,] Foo = new string[7, 2]; Zasada deklarowania tablic wielowymiarowych jest prosta. W nawiasie kwadratowym wpisujemy znak przecinka (,), natomiast podczas inicjalizacji musimy podać wymiar tablicy (ilość elementów należy również rozdzielić znakiem średnika). Podczas przypisywania danych do elementów należy podać dokładny indeks:

174 Wstęp do programowania w języku C# Foo[0, 0] = "Pn"; Foo[1, 0] = "Wt"; Foo[2, 0] = "Śr"; Foo[3, 0] = "Czw"; Foo[4, 0] = "Pt"; Foo[5, 0] = "So"; Foo[6, 0] = "Nd"; Foo[0, 1] = "Mon"; Foo[1, 1] = "Tue"; Foo[2, 1] = "Wed"; Foo[3, 1] = "Thu"; Foo[4, 1] = "Fri"; Foo[5, 1] = "Sat"; Foo[6, 1] = "Sun"; Język C# nie ogranicza nas w ilości wymiarów. Możemy więc wprowadzić do naszej tablicy kolejny wymiar. Poniższy fragment prezentuje deklarację tablicy 2 4 2: string[,,] Foo = new string[2, 4, 2]; Inicjalizacja danych tablicy wielowymiarowej jest analogiczna do standardowej tablicy: int[,] Foo = new int[3, 3] 1, 2, 3, 4, 5, 6, 7, 8, 9 ; Zauważ jednak, że poszczególne elementy zawarte w klamrach są rozdzielone znakiem przecinka. Oczywiście istnieje możliwość skrótowego zapisu: lub: int[,] Foo = new int[,] 1, 2, 3, 4, 5, 6, 7, 8, 9 ; int[,] Foo = 1, 2, 3, 4, 5, 6, 7, 8, 9 ; Pętla foreach Podczas omawiania zagadnienia pętli nie wspomniałem o jednej ważnej pętli służącej do operowania na tablicach. Ponieważ tematyka tablic w rozdziale 3. nie była omawiania, pragnę wspomnieć o tej pętli właśnie tutaj. Pętla ta, znana programistom PHP, Perl czy też Delphi, dla.net jako parametru wymaga tablicy. Spójrz na poniższy fragment kodu: string[] Foo = new string[7]; Foo[0] = "Pn"; Foo[1] = "Wt"; Foo[2] = "Śr"; Foo[3] = "Czw"; Foo[4] = "Pt"; Foo[5] = "So"; Foo[6] = "Nd";

Rozdział 7. Tablice i kolekcje 175 foreach (string Bar in Foo) Console.WriteLine(Bar); Uruchomienie takiej aplikacji spowoduje wyświetlenie, jeden pod drugim, kolejnych elementów tablicy. Po każdej iteracji kolejny element tablicy przypisywany jest do zmiennej Bar. Tutaj ważna uwaga. Zmienna Bar nie może być zadeklarowana lub użyta we wcześniejszych fragmentach kodu. Np. poniższa konstrukcja jest błędna: string Bar = "Test"; foreach (string Bar in Foo) Console.WriteLine(Bar); Przy próbie kompilacji wyświetlony zostanie błąd: A local variable named 'Bar' cannot be declared in this scope because it would give a different meaning to 'Bar', which is already used in a 'parent or current' scope to denote something else. Identyczny rezultat jak ten pokazany przed chwilą można osiągnąć, stosując pętlę for: for (int i = 0; i < Foo.Length; i++) Console.WriteLine(Foo[i]); Konstrukcja Foo.Length zwraca rozmiar tablicy. Zasadniczo wygodniejszym i czytelniejszym sposobem jest użycie pętli foreach, która w końcu została stworzona po to, by operować na tablicach. Jednakże użycie pętli for ma jedną przewagę nad foreach można w niej modyfikować wartości elementów. Spójrz na poniższy przykład: for (int i = 0; i < Foo.Length; i++) Foo[i] = "Foo"; Console.WriteLine(Foo[i]); Identycznego efektu nie uzyskamy, stosując pętlę foreach: foreach (string Bar in Foo) Bar = "Foo"; W tym momencie kompilator zasygnalizuje błąd: Cannot assign to 'Bar' because it is a 'foreach iteration variable'.

176 Wstęp do programowania w języku C# Pętla foreach a tablice wielowymiarowe Pętla foreach z powodzeniem działa na tablicach wielowymiarowych. W takim wypadku kolejność iteracji jest następująca: najpierw przekazana zostanie wartość elementu [0, 1], następnie [0, 2] itd. Krótki kod prezentujący takie działanie: string[,] Foo = new string[7, 2]; Foo[0, 0] = "Pn"; Foo[1, 0] = "Wt"; Foo[2, 0] = "Śr"; Foo[3, 0] = "Czw"; Foo[4, 0] = "Pt"; Foo[5, 0] = "So"; Foo[6, 0] = "Nd"; Foo[0, 1] = "Mon"; Foo[1, 1] = "Tue"; Foo[2, 1] = "Wed"; Foo[3, 1] = "Thu"; Foo[4, 1] = "Fri"; Foo[5, 1] = "Sat"; Foo[6, 1] = "Sun"; foreach (string Bar in Foo) Console.WriteLine(Bar); Kolejność wyświetlania danych na konsoli będzie następująca: Pon Mon Wt Tue... W przypadku tablic wielowymiarowych konstrukcja Tablica.Length zwraca liczbę wszystkich elementów w tablicy. W prezentowanym przykładzie będzie to 7 2, czyli 14. Działanie pętli for na tablicach wielowymiarowych jest nieco inne. Przykładowo, poniższa pętla spowoduje wyświetlenie jedynie polskich dni tygodnia: for (int i = 0; i < Foo.Length / 2; i++) Console.WriteLine(Foo[i, 0]);

Rozdział 7. Tablice i kolekcje 177 Tablice tablic Mechanizm tablic jest w języku C# bardzo rozbudowany. Umożliwia nawet tworzenie tablic, które zawierają kolejne tablice. Poniższy kod prezentuje deklarację takiej tablicy: int[][] Foo = new int[2][]; Ten zapis oznacza, iż tablica Foo zawierać będzie kolejne dwie tablice o nieokreślonej jeszcze liczbie elementów. Te dwie kolejne tablice również muszą zostać utworzone: Foo[0] = new int[50]; Foo[1] = new int[1000]; Przypisywanie danych do takich tablic wygląda podobnie jak w przypadku tablic wielowymiarowych: // przypisanie wartości do elementu 26. tablicy nr 1 Foo[0][25] = 100; // przypisanie wartości do elementu 1000. tablicy drugiej Foo[1][999] = 1; Sprawa inicjalizacji tablic prezentuje się podobnie, jak to zostało zaprezentowane w trakcie omawiania bardziej podstawowych elementów. Przypisanie wartości do elementów w tablicach tego typu charakteryzuje się dość specyficzną składnią: int[][] Foo = new int[][] new int[] 1, 2, // zwróć uwagę na brak średnika! new int[] 1, 2, 3 ; // zwróć uwagę na obecność średnika! Console.WriteLine(Foo[0][1]); Moim zdaniem przejrzystszy jest skrótowy zapis powyższego kodu, również akceptowany przez kompilator C#: int[][] Foo = new int[] 1, 2, new int[] 1, 2, 3 ; Tablice struktur O strukturach i wyliczeniach powiedzieliśmy sobie w rozdziale 5. W niektórych przypadkach przydatna okazuje się możliwość deklarowania tablic struktur lub typów wyliczeniowych. Jest to sprawa dość prosta, jeżeli znasz już podstawy użycia tablic, bowiem zamiast typu dotychczas używanego (czyli int, string, char itp.) należy użyć wcześniej zadeklarowanej struktury:

178 Wstęp do programowania w języku C# public struct Bar public string Name; public byte Age; class Program static void Main(string[] args) Bar[] BarArr = new Bar[2]; BarArr[0].Name = "Janusz Kowalski"; BarArr[0].Age = 52; BarArr[1].Name = "Piotr Nowak"; BarArr[1].Age = 18; Parametr args w metodzie Main() Gdy w rozdziale trzecim omawiałem podstawowe elementy programu C#, wspomniałem oczywiście o metodzie Main(), lecz pominąłem znaczenie parametru args. Zrobiłem to celowo, aby nie wprowadzać zamętu, gdyż tematyka tablic czy nawet typów danych nie była wówczas poruszana. Parametr args typu tablicowego zawiera ewentualne parametry przekazane do naszej aplikacji z linii poleceń. Czyli uruchamiając program z poziomu linii komend, mogę napisać: MojaAplikacja.exe Parametr1 Parametr2 Zarówno Parametr1, jak i Parametr2 zostaną przekazane do aplikacji, każdy zostanie przypisany do odrębnego elementu tablicy. Napiszmy dla treningu prosty program. Jego zadanie będzie banalne: sortowanie argumentów przekazanych do programu. Właściwie najtrudniejszą rzeczą w programie jest sama konwersja danych z łańcucha string na wartość całkowitą int. Samo sortowanie tablicy realizuje metoda Sort() klasy Array. Całość programu prezentuje listing 7.1. Listing 7.1. Pobieranie i sortowanie argumentów programu using System; namespace FooConsole class Program static void Main(string[] args)

Rozdział 7. Tablice i kolekcje 179 if (args.length == 0) Console.WriteLine("Brak argumentów programu!"); return; int[] ArrInt = new int[args.length]; int count = 0; foreach (string element in args) ArrInt[count] = Int32.Parse(element); ++count; Array.Sort(ArrInt); for (int i = 0; i < ArrInt.Length; i++) Console.WriteLine("0 ", ArrInt[i]); Argumenty przekazane do aplikacji konwertujemy, a następnie zapisujemy w nowo utworzonej tablicy ArrInt. Zwróć uwagę, że do konwersji danych ze string na int użyłem metody Parse() z klasy Int32. To również jest dopuszczalny sposób, równie dobrze mogłem także użyć klasy Convert. Posortowaną tablicę prezentuję na konsoli, wyświetlając w pętli kolejne jej elementy. Element 0 wykorzystany w łańcuchu w metodzie WriteLine() zostanie zastąpiony wartością zmiennej przekazanej w tej samej metodzie. Jest to czytelny i prosty sposób formatowania łańcuchów np.: string sname = "Adam"; string slocation = "Wrocławiu"; Console.WriteLine("Mam na imię 0 i mieszkam we 1", sname, slocation); Klasa System.Array Chyba oswoiłeś się już z myślą, że całe środowisko.net oparte jest na klasach, strukturach i wyliczeniach? Nie inaczej jest w przypadku tablic. Każda tablica w języku C# dziedziczy po klasie System.Array, która dostarcza podstawowych mechanizmów do manipulacji na elementach tablicy. To dzięki metodom tej klasy możemy pobrać ilość elementów w tablicy, posortować ją czy przeszukać. Kilka najbliższych stron zostanie przeznaczonych na opisanie podstawowych elementów tej klasy.

180 Wstęp do programowania w języku C# Jeżeli chodzi o właściwości klasy, to najważniejszą jest Length, która zwraca aktualną liczbę elementów tablicy. Ta sama klasa udostępnia również właściwość LongLength, która zwraca 64-bitową wartość określającą rozmiar wszystkich elementów w przypadku tablic wielowymiarowych. Warto również wspomnieć o właściwości Rank, która zwraca liczbę wymiarów danej tablicy: int[,] Foo = new int[3, 2] 1, 2, 1, 2, 1, 2 ; Console.WriteLine(Foo.Rank); // tablica dwuwymiarowa (wyświetli 2) Metody klasy W trakcie omawiania klasy System.Array należy wspomnieć o paru metodach, które mogą Ci się przydać przy okazji operowania na tablicach. BinarySearch() Clear() Używając algorytmu przeszukiwania binarnego, przeglądam elementy tablicy, aby znaleźć żądaną wartość. Pierwszym parametrem tej metody musi być nazwa tablicy, na której będzie ona operować. Drugim parametrem szukany element. Oto przykład użycia tej metody: string[] Foo = new string[] "Pn", "Wt", "Śr", "Czw", "Pt" ; Console.WriteLine(Array.BinarySearch(Foo, "Śr")); Metoda zwraca numer indeksu, pod jakim znajduje się szukany element, lub 1, jeżeli nic nie zostało znalezione. W zaprezentowanym przykładzie metoda zwróci wartość 2. Metoda umożliwia wyczyszczenie tablicy. W rzeczywistości ustawia każdemu elementowi wartość 0 lub null w zależności od jego typu. Metoda przyjmuje trzy parametry. Pierwszym jest nazwa tablicy, drugim numer indeksu, od którego ma rozpocząć czyszczenie, a trzecim zasięg tego procesu. Dzięki metodzie Clear() można bowiem wyczyścić określone elementy z tablicy. Poniższy przykład prezentuje czyszczenie całej zawartości: Array.Clear(Foo, 0, Foo.Length); Metoda Clear() nie zmienia rozmiaru czyszczonej tablicy. Jeżeli czyścimy tablicę, która ma powiedzmy 5 elementów, to po przeprowadzeniu tej operacji nadal będzie ich miała tyle samo. Do elementów wyczyszczonej tablicy ponownie możemy przypisywać jakieś wartości.

Rozdział 7. Tablice i kolekcje 181 Słowo kluczowe null w języku C# oznacza wartość pustą. Clone() Copy() Find() Metoda Clone() zwraca kopię tablicy, z której została wywołana np.: Bar = Foo.Clone(); Od tej pory Bar będzie posiadała takie same elementy co Foo. Ponieważ metoda Clone() zwraca dane w postaci typu object, należy dokonać rzutowania na właściwy typ. Tzn. jeżeli mamy tablicę typu string, należy na niego dokonać odpowiedniego rzutowania, co prezentuje poniższy przykład: string[] Foo = new string[] "Pn", "Wt", "Śr", "Czw", "Pt" ; // tworzenie kopii string[] Bar = (string[])foo.clone(); foreach (string element in Bar) Console.WriteLine(element); Być może lepszym sposobem na utworzenie kopii tablicy będzie zastosowanie metody Copy(). Umożliwia ona dodatkowo określenie rozmiarów kopiowania, tj. ile elementów zostanie skopiowanych. Oto przykład: string[] Foo = new string[] "Pn", "Wt", "Śr", "Czw", "Pt" ; string[] Bar = new string[foo.length]; // tworzenie kopii Array.Copy(Foo, Bar, Foo.Length); Pierwszym parametrem tej metody musi być tablica źródłowa (kopiowana), drugim tablica, do której skopiowane zostaną elementy. Trzeci parametr to oczywiście ilość kopiowanych elementów. Metoda umożliwia przeszukanie całej tablicy w celu znalezienia danego elementu. Kwalifikacja danego elementu jako znaleziony lub też nie odbywa się przy pomocy zewnętrznej metody. Oto przykładowy program: Point[] points = new Point(10, 20), new Point(100, 200), new Point(400, 500) ;

182 Wstęp do programowania w języku C# Point first = Array.Find(points, pointfind); Console.WriteLine("Found: 0, 1", first.x, first.y); Console.Read(); private static bool pointfind(point point) if (point.x % 2 == 0) return true; else return false; Na samym początku zadeklarowałem tablicę struktur Point, które będą przeszukiwane. Program wyszukuje elementów tablicy, w której element X struktury Point jest liczbą parzystą. Po znalezieniu pierwszego metoda pointfind() zwraca true i kończy swe działanie. Struktura Point zadeklarowana jest w przestrzeni nazw System.Drawing. Nie zapomnij zadeklarować jej użycia przy pomocy słowa using oraz dołączyć odpowiedniego podzespołu (System.Drawing.dll). FindAll() Jak sama nazwa wskazuje, metoda FindAll() wyszukuje wszystkie elementy, które spełniają dane kryteria poszukiwań. Oto jak powinien wyglądać program z poprzedniego listingu, jeśli ma wyszukiwać wszystkie elementy: static void Main(string[] args) Point[] points = new Point(10, 20), new Point(100, 200), new Point(400, 500) ; Point[] find = Array.FindAll(points, pointfind); foreach (Point element in find) Console.WriteLine("Found: 0, 1", element.x, element.y); Console.Read();

Rozdział 7. Tablice i kolekcje 183 FindLast() private static bool pointfind(point point) if (point.x % 2 == 0) return true; else return false; Metoda ta działa podobnie jak Find(). Jedyna różnica jest taka, że FindLast() szuka ostatniego wystąpienia danego elementu; nie kończy pracy, gdy znajdzie pierwszy element pasujący do kryteriów. GetLength() Zwraca ilość elementów w tablicy. Umożliwia działanie na tablicach wielowymiarowych. W parametrze tej metody należy podać numer wymiaru, którego ilość elementów ma być pobrana. Jeżeli mamy do czynienia z tablicą jednowymiarową, w parametrze wypisujemy cyfrę 0. Klasa System.Array udostępnia również metodę GetLongLength(), która działa analogicznie do GetLength(), z tą różnicą, iż zwraca dane w postaci liczby typu long. GetLowerBund(), GetUpperBund() GetValue() Metoda GetLowerBund() zwraca numer najmniejszego indeksu w tablicy. W przeważającej części przypadków będzie to po prostu cyfra 0. Metoda GetUpperBund() zwraca natomiast największy indeks danej tablicy. Obie metody mogą działać na tablicach wielowymiarowych; wówczas należy w parametrze podać indeks wymiaru. Przykładowe użycie: int[] Foo = 1, 2, 3, 4, 5, 6 ; Console.WriteLine("Najmniejszy indeks: 0, największy: 1", Foo.GetLowerBound(0), Foo.GetUpperBound(0)); Prawdopodobnie nie będziesz zmuszony do częstego korzystania z tej metody, zwraca ona bowiem wartość danego elementu tablicy. W parametrze tej metody musisz podać indeks elementu, tak więc jej działanie jest równoznaczne z konstrukcją: Tablica[1]; // zwraca element znajdujący się pod indeksem 1

184 Wstęp do programowania w języku C# Initialize() IndexOf() Resize() SetValue() Chcąc wykorzystać tę metodę, kod możemy zapisać następująco: int[] Foo = 1, 2, 3, 4, 5, 6 ; Console.WriteLine(Foo.GetValue(1)); We wcześniejszych fragmentach tego rozdziału pisałem o inicjalizacji tablicy. Metoda Initialize() może to ułatwić. Jej użycie powoduje przypisanie każdemu elementowi pustej wartości (czyli może to być cyfra 0 lub np. wartość null). Jej użycie jest bardzo proste, nie wymaga podawania żadnych argumentów: Foo.Initialize(); Przydatna metoda. Zwraca numer indeksu na podstawie podanej wartości elementu. Przykład użycia: string[] Foo = "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nd" ; Console.WriteLine(Array.IndexOf(Foo, "Pt")); W powyższym przykładzie na konsoli zostanie wyświetlona cyfra 4, gdyż pod tym numerem kryje się element Pt. Metoda Resize() przydaje się wówczas, gdy musimy zmienić rozmiar danej tablicy. W pierwszym jej parametrze musimy podać nazwę tablicy poprzedzoną słowem kluczowym ref oznaczającym referencję. Drugim parametrem musi być nowy rozmiar tablicy: string[] Foo = "Pn", "Wt", "Śr", "Czw", "Pt", "So", "Nd" ; Array.Resize(ref Foo, Foo.Length + 5); Metoda SetValue() umożliwia nadanie wartości dla danego elementu tablicy. Prawdopodobnie nie będziesz korzystał z niej zbyt często, gdyż to samo działanie można zrealizować przy pomocy operatora przypisania. Gdybyś jednak miał wątpliwości, co do jej użycia, poniżej prezentuję przykład: Foo.SetValue("Weekend", 9); Taki zapis oznacza przypisanie wartości Weekend pod indeks nr 9.

Rozdział 7. Tablice i kolekcje 185 Słowo kluczowe params Mechanizm tablic języka C# nie umożliwia tworzenia tablic dynamicznych, tj. o zmiennym rozmiarze. Zmiana rozmiaru tablic (ilości elementów) jest nieco problematyczna, podobnie jak usuwanie elementów. Warto jednak wspomnieć o słowie kluczowym params, używanym w połączeniu z tablicami. Konkretnie z tablicowymi parametrami metod: static void Foo(params string[] args) Słowo params, które poprzedza właściwą deklarację parametru, mówi o tym, iż liczba elementów przekazywanych do metody będzie zmienna. Oto przykład takiego programu: using System; namespace FooApp class Program static void Foo(params string[] args) for (int i = 0; i < args.length; i++) Console.Write(args[i] + " "); Console.WriteLine(); static void Main(string[] args) Foo("Adam", "Paulina"); Foo("Adam", "Paulina", "Marta"); Console.Read(); Jak widzisz, możliwe jest przekazanie dowolnej liczby parametrów do metody Foo(). Każdy parametr będzie kolejnym elementem tablicy i jest to przydatna cecha języka C#. Możliwe jest przekazywanie parametrów różnego typu. Nagłówek metody musi wyglądać wówczas tak: static void Foo(params object[] args) Taką metodę można wywołać np. tak: Foo("Adam", 10, 12.2);