Przesyłanie argumentów do metody
Przegląd zagadnień
W celu umożliwienia metodzie wykonywanie działania dla różnych wartości i
parametrów oraz przekazania wielu wartości przez metodę możemy przekazać
metodzie odpowiednie argumenty. Przy pomocy argumentów metody, lub
inaczej parametrów metody, tworzymy interfejs, przy pomocy którego metoda
wymienia informację (dane) z pozostałymi częściami programu. W poprzednim
rozdziale do wymiany informacji między metodami były używane zmienne
współdzielone, w innych językach natomiast można używać tzw. zmiennych
globalnych - zmiennych zadeklarowanych poza metodą i poza klasą. Wymiana
informacji między metodami z użyciem zmiennych współdzielonych w
porównaniu do przesyłania argumentów do metody, generuje mniej czytelny
kod. Sam mechanizm przesyłania argumentów do metody wymusza na
programiście nadanie odpowiednich wartości parametrom, od których jest
zależne działanie metody. Dzięki temu można uniknąć licznych błędów
logicznych. Poszczególne metody stają się niezależnymi jednostkami.
Po skończeniu tego rozdziału studenci będą potrafić:
Definiować metody do których przesyłane są argumenty.
Wywoływać metody z parametrami.
Wybierać odpowiedni sposób przesyłania argumentów.
Przeciążyć nazwę metody.
Pobierać argumenty z linii wywołania programu.
Deklaracja i wywołanie metod z parametrami
Listę parametrów które mają być przekazane do metody, umieszczamy
wewnątrz nawiasów okrągłych tuż za nazwą metody. Każdy parametr musi
mieć określony typ i nazwę. Również gdy kilka parametrów ma ten sam typ,
każdemu argumentowi trzeba oddzielnie określić typ. Poszczególne parametry
oddzielamy przecinkiem. Wszystkie argumenty zdefiniowane wewnątrz
nawiasów okrągłych nazywamy parametrami formalnymi metody. Nazwy
parametrów są lokalne dla danej metody i są dostępne w całym "ciele" metody.
Następujące przykłady pokazują jak definiować metodę z parametrami:
1. Metoda przyjmująca dwa argumenty typu string
static void Powitanie(string imie, string nazwisko)
{
Console.WriteLine("Witam Pana(ią) {0} {1}",
imie, nazwisko);
}
2.
Metoda przyjmująca jeden parametr typu double
static double Szescian(double x)
{
return x*x*x;
}
Wywołując metodę z parametrami, każdemu jej argumentowi musimy
dostarczyć wartość odpowiedniego typu. Wartości te umieszczamy w
nawiasach okrągłych po nazwie metody i są one przypisywane argumentom na
podstawie kolejności występowania. Poszczególne wartości oddzielamy
przecinkiem. I tak, aby wywołać metodę Powitanie z przykładu powyżej
należy napisać:
Powitanie("Kubuś", "Puchatek");
Argumentowi o nazwie imie zostanie nadana wartość Kubuś, a argumentowi
nazwisko wartość Puchatek. Wykonanie powyższej linijki spowoduje
pojawienie się na ekranie napisu:
Witam Pana(ią) Kubuś Puchatek
Argumenty (wartości, zmienne) umieszczone w nawiasach okrągłych w miejscu
wywołania metody nazywamy parametrami aktualnymi metody.
Sposoby przesyłania argumentów do metody
W języku C# mamy trzy sposoby przesyłania argumentów do metody:
przez wartość
przez referencję
jako parametr wyjściowy
Przesyłanie parametru przez wartość.
Przesyłanie przez wartość jest domyślnym mechanizmem przesyłania
argumentów do metody. Argument jest traktowany jako parametr wejściowy.
Przesyłanie przez wartość definiujemy przez podanie typu argumentu i jego
nazwy, czyli tak jak to było pokazane wcześniej w tym rozdziale. W miejscu
wywołania metody, każdy parametr formalny przesyłany przez wartość
reprezentuje nowo utworzoną zmienną lokalną. Zmienne te inicjalizowane są
wartościami odpowiednich parametrów aktualnych.
Mechanizm przesyłania przez wartość charakteryzuje się następującymi
właściwościami:
Argumentem aktualnym może być dowolne wyrażenie odpowiedniego typu.
Metodę
static void f(int x){...}
można wywołać
f(2*4);
lub
f(y);
gdzie y jest zmienną typu int.
Jeżeli jako parametr aktualny przesyłamy zmienną, musi być ona wcześniej
zainicjalizowana.
int y;
f(y);
//błąd - niezainicjalizowana zmienna
Wewnątrz metody parametry przesyłane przez wartość traktowane są jako
zmienne zainicjalizowane.
Zmiana wartości parametru formalnego nie wpływa na wartość parametru
aktualnego.
static void Zwieksz(int x){ x++;}
...
int y = 10;
Zwieksz(y);
Console.Write(y);
Na ekranie pojawi się 10, a nie 11.
Przesyłanie parametru przez referencję.
Argument przesyłany przez referencję traktowany jest, zarówno jako parametr
wejściowy jak i parametr wyjściowy. Przesyłanie przez referencję definiujemy
przez dodanie przed nazwą typu parametru słowa ref, dla każdego argumentu
przesyłanego przez referencję.
static void PrzezReferencje(ref int x,ref int y){...}
W miejscu wywołania metody, dla parametrów przesyłanych przez referencję,
nie jest tworzona nowa zmienna. Parametr formalny reprezentuje ten sam
obszar pamięci, tą samą zmienną, co parametr aktualny. W celu wywołania
metody, przed każdym argumentem przesyłanym przez referencję musimy
postawić słowa ref.
PrzezReferencje(ref akt1,ref akt2);
Przy powyższym wywołaniu, zmienna akt1 wewnątrz metody
PrzezReferencje
będzie się nazywać ("będziemy przezywać") x, a
zmienna akt2 będzie się nazywać y.
Mechanizm przesyłania przez referencję charakteryzuje się następującymi
właściwościami:
Argumentem aktualnym może być tylko zmienna odpowiedniego typu.
Metodę
static void f(ref int x){...}
można wywołać
f(ref y);
gdzie y jest zmienną typu int.
Wywołanie
f(ref 2*4);
spowoduje błąd kompilacji
Zmienna przesyłana przez referencję do metody musi być wcześniej
zainicjalizowana.
int y;
f(ref y); //błąd - niezainicjalizowana zmienna
Wewnątrz metody parametry przesyłane przez referencję traktowane są jako
zmienne zainicjalizowane.
Zmiana wartości parametru formalnego wpływa na wartość parametru
aktualnego.
static void Zwieksz(ref int x){ x++;}
...
int y = 10;
Zwieksz(ref y);
Console.Write(y);
Na ekranie pojawi się 11, a nie 10.
Przesyłanie parametru jako parametr wyjściowy.
Argument przesyłany jako parametr wyjściowy traktowany jest jako parametr
wyjściowy. Przesyłanie argumentu jako parametr wyjściowy definiujemy przez
dodanie przed nazwą typu parametru słowa out, dla każdego argumentu
przesyłanego jako parametr wyjściowy.
static void JakoWyjsciowy(out int x,out int y){...}
W miejscu wywołania metody, dla parametrów przesyłanych jako parametr
wyjściowy, podobnie jak w przypadku parametrów przesyłanych przez
referencję, nie jest tworzona nowa zmienna. Parametr formalny reprezentuje ten
sam obszar pamięci, tą samą zmienną, co parametr aktualny. W celu wywołania
metody, przed każdym argumentem przesyłanym jako parametr wyjściowy
musimy postawić słowa out.
JakoWyjsciowy(out akt1,out akt2);
Przy powyższym wywołaniu, zmienna akt1 wewnątrz metody
JakoWyjsciowy będzie się nazywać ("będziemy przezywać") x, a zmienna
akt2
będzie się nazywać y.
Mechanizm przesyłania argumentu jako parametr wyjściowy charakteryzuje się
następującymi właściwościami:
Argumentem aktualnym może być tylko zmienna odpowiedniego typu.
Metodę
static void f(out int x){...}
można wywołać
f(out y);
gdzie y jest zmienną typu int.
Wywołanie
f(out 2*4);
spowoduje błąd kompilacji.
Zmienna przesyłana jako parametr wyjściowy do metody, nie musi być
wcześniej zainicjalizowana.
int y;
f(out y);
//Wszystko OK
Wewnątrz metody parametry przesyłane przez referencję traktowane są jako
zmienne niezainicjalizowane.
static void f(out int x)
{
...int y = x; //błąd, pobieramy wartość
//niezainicjalizowanej zmiennej
}
Przed wyjściem z metody każdy parametr przesyłany jako parametr
wyjściowy musi mieć nadaną wartość.
Zmiana wartości parametru formalnego wpływa na wartość parametru
aktualnego.
static void Zmien(out int x){ x=11;}
...
int y = 10;
Zmien(out y);
Console.Write(y);
Na ekranie pojawi się 11, a nie 10.
Przykłady demonstrujące różne sposoby przesyłania argumentów do metody
można znaleźć w programach RodzajePrzesylan i
RownanieKwadratowe
, które stanowią część rozwiązania
Kurs\Demo\Modul9\Modul9.sln, gdzie Kurs jest katalogiem, gdzie
skopiowano pliki kursu.
Argumenty typów referencyjnych
Przesyłanie argumentu przez wartość powoduje utworzenie nowej zmiennej i
skopiowanie zawartości parametru aktualnego do tej zmiennej. W przypadku
przesłania zmiennej typu referencyjnego spowoduje to, że nowo utworzona
zmienna będzie się odwoływać do tego samego obiektu, co zmienna która
została przesłana jako parametr aktualny. Zmiany obiektu wewnątrz metody
przy pomocy nowo utworzonej zmiennej, będą widoczne również na zewnątrz
metody. Rozważmy to na przykładzie przesyłania tablic do metody - tablice są
obiektami, typem referencyjnym.
static void M1(int [] t)
{
t[0] = 1;
}
...
int [] tab = {10,11,12};
M1(tab);
Console.Write(tab[0]);
W wyniku działania powyższego kodu na ekranie powinno pojawić się:
1
Dzieje się tak, ponieważ zmienna tablicowa t oraz zmienna tablicowa tab
odwołują się do tego samego obiektu.
Rozważmy jeszcze jeden przykład:
static void M2(int [] t)
{
t = new int[3];
t[0] = 1
}
...
int [] tab = {10,11,12};
M2(tab);
Console.Write(tab[0]);
W wyniku działania powyższego kodu na ekranie powinno pojawić się:
10
Przykład powyższy różni się tym od poprzedniego, że w momencie ustawiania
wartości pierwszego elementu tablicy w metodzie M2, zmienna t odwołuje się
już do innego obiektu tablicy. Linijka
t = new int[3];
powoduje zmianę wartości zmiennej tablicowe, a nie obiektu, a przy
przesyłaniu przez wartość, co już wspominano wcześniej, zmiany wartości
parametru formalnego nie są przenoszone na parametr aktualny.
W przypadku gdyby parametr był przesyłany przez referencję lub jako parametr
wyjściowy, zmiana wartości zmienne, którą reprezentuje parametr formalny,
pociąga za sobą zmianę w parametrze aktualnym.
Poniższy kod
static void M3(ref int [] t)
{
t = new int[3];
t[0] = 1;
}
...
int [] tab = {10,11,12};
M3(ref tab);
Console.Write(tab[0]);
spowoduje więc, że na ekranie pojawi się:
1
Przesyłanie dowolnej liczby argumentów
W języku C# istnieje mechanizm przesyłania dowolnej liczby argumentów do
metody. Wykorzystywany jest choćby w metodzie Write, klasy Console.
Do oznaczenia, że metoda może przyjąć dowolną liczbę parametrów, używamy
słowa kluczowego params w połączeniu z deklaracją argumentu typu
jednowymiarowej tablicy np.:
static double Suma(params double [] skladniki)
{
double suma = 0;
foreach(double x in skladniki)
suma += x;
return suma;
}
Powyższą metodę możemy wywołać na dwa sposoby:
1.
Przesyłając jako argument tablicę
double [] t = {1.3,2.4,3.1,4.3};
double x = Suma(t);
2. Przesyłając jako argument listę elementów. Lista może być również pusta.
Jako element może występować dowolne wyrażenie, którego typ jest
zgodny z typem podstawowym tablicy występującej po słowie params.
double y = Suma(1.3,2.4,3.1,4.3);
W przypadku powyższego wywołania, automatycznie tworzony jest obiekt
tablicy.
W przypadku definiowania metody z dowolną liczbą parametrów należy
pamiętać:
Słowa kluczowego params używamy w połączeniu z deklaracją argumentu
typu jednowymiarowej tablicy.
Argument z modyfikatorem params musi być definiowany na końcu listy
parametrów.
Może być tylko jeden argument z modyfikatorem params dla pojedynczej
metody.
Argument z modyfikatorem params zawsze przesyłamy przez wartość.
Przeciążenie nazwy metody
W poprzednim rozdziale wspominano, że wyjątkiem od reguły tworzenia
unikalnych nazw, jest możliwość nadania takiej samej nazwy zmiennej
współdzielonej i zmiennej lokalnej. Drugim wyjątkiem od reguły, że w jednym
bloku kodu nie może występować dwóch takich samych identyfikatorów, jest
mechanizm zwany przeciążeniem nazwy metody. Przeciążenie nazwy metody
lub krócej przeciążenie metody, polega na nadaniu kilku metodom jednej klasy
tej samej nazwy. Jest to możliwe, ponieważ w trakcie kompilacji nazwa metody
jest rozszerzana o typ argumentów przekazywanych do metody. Metody
należące do jednej klasy muszą różnić się sygnaturą. Na sygnaturę metody
składają się:
nazwa metody
typ parametrów
ilość parametrów
modyfikator typu parametru
Uwaga:
Modyfikatory out i ref nie są rozróżnialne przez kompilator.
Do sygnatury metody nie należą:
typ wartości zwracanej przez metodę
nazwy parametrów metody
Dopuszczalna jest więc następująca definicja klasy (przykład przeciążenia
nazwy metody):
class MetodyPrzeciazone
{
static void Nazwa(){...}
static void Nazwa(int i){...}
static void Nazwa(int i,int y){...}
static void Nazwa(ref int i){...}
static void Nazwa(double x){...}
static void Nazwa(double x,int i){...}
static void Nazwa(int i,double x){...}
}
Niedopuszczalne są następujące pary metod w jednej klasie:
static void Nazwa(){...}
static int Nazwa(){...}
Różnią się tylko typem wartości zwracanej przez metodę
static void Nazwa(double a,double b){...}
static void Nazwa(double x,double y){...}
Różnią się tylko nazwą parametrów
static void Nazwa(ref double a){...}
static void Nazwa(out double x){...}
Modyfikatory out i ref nie są rozróżnialne przez kompilator.
Napotykając wywołanie metody, której nazwa jest przeciążona, kompilator
wybiera odpowiednią metodę na podstawie typu argumentów aktualnych.
Nie można nadawać takich samych nazw metodzie i innym składnikom klasy:
zmiennym współdzielonym, nazwom typów zdefiniowanych w klasie lub
stałym nazwanym.
Stosowanie jednakowych nazw dla kilku metod tej samej klasy powinno być
używane bardzo roztropnie, gdyż może powodować trudności z utrzymaniem
kodu.
Argument metody Main
Uruchamiając program, można przekazać do niego pewną informację -
argumenty w wierszu wywołania. W celu uruchomienia programu z
argumentami w linii poleceń wydajemy następującą komendę.
NazwaProgramu arg1 arg2<ENTER>
W środowisku Visual Studio można również ustawić argumenty linii poleceń.
Ustawia się je w oknie Właściwości Projektu (Menu Project/Nazwa
Projektu Properties...) na zakładce Debug, w polu edycyjnym Command line
arguments:.
Argumenty podane w wierszu wywołania programu, są przekazywane do
programu za pomocą tablicy napisów (string), która jest parametrem metody
Main.
Chcąc przetwarzać argumenty linii poleceń musimy jako punkt startowy
naszego programu użyć metody Main z argumentem.
static int Main(string[] args)
lub
static void Main(string[] args)
Poniższy program wypisuje na ekranie wszystkie argumenty, które zostały
podane w wierszu wywołania.
static int Main(string[] args)
{
foreach (string s in args)
Console.WriteLine(s);
Console.ReadKey();
return 0;
}
Przykład demonstrujący użycie argumentów linii wywołania można znaleźć w
programie ArgumentyMain, który stanowi część rozwiązania
Kurs\Demo\Modul9\Modul9.sln, gdzie Kurs jest katalogiem, gdzie
skopiowano pliki kursu.
Pytania sprawdzające
1. Wymień trzy sposoby przesyłania parametrów do metody.
Odp.
Argumenty do metody możemy przesyłać:
a. Przez wartość.
b. Przez referencję.
c. Jako parametr wyjściowy
2. Co należy do sygnatury metody?
Odp.
Do sygnatury metody należ: nazwa metody, typ parametrów, ilość
parametrów, modyfikator typu parametru
3. Zaznacz prawidłowe formy przeciążenia metody:
static double Dodaj(int x, double y)
a. static double Dodaj(int a, double b)
b. static double Dodaj(double x, double y)
c. static double Dodaj()
d. static double Dodaj(ref int x,out double y)
e. static int Dodaj(int x, double y)
Odp.
Prawidłowe odpowiedzi to: b, c, d.
4. Co zostanie wypisane na ekranie?
static void DodajJeden(double [] t){
for(int i=0; i<t.Lenght;i++)
t[i]++;
}
static void Main(){
double [] tab = {1,2,3,4};
DodajJeden(tab);
foreach(double d in tab)
Console.Write("{0}, ",d);
}
Odp.
Na ekranie zostanie wypisane: 2, 3, 4, 5
5.
Jaki popełniono błąd w poniższym kodzie?
static void Wypisz(out double d){
Console.Write("d = {0}",d)
}
Odp.
W powyższym kodzie pobierany wartość niezainicjalizowanej zmiennej.
Argumenty przesyłane jako parametr wyjściowy są traktowane przez
kompilator jako niezainicjalizowane.
Laboratorium
Ćwiczenie 1:
Napisz dwie metody obliczające wartość wielomianu metodą Hornera. Pierwsza
metoda oblicza tylko wartość wielomianu dla wartości x podanej jako argument
metody i zwraca ją do programu. Współczynniki wielomianu przesyłane są jako
parametr z modyfikatorem params (dowolna ilość argumentów). Druga metoda
dodatkowo oblicza stopień wielomianu - argument przesyłany jako parametr
wyjściowy.
W metodzie Hornera stosuje się następujące przekształcenie :
a
0
x
n
+ a
1
x
n-1
+ a
2
x
n-2
+... +a
n-1
x
1
+ a
n
= (...((a
0
x + a
1
)*x + a
2
)*x+...+a
n-1
)*x + a
n
W wyniku zastosowania powyższego przekształcenia zmniejszamy ilość
wykonywanych działań i zwiększamy dokładność obliczonego wyniku.
1. Uruchom Visual Studio
Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005.
2. Utwórz nowy projekt
a. Z menu File wybierz New/Project...
b. W oknie dialogowym New Project określ następujące właściwości:
i. typu projektu: Visual C#/Windows
ii. szablon: Console Application
iii. lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\
iv. nazwa projektu: Wielomian.
v. nazwa rozwiązania: Lab9
3. Wewnątrz klasy Program utwórz metodę Wielomian, która zwraca
wartość wielomianu dla wartości x podanej jako argument metody.
Parametry wielomianu są przekazywane jako argument z modyfikatorem
params.
static double Wielomian(double x,params double[] a)
{
double suma = a[0];
for (int i = 1; i < a.Length; i++)
{
suma = suma * x + a[i];
}
return suma;
}
4. Do klasy Program dodaj drugą metodę Wielomian, W odróżnieniu od
metody zdefiniowanej w punkcie poprzednim, metoda ta posiada dodatkowy
argument przesyłany jako parametr wyjściowy w którym zawarta jest
informacja o stopniu wielomianu.
static double Wielomian(double x,
out double stopien, params double[] a)
{
stopien = a.Length - 1;
for (int i = 0; i < a.Length - 1; i++)
{
if (a[i] != 0)
break;
stopien--;
}
return Wielomian(x, a);
}
5. Wewnątrz metody Main napisz następujący kod testujący metody
zdefiniowane w poprzednich krokach:
static void Main(string[] args)
{
double stopienWielomianu;
double[] wspolczynnikiWielomianu={1, 1, 0, 1};
Console.WriteLine("Wartość wielomianu obliczona
¬pierwszą metodą {0}",
Wielomian(1,wspolczynnikiWielomianu));
Console.WriteLine("Wartość wielomianu obliczona
¬drugą metodą {0}",
Wielomian(1,out stopienWielomianu,
wspolczynnikiWielomianu));
Console.WriteLine("Stopień wielomianu: {0}",
stopienWielomianu);
Console.WriteLine("\nInny sposób przekazania
¬ wartości współczynników wielomianu
¬do metody");
Console.WriteLine("Wartość wielomianu obliczona
¬pierwszą metodą {0}",
Wielomian(1, 0,1,2));
Console.WriteLine("Wartość wielomianu obliczona
¬drugą metodą {0}",
Wielomian(1, out stopienWielomianu,
0, 1, 2));
Console.WriteLine("Stopień wielomianu: {0}",
stopienWielomianu);
Console.ReadKey();
}
6. Skompiluj i uruchom program.
Ćwiczenie 2:
Napisz dwie metody sortujące tablice. Pierwsza niech sortuje tablice liczb
rzeczywistych. Druga metoda będzie sortowała tablice napisów. Do porównania
dwóch napisów użyj metody String.Compare(string s1,string
s2). Metoda ta zwraca wartość mniejszą od zera, gdy s1 jest "mniejsze" od
s2
, wartość zero gdy oba napisy są jednakowe oraz wartość większą od zera
gdy s1 jest później w kolejności alfabetycznej niż s2. Więcej na temat metody
Compare można znaleźć w MSDN Library.
Do sortowania użyj algorytmu sortowania przez kopcowanie (heap sort).
Podstawą tej metody jest tworzenie tzw. kopca. Kopiec definiujemy jako ciąg
elementów tablicy a[p], a[p+1], ..., a[q] spełniających następujące warunki:
a[i]>=a[2i+1]
a[i]>=a[2i+2]
dla wszystkich i = p, ..., (q-1)/2
Schemat blokowy metody sortowanie przez kopcowanie znajduje się w pliku
Kurs\Lab\Modul9\Start\Przezkopcowanie.gif, a metody
Przesiew
, która jest wykorzystywana w metodzie sortującej, w pliku
Kurs\Lab\Modul9\Start\Przesiew.gif, gdzie Kurs jest
katalogiem gdzie skopiowano pliki kursu.
1. Dodaj do bieżącego rozwiązania nowy projekt
a. Z menu File wybierz Add/New Project...
b. W oknie dialogowym Add New Project określ następujące
właściwości:
i. typu projektu: Visual C#/Windows
ii. szablon: Console Application
iii. nazwa projektu: SortowanieStogowe.
2. Uczyń nowo utworzony projekt projektem startowym
a. Zaznacz projekt SortowanieStogowe w okienku Solution Explorer i z
menu kontekstowego wybierz Set as StartUp Project.
albo, gdy rozpoczynasz laboratorium od tego ćwiczenia
1. Uruchom Visual Studio
Naciśnij przycisk Start systemu Windows, wybierz Wszystkie Programy
następnie Microsoft Visual Studio 2005/ Microsoft Visual Studio 2005.
2. Utwórz nowy projekt
a. Z menu File wybierz New/Project...
b. W oknie dialogowym New Project określ następujące właściwości:
i. typu projektu: Visual C#/Windows
ii. szablon: Console Application
iii. lokalizacja: Moje Dokumenty\Visual Studio 2005\Projects\
iv. nazwa projektu: SortowanieStogowe.
v. nazwa rozwiązania: Lab9
3. Do klasy Program dodaj metodę Przesiewaj, której działanie jest
określone przez schemat blokowy w pliku Przesiew.gif. Typ double
przyjmij jako typ podstawowy tablicy.
static void Przesiewaj(double[] tab,uint l,uint p)
{
uint i = l,j = 2*i+1;
double x = tab[i];
while(j<=p)
{
if(j<p)
if(tab[j]<tab[j+1])
j++;
if(tab[j]<x)
break;
tab[i] = tab[j];
i=j;
j=2*i+1;
}
if(i != l)
tab[i] = x;
}
4. Do klasy Program dodaj metodę Przesiewaj, której działanie jest
określone przez schemat blokowy w pliku Przesiew.gif. Typ string
przyjmij jako typ podstawowy tablicy. Do porównania elementów tablicy,
zmiast operatora mniejszości <, używaj metodę Comapre klasy string.
static void Przesiewaj(string[] tab,uint l,uint p)
{
uint i = l, j = 2 * i + 1;
string x = tab[i];
while (j <= p)
{
if (j < p)
if (string.Compare(tab[j],tab[j + 1])<0)
j++;
if (string.Compare(tab[j], x)<0)
break;
tab[i] = tab[j];
i = j;
j = 2 * i + 1;
}
if (i != l)
tab[i] = x;
}
5. Do klasy Program dodaj metodę Sortuj, której działanie jest określone
przez schemat blokowy w pliku Przezkopcowanie.gif. Typ double
przyjmij jako typ podstawowy tablicy.
static void Sortuj(double [] tab)
{
uint l = (uint)tab.Length/2,
p=(uint)tab.Length-1;
double x;
while(l>0)
{
l--;
Przesiewaj(tab,l,p);
}
while(p>0)
{
x=tab[0];
tab[0] = tab[p];
tab[p] = x;
p--;
Przesiewaj(tab,0,p);
}
}
6. Do klasy Program dodaj metodę Sortuj, której działanie jest określone
przez schemat blokowy w pliku Przezkopcowanie.gif. Typ string
przyjmij jako typ podstawowy tablicy.
static void Sortuj(string [] tab)
{
uint l = (uint)tab.Length / 2,
p = (uint)tab.Length - 1;
string x;
while (l > 0)
{
l--;
Przesiewaj(tab, l, p);
}
while (p > 0)
{
x = tab[0];
tab[0] = tab[p];
tab[p] = x;
p--;
Przesiewaj(tab, 0, p);
}
}
7. Wewnątrz metody Main napisz kod testujący obie metody Sortuj.
static void Main(string[] args)
{
double[] tab = { 2.3, 3, 45, 12.3, 4.3, 7.2 };
Console.WriteLine("Tablica liczb rzeczywistych
¬przed sortowaniem");
foreach (double d in tab)
Console.Write("{0}; ", d);
Sortuj(tab);
Console.WriteLine("\nTablica liczb
¬rzeczywistych po sortowanu");
foreach (double d in tab)
Console.Write("{0}; ", d);
Console.WriteLine("\n\n*****************\n");
string[] napisy = { "szafa", "Szwecja",
"szalik", "siano", "stóg",
"szampan", "Słowacja" };
Console.WriteLine("Tablica wyrazów przed
¬sortowaniem");
foreach (string s in napisy)
Console.Write("{0}; ", s);
Sortuj(napisy);
Console.WriteLine("\nTablica wyrazów po
¬sortowanu");
foreach (string s in napisy)
Console.Write("{0}; ", s);
Console.ReadKey();
}
8. Skompiluj i uruchom program.