Statyczne tablice wielowymiarowe
Typ tablicowy niekoniecznie musi być jednowymiarowy. Najprostszym przykładem tablicy wielowymiarowej jest tablica dwuwymiarowa. Jej deklaracja oprócz typu zmiennych przechowywanych w tablicy wymaga podania rozmiaru w każdym wymiarze.
Przykładem tablicy dwuwymiarowej jest tabela określonej ilości wierszy i dwóch kolumnach.
Cel: Napisz aplikację, która będzie przechowywać losowe wartości liczbowe w statycznej tablicy dwuwymiarowej. Utwórz funkcje o argumencie opartym na tablicy dwuwymiarowej wykonujące podstawowe działania matematyczne.
Krok 1. Układ komponentów
- GroupBox- sztuk 1
- TextBox- sztuk 3
- Label- sztuk 2
- Button- sztuk 5
Jedną z kontrolek TextBox przeznacz na wyświetlanie wyników. Tej kontrolce zmień wartość Multiline na True
Wybierz możliwość przewijania zawartości kontrolki poprzez ustawienie ScrollBars na Vertical
Proponowany układ komponentów przedstawia poniższa ilustracja
Krok 2. Deklaracja zmiennych
Deklaracja zmiennej dwuwymiarowej tablicy statycznej przechowującej typ całkowity ma postać
Wskazówka:
int[,] t;
Uwaga. Odpowiedni rozmiar przypiszemy w dalszej części kodu.
Deklarujemy zmienne lokalne wewnątrz klasy Form
Wskazówka:
public partial class Form1 : Form
{
int[,] t;
int rozmiar = 0, zakres =100;
Random los = new Random();
public Form1()
{
InitializeComponent();
}
Krok 3. Losowe elementy tablicy dwuwymiarowej
W zdarzeniu Click kontrolki button1 wykonamy przypisanie pamięci (rozmiaru) tworzonej tablicy. Wylosujemy kolejne elementy, wstawimy je do tablicy i pokażemy w komponencie TextBox.
Proponowany kod realizujący to zadanie ma postać
Wskazówka:
private void button1_Click(object sender, EventArgs e)
{
rozmiar = Convert.ToInt16(textBox1.Text);
zakres = Convert.ToInt16(textBox2.Text);
textBox3.Clear();
t = new int [rozmiar,2];
for(int i = 0; i < rozmiar; i++)
{
t[i, 0] = los.Next(zakres);
t[i, 1] = los.Next(zakres);
textBox3.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString()
+ ";" + t[i, 1].ToString()
+Environment.NewLine);
}
}
Skompiluj program i sprawdź efekt działania. Prawidłowo działająca aplikacja zwróci zawartość tablicy
Krok 4. Deklarujemy funkcję wykonującą działania na elementach tablicy
Podany kod funkcji jest przykładem jak należy podawać argument typu tablicowego do ciała funkcji. Funkcja nie zwraca wyniku. Efekt działań zapisywany jest do drugiego argumentu, który jest typem TextBox
Wskazówka:
void dodawanie(int[,] t,TextBox tb)
{
tb.Clear();
for(int i = 0; i < t.GetLength(0); i++)
{
tb.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString() + "+"
+ t[i, 1].ToString() +"="
+(t[i,0]+t[i,1]).ToString()
+ Environment.NewLine);
}
}
Skompiluj program i sprawdź czy nie ma błędów.
Krok 5. Wywołujemy funkcję dodawania
W celu skrócenia kodu, wykorzystamy rzutowanie typu obiektów przypisanych do zdarzenia Click. Rozpoznanie wykonane jest po sprawdzeniu zawartości Tag wybranych kontrolek Button
Wskazówka:
private void button2_Click(object sender, EventArgs e)
{
Button bt = sender as Button;
switch (bt.Tag)
{
case "+": dodawanie(t, textBox3); break;
}
}
Skompiluj program i sprawdź efekt działania
Ćwiczenie sprawdzające: Wykonaj pozostałe funkcje działań arytmetycznych (+,-,/) z uwzględnieniem zabezpieczenia przed dzieleniem przez zero
Pełny kod rozwiązania
Wskazówka:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _27tabliceWielowymiarowe
{
public partial class Form1 : Form
{
int[,] t;
int rozmiar = 0, zakres =100;
Random los = new Random();
public Form1()
{
InitializeComponent();
}
void dodawanie(int[,] t,TextBox tb)
{
tb.Clear();
for(int i = 0; i < t.GetLength(0); i++)
{
tb.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString()
+ "+" + t[i, 1].ToString()
+"="+(t[i,0]+t[i,1]).ToString()
+ Environment.NewLine);
}
}
void odejmowanie(int[,] t, TextBox tb)
{
tb.Clear();
for (int i = 0; i < t.GetLength(0); i++)
{
tb.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString() + "-"
+ t[i, 1].ToString() + "="
+ (t[i, 0] - t[i, 1]).ToString()
+ Environment.NewLine);
}
}
void mnozenie(int[,] t, TextBox tb)
{
tb.Clear();
for (int i = 0; i < t.GetLength(0); i++)
{
tb.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString() + "*"
+ t[i, 1].ToString() + "="
+ (t[i, 0] * t[i, 1]).ToString()
+ Environment.NewLine);
}
}
void dzielenie(int[,] t, TextBox tb)
{
tb.Clear();
for (int i = 0; i < t.GetLength(0); i++)
{
if(t[i,1]!=0)
tb.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString() + "/"
+ t[i, 1].ToString() + "="
+ ((float)t[i, 0]/(float)t[i, 1]).ToString()
+ Environment.NewLine);
else
tb.AppendText("dzielnie przez zero"
+ Environment.NewLine);
}
}
private void button2_Click(object sender, EventArgs e)
{
Button bt = sender as Button;
switch (bt.Tag)
{
case "+": dodawanie(t, textBox3); break;
case "-": odejmowanie(t, textBox3); break;
case "*": mnozenie(t, textBox3); break;
case "/": dzielenie(t, textBox3); break;
}
}
private void button1_Click(object sender, EventArgs e)
{
rozmiar = Convert.ToInt16(textBox1.Text);
zakres = Convert.ToInt16(textBox2.Text);
textBox3.Clear();
t = new int [rozmiar,2];
for(int i = 0; i < rozmiar; i++)
{
t[i, 0] = los.Next(zakres);
t[i, 1] = los.Next(zakres);
textBox3.AppendText((i + 1).ToString() + ") "
+ t[i, 0].ToString() + ";"
+ t[i, 1].ToString()
+Environment.NewLine);
}
}
}
}
Rozwiązanie pod konsolę
W rozwiązaniu na konsolę wprowadzimy coś w rodzaju menu wyboru. W zależności od wybranego klawisza program wykona inna funkcję obliczającą wybrane działanie matematyczne
Przy obsłudze wyboru klawiszy zastosujemy pętle do while. Do przechwytywania informacji o wcisnietym klawiszu użyjemy klasy ConsoleKeyInfo. Przykładowy kod uruchamiany w funkcji Main podaję poniżej
Wskazówka:
ConsoleKeyInfo klawiszInfo;
do
{
klawiszInfo=Console.ReadKey();
switch (klawiszInfo.KeyChar)
{
case '+': dodawanie(t);break;
case '-': odejmowanie(t); break;
case '*': mnozenie(t); break;
case '/': dzielenie(t); break;
}
} while (klawiszInfo.Key != ConsoleKey.Escape);
Pełny kod rozwiązania poniżej
Wskazówka:
namespace statyczne_tablice_wielowymiarowe_konsola
{
internal class Program
{
static int[,] t;
static int rozmiar = 0, zakres = 100;
static Random los = new Random();
static void losujTablice()
{
Console.WriteLine("Podaj rozmiar tablicy:");
rozmiar = int.Parse(Console.ReadLine());
Console.WriteLine("Podaj zakres losowego zbioru:");
zakres = int.Parse(Console.ReadLine());
Console.Clear();
Console.WriteLine("Zawartość wylosowanej tablicy:");
t = new int[rozmiar, 2];
//losuj i pokaz elementy tablicy
for (int i = 0; i < rozmiar; i++)
{
t[i, 0] = los.Next(zakres);
t[i, 1] = los.Next(zakres);
Console.WriteLine(i + "\t" + t[i, 0] + "\t" + t[i,1]);
}
}
static void dodawanie(int[,] t)
{
for (int i = 0; i < t.GetLength(0); i++)
{
int a = t[i, 0];
int b = t[i, 1];
int suma = a + b;
Console.WriteLine(i + "\t"+a+"+"+b+"="+suma);
}
}
static void odejmowanie(int[,] t)
{
for (int i = 0; i < t.GetLength(0); i++)
{
int a = t[i, 0];
int b = t[i, 1];
int roznica = a - b;
Console.WriteLine(i + "\t" + a + "-" + b + "=" + roznica);
}
}
static void mnozenie(int[,] t)
{
for (int i = 0; i < t.GetLength(0); i++)
{
int a = t[i, 0];
int b = t[i, 1];
int iloczyn = a * b;
Console.WriteLine(i + "\t" + a + "*" + b + "=" + iloczyn);
}
}
static void dzielenie(int[,] t)
{
for (int i = 0; i < t.GetLength(0); i++)
{
int a = t[i, 0];
int b = t[i, 1];
if (b == 0) continue;
float iloraz = (float)a / b;
//wynik zaokraglij do 3 miejsc po przecinku
Console.WriteLine(i + "\t" + a + "/" + b + "=" + iloraz.ToString("F3"));
}
}
static void Main(string[] args)
{
Console.WriteLine("Witaj w CzD!");
losujTablice();
Console.WriteLine("Wybierz działanie (klawisze: +, -, *, /, Esc- koniec)");
ConsoleKeyInfo klawiszInfo;
do
{
klawiszInfo=Console.ReadKey();
switch (klawiszInfo.KeyChar)
{
case '+': dodawanie(t);break;
case '-': odejmowanie(t); break;
case '*': mnozenie(t); break;
case '/': dzielenie(t); break;
}
} while (klawiszInfo.Key != ConsoleKey.Escape);
}
}
}
Działanie wersji pod konsolę przedstawia poniższa ilustracja