Creativity | Reliability | Innovations

C# | Tworzenie tabliczki mnożenia i rysowanie figur geometrycznych

Nieodłączną cechą wszystkich języków programowania jest wykorzystanie pętli. Służą nam one przede wszystkim do wykonywania n-operacji, które normalnie musielibyśmy wykonywać ręcznie – o ile w niewielkich projektach, w których mamy do wykonania tylko kilka podobnych operacji nie jest to jeszcze uciążliwe, to przy projektach wymagających wykonania zbioru instrukcji kilka tysięcy razy, staje się to już praktycznie niemożliwe. Umiejętnie wykorzystywane pętle for, while, do..while itp. w znacznym stopniu odciąża nas od nadmiaru pracy, dodatkowo przyspieszając funkcjonowanie całego projektu programistycznego.

1. Podstawowa konstrukcja pętli

Funkcjonowanie pętli opiera się na banalnie prostym założeniu – wykonuj daną operację dopóki warunek pętli będzie spełniony – w przeciwnym wypadku zakończ działanie pętli i wykonaj dalszą część kodu programu. Innymi słowy wykorzystujemy zmienną pomocniczą (zwaną również sterującą, kontrolną), za pomocą której określamy, ile razy dana pętla ma się wykonać. Prosty przykład:

for(int i = 0; i < 10; i++) {
  Console.Write("#");
}

Wykonanie powyższego kodu spowoduje, że program wyświetli nam 10 razy znak „#”. Pojawi się pewnie pytanie „dlaczego zaczynamy od 0?”. Odpowiedź jest bardzo prozaiczna – kwestie praktyczne. Wykorzystując pętle do wypełniania tablic koniecznie musimy uważać na to, aby nie wyjść poza zarezerwowany obszar tablicy w pamięci operacyjnej – jeżeli do tego dojdzie, mówimy wtedy o tzw. przepełnieniu bufora, lub, w przypadku stosów, o przepełnieniu stosu (z ang. stack overflow). Indeksacja tablic w większości języków programowania ZAWSZE zaczyna się od liczby 0. Jeżeli tworzymy 10-elementową tablicę liczb całkowitych o nazwie arr, to pierwszy element tablicy będzie na pozycji 0, a ostatni na pozycji 9. Dlatego przyjęło się, że iterację pętli także rozpoczynamy od liczby 0.

int[] arr = new int[10];
for(int i = 0; i < arr.Length; i++) {
  arr[i] = i + 1;
  Console.Write("arr[{0}] = {1}", i, arr[i]);
}

W tym wypadku sprawiliśmy, że kolejne elementy przyjmowały wartości o 1 większe niż ich numer indeksu. Możemy w ten sposób sprawdzić, że faktycznie tablica ma 10 elementów, tyle że ich numeracja logiczna jest o 1 mniejsza i zaczyna się od 0.

2. Rysowanie prostych figur geometrycznych

Rysowanie figur geometrycznych w konsoli opiera się na umiejętnym wykorzystaniu pętli. W tym celu wykorzystujemy co najmniej dwie zagnieżdżone pętle for – pierwsza pętla odpowiedzialna jest za sterowanie wyświetlaniem poszczególnych wierszy, a druga za wyświetlanie kolumn. Jeżeli chcemy narysować prostokąt o wymiarach 20×12, musimy tak skonstruować pętle for, aby jedna z nich wykonała się 20 razy, a druga 12, adekwatnie do wymiarów jakie podamy w programie, czy to wewnątrz kodu, czy to z klawiatury. Pamiętajmy, że zewnętrzna pętla steruje wierszami, także jeżeli zależy nam na prostokącie o szerokości 20, to wartość tą musimy podać wewnątrz drugiej pętli.

for(int i = 0; i < 12; i++) {
  for(int j = 0; j < 20; j++) {
    Console.Write("#");
  }
  Console.WriteLine();
}
Wynik działania

Sprawa komplikuje się w momencie, gdy chcemy stworzyć jedynie obrys danej figury – nie obejdzie się wtedy bez zagnieżdżenia dodatkowej instrukcji warunkowej if. Rozumowanie w takim wypadku jest takie – Dla pierwszego i ostatniego wiersza drukuj wszystkie znaki „#”, a dla wszystkich pozostałych tylko pierwszy i ostatni znak „#”, a pomiędzy nimi wstaw znak spacji. Brzmi groźnie, ale rozwiązanie tego problemu jest bardzo proste.

for (int i = 0; i < 12; i++)
{
    for (int j = 0; j < 20; j++)
    {
        if (i == 0 || i == 11 || j == 0 || j == 19)
        {
            Console.Write("#");
        }
        else
        {
            Console.Write(" ");
        }
    }
    Console.WriteLine();
}
Wynik działania

Jak możemy zauważyć, wystarczy sprawne operowanie i łączenie pętli for z instrukcją warunkową, aby osiągnąć pożądane rezultaty. W dalszej części rozpatrzymy nieco trudniejszy przykład z rysowaniem trójkąta prostokątnego w oparciu o wcześniejsze przykłady.

3. Rysowanie trójkątów prostokątnych

W omawianym przykładzie mamy za zadanie narysować cztery trójkąty prostokątne, z których każdy musi być zwrócony w innym kierunku. Aby to osiągnąć, musimy wprowadzić dodatkową zmienną pomocniczą – nazwijmy ją literą e. Będzie ona odpowiedzialna za ilość wyświetlanych znaków „#” w danym wierszu. Jako że wykorzystujemy ją przy rysowaniu każdego trójkąta, musimy pamiętać o jej resetowaniu do wartości 1 po każdej głównej pętli.

int e = 1;
for (int i = 0; i < 10; i++) // Trójkąt 1
{
  for (int j = 0; j < e; j++)
  {
    Console.Write("*");
  }
  Console.WriteLine();
  e += 2;
}
e = 1;
Console.WriteLine();
for (int i = 0; i < 10; i++) // Trójkąt 2
{
  for (int j = 20; j > e; j--)
  {
    Console.Write("*");
  }
  Console.WriteLine();
  e += 2;
}
e = 1;
Console.WriteLine();
for (int i = 0; i < 10; i++) // Trójkąt 3
{
  for (int k = 20; k > e; k--)
  {
    Console.Write(" ");
  }
  for (int j = 0; j < e; j++)
  {
    Console.Write("*");
  }
  Console.WriteLine();
  e += 2;
}
e = 1;
Console.WriteLine();
for (int i = 0; i < 10; i++) // Trójkąt 4
{
  for (int k = 0; k < e; k++)
  {
    Console.Write(" ");
  }
  for (int j = 20; j > e; j--)
  {
    Console.Write("*");
  }
  Console.WriteLine();
  e +=2;
}
Wynik działania

4. Tabliczka mnożenia

Tworzenie tabliczki mnożenia można rozwiązać na dwa sposoby – bezpośrednio odwołując się do wartości zmiennych i i j, jak również za pomocą tablicy liczb całkowitych. Wykorzystując drugą metodę po wygenerowaniu tabliczki mnożenia możemy się później odwołać do jej poszczególnych elementów, bez konieczności ponownego jej generowania. A więc zaczynamy.

Metoda 1
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        Console.Write("{0}\t", (i + 1) * (j + 1));
    }
    Console.WriteLine();
}

Metoda 2
int[,] tabliczka = new int[10, 10];
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        tabliczka[i, j] = (i + 1) * (j + 1);
        Console.Write(tabliczka[i, j] + "\t");
    }
    Console.WriteLine();
}

Jak widzimy, efekt działania obydwu rozwiązań pod względem wizualnym jest identyczny. Różnica polega na tym, że korzystając z tablicy możemy się później odwołać do jej zawartości w celu przeprowadzania różnego typu obliczeń na jej elementach.

5. Podsumowanie

W tym materiale poznaliśmy podstawową konstrukcję i zastosowanie pętli w programowaniu.  Poruszyliśmy temat zagnieżdżania pętli oraz instrukcji warunkowych w celu modyfikacji generowanych struktur, m.in. figur geometrycznych czy tabliczki mnożenia. W razie jakichkolwiek pytań odnośnie poruszonych zagadnień, zachęcam do skorzystania z sekcji komentarzy.

0 0 votes
Article Rating
Subscribe
Powiadom o

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.

0 komentarzy
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x