|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autor artykułu: mgr Jerzy Wałaszek |
©2026 mgr Jerzy Wałaszek
|
| SPIS TREŚCI |
|
| Podrozdziały |
W matematyce macierz ( ang. matrix ) jest prostokątną tablicą liczb, którą zwykle przedstawiamy następująco:

Liczby w macierzy ułożone są w poziomych wierszach oraz pionowych kolumnach. Liczba wierszy i liczba kolumn określa rozmiar macierzy ( ang. matrix size ). Macierze zapisujemy zwykle dużymi literami alfabetu, a w indeksie podajemy ich rozmiar. Liczby w macierzy są jej wyrazami ( ang. matrix elements/entries ) i posiadają indeksy określające numer wiersza i numer kolumny, w których się znajdują. Wyrazy macierzy zapisujemy małymi literami alfabetu:

Macierz zbudowaną z jednego wiersza lub jednej kolumny nazywamy wektorem ( ang. vector matrix ). Wektory zapisujemy skrótowo jako:

Macierz o jednakowej liczbie wierszy i kolumn nazywamy macierzą kwadratową ( ang. square matrix ):

Wyrazy macierzy o równych numerach wiersza i kolumny nazywamy przekątną główną macierzy ( ang. matrix main diagonal ), a liczba wierszy lub kolumn nazywana jest wtedy stopniem tej macierzy. Macierz kwadratowa stopnia czwartego wygląda następująco:

Macierz zerowa ( ang. zero matrix lub null matrix ) posiada wszystkie elementy zerowe:

Macierz jednostkowa, tożsamościowa, identycznościowa ( ang. unit matrix lub identity matrix ) jest macierzą kwadratową, której elementy przekątnej głównej są równe 1, a wszystkie pozostałe są równe 0:

Podmacierzą ( ang. submatrix ) nazywamy macierz, która powstaje z macierzy wyjściowej po usunięciu dowolnej liczby kolumn i wierszy:

Poniższy program deklaruje tablicę o rozmiarze 10×20 i wypełnia ją liczbami przypadkowymi o zakresie od 0 do 99.
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Program główny
//---------------
int main()
{
setlocale(LC_ALL,"");
cout << "Tablica statyczna o rozmiarze 10x20" << endl
<< "-----------------------------------" << endl << endl;
// Definicja tablicy statycznej
unsigned int A[10][20];
// Indeksy elementów
unsigned i,j;
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Tablicę wypełniamy liczbami pseudolosowymi z zakresu 0...99
for(i = 0; i < 10; i++) // Wiersze
for(j = 0; j < 20; j++) // Kolumny
A[i][j] = rand() % 100;
// Weświetlamy wyniki
for(i = 0; i < 10; i++)
{
for(j = 0; j < 20; j++) cout << setw(3) << A[i][j];
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Tablica statyczna o rozmiarze 10x20 ----------------------------------- 36 34 35 86 2 27 61 50 55 52 59 4 34 77 98 43 94 59 7 73 15 37 5 96 23 31 90 61 13 13 48 0 74 15 52 46 33 75 14 24 32 39 11 28 43 22 10 37 81 93 12 70 81 18 28 23 47 27 62 39 38 55 60 29 12 30 66 74 52 79 48 98 80 87 25 47 95 3 42 18 76 40 70 87 16 34 20 4 13 47 37 76 51 46 83 5 39 36 37 59 34 89 37 27 2 42 59 29 87 26 35 48 61 30 20 30 33 69 27 66 29 28 68 72 44 71 54 86 86 32 21 21 32 19 95 14 11 62 28 41 71 58 83 73 49 2 36 37 72 0 39 59 44 49 73 95 64 44 58 74 90 62 6 20 1 13 24 82 90 82 52 88 22 59 60 26 67 9 57 85 24 34 66 49 14 35 37 21 84 7 25 66 31 19 81 15 79 5 7 76 |
Pamiętaj, iż w języku C++ indeksy rozpoczynają się od 0, zatem element A[0][0] jest elementem w pierwszym wierszu i w pierwszej kolumnie macierzy.
Tablicę dynamiczną można stworzyć na kilka sposobów. Pierwszy z nich polega na zarezerwowaniu odpowiedniego obszaru pamięci i umieszczenie w nim tablicy, Po wykorzystaniu tablicy zarezerwowany dla niej obszar pamięci należy zwolnić.
Drugi program pokazuje, jak to zrobić w języku C++:
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Program główny
//---------------
int main()
{
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Generujemy rozmiar tablicy:
// n - liczba wierszy: 5...15
// m - liczba kolumn: 10...20
int n = 5 + rand() % 11;
int m = 10 + rand() % 11;
// Tworzymy wskaźnik do wskaźników liczb całkowitych
int ** A;
// Tworzymy dynamicznie obszar na tablicę n wskaźników
A = new int * [n];
// Tworzymy dynamiczne tablice dla każdego wiersza
int i,j;
for(i = 0; i < n; i++) A[i] = new int [m];
setlocale(LC_ALL,"");
cout << "Tablica dynamiczna o rozmiarze " << n << "x" << m << endl
<< "------------------------------------" << endl << endl;
// Tablicę wypełniamy liczbami pseudolosowymi z zakresu 0...99
for(i = 0; i < n; i++) // Wiersze
for(j = 0; j < m; j++) // Kolumny
A[i][j] = rand() % 100;
// Wyświetlamy wyniki
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++) cout << setw(3) << A[i][j];
cout << endl;
}
cout << endl;
// Usuwamy tablice wierszy
for(i = 0; i < n; i++) delete [] A[i];
// Usuwamy tablicę wskaźników
delete [] A;
return 0;
}
|
| Wynik |
| Tablica dynamiczna o rozmiarze 12x19 ------------------------------------ 22 61 20 80 10 97 86 84 41 26 64 66 7 92 85 76 55 0 90 44 76 77 14 51 18 16 63 42 94 93 27 43 15 35 6 7 6 36 2 51 47 67 70 71 35 17 3 15 44 77 23 4 12 45 36 5 95 66 9 78 67 68 40 88 24 62 36 43 19 54 3 20 95 56 18 80 95 91 76 65 83 33 61 69 37 56 12 0 21 89 95 9 28 4 4 77 14 84 47 32 42 40 91 20 98 26 42 83 3 55 82 95 18 79 92 3 56 94 50 41 47 36 51 26 21 21 17 74 52 52 12 53 91 37 45 97 4 84 41 8 34 8 75 96 37 71 68 38 28 40 38 88 90 71 78 94 85 36 94 95 46 30 97 95 1 25 97 83 36 50 47 21 21 78 61 46 73 14 73 9 70 97 15 81 81 70 5 45 44 87 30 7 50 59 40 42 4 72 59 68 94 56 88 20 19 57 27 71 62 86 95 90 57 37 3 19 18 54 62 15 19 17 71 67 86 58 71 18 |
Macierz może również zostać odwzorowana jako klasa języka C++. W klasie można zdefiniować różne operacje na zawartej w niej macierzy. Plik definiujący klasę można używać jako plik nagłówkowy w programach przetwarzających macierze. Zaletą klasy jest to, iż prosto możemy zdefiniować w programie wiele różnych macierzy.
Poniższy program demonstruje przykładową prostą klasę macierzy liczb całkowitych. Klasa ta wspiera operacje przypisywania wartości elementom macierzy oraz odczytywania wartości elementów ( dla prostoty klasa nie sprawdza błędów ). Zwróć uwagę, iż zarezerwowano obszar dla tablicy jednowymiarowej. Tak też można.
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
class matrix
{
private:
int n,m; // Rozmiar macierzy
int * A; // Elementy
public:
matrix(int r, int c); // Konstruktor
~matrix(); // Destruktor
void setv(int r, int c, int v);
int getv(int r, int c);
};
// Konstruktor - tworzy macierz o podanych wymiarach:
// r - liczba wierszy
// c - liczba kolumn
//---------------------------------------------------
matrix::matrix(int r, int c)
{
n = r;
m = c;
A = new int [n * m];
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
matrix::~matrix()
{
delete [] A;
}
// Ustawia wartość elementu
// r - numer wiersza
// c - numer kolumny
// v - wartość dla elementu
//-------------------------
void matrix::setv(int r, int c, int v)
{
A[r * m + c] = v;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
int matrix::getv(int r, int c)
{
return A[r * m + c];
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Generujemy rozmiar tablicy:
// n - liczba wierszy: 5...15
// m - liczba kolumn: 10...20
int n = 5 + rand() % 11;
int m = 10 + rand() % 11;
// Tworzymy macierz
matrix A(n,m);
// Macierz wypełniamy liczbami od -99 do 99
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++) A.setv(i,j,-99+rand() % 199);
// Wyświetlamy macierz
setlocale(LC_ALL,"");
cout << "Klasa macierzy o rozmiarze " << n << "x" << m << endl
<< "--------------------------------" << endl << endl;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++) cout << setw(4) << A.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Klasa macierzy o rozmiarze 10x15 -------------------------------- 55 -98 -58 16 10 -13 87 26 -51 -20 0 20 -76 68 -91 0 20 -76 68 -91 -85 -6 96 75 96 32 -38 -18 -79 -92 32 -38 -18 -79 -92 73 99 62 -63 37 73 -65 -19 30 17 73 -65 -19 30 17 -29 75 55 57 99 85 35 -36 73 -43 85 35 -36 73 -43 -35 -57 -45 -35 83 -89 4 65 6 10 -89 4 65 6 10 -27 67 64 -49 -39 -95 -57 -75 -54 60 -95 -57 -75 -54 60 -44 86 22 -16 14 61 -80 -57 18 -40 61 -80 -57 18 -40 -46 -69 25 -89 7 -8 -3 33 -80 27 -8 -3 33 -80 27 78 -78 48 85 -90 54 84 75 -94 59 54 84 75 -94 59 48 -60 -2 43 -22 78 39 -94 -20 52 |
Lepszym pomysłem jest wykorzystanie klasy szablonowej. Klasa szablonowa nie określa typu elementów - robi to program użytkownika w momencie tworzenia zmiennej na podstawie szablonu klasy. Dzięki temu możemy w prosty sposób otrzymać macierz o dowolnym typie elementów.
Poniższy przykład programu definiuje klasę szablonową macierzy, następnie na jej podstawie tworzy macierz liczb typu double, wypełnia ją pseudolosowymi wartościami i wyświetla jej zawartość. Wszystko jest maksymalnie uproszczone.
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int n,m; // Rozmiar macierzy
T * A; // Elementy
public:
matrix(int r, int c); // Konstruktor
~matrix(); // Destruktor
void setv(int r, int c, T v);
T getv(int r, int c);
};
// Konstruktor - tworzy macierz o podanych wymiarach:
// r - liczba wierszy
// c - liczba kolumn
//---------------------------------------------------
template <class T> matrix<T>::matrix(int r, int c)
{
n = r;
m = c;
A = new T [n * m];
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Ustawia wartość elementu
// r - numer wiersza
// c - numer kolumny
// v - wartość dla elementu
//-------------------------
template <class T> void matrix<T>::setv(int r, int c, T v)
{
A[r * m + c] = v;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Generujemy rozmiar tablicy:
// n - liczba wierszy: 5...15
// m - liczba kolumn: 5...15
int n = 5 + rand() % 11;
int m = 5 + rand() % 11;
// Tworzymy macierz
matrix<double> A(n,m);
// Macierz wypełniamy liczbami pseudolosowymi od 0 do 9.99
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++) A.setv(i,j,(rand() % 1000) / 100.0);
// Wyświetlamy macierz
setlocale(LC_ALL,"");
cout << setprecision(2) << fixed;
cout << "Klasa szablonowa macierzy o rozmiarze " << n << "x" << m << endl
<< "-------------------------------------------" << endl << endl;
for(i = 0; i < n; i++)
{
for(j = 0; j < m; j++) cout << setw(5) << A.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Klasa szablonowa macierzy o rozmiarze
12x13 ------------------------------------------- 8.40 8.88 4.15 1.27 2.23 5.34 6.05 5.91 7.75 6.53 6.92 0.58 0.24 1.01 2.01 6.73 4.22 8.37 4.53 7.18 2.58 9.83 7.24 4.40 4.09 2.83 7.34 9.16 5.37 0.04 7.90 0.38 0.02 9.60 8.33 1.45 8.97 5.95 8.09 3.31 8.59 5.02 2.99 4.04 6.39 4.76 6.70 7.69 5.96 8.54 6.21 5.00 2.14 2.55 7.51 7.34 1.31 0.74 4.13 6.64 7.95 7.63 4.91 6.78 5.03 2.59 8.26 9.01 8.17 3.84 1.33 8.87 8.77 3.80 1.63 1.80 6.70 5.81 1.81 0.43 7.87 9.33 1.05 8.98 3.40 1.15 8.70 1.86 1.76 8.26 7.28 0.30 9.20 0.64 2.78 1.57 2.18 8.97 0.18 2.54 9.10 0.05 7.61 2.92 0.13 0.87 0.76 0.58 2.92 6.16 2.54 8.96 7.55 6.84 6.64 1.27 4.10 5.87 3.61 4.50 7.66 5.22 9.93 1.97 2.49 4.83 3.83 5.78 7.92 0.50 7.69 5.46 3.37 0.10 3.01 0.57 0.68 4.88 1.74 2.69 0.73 3.01 5.29 6.00 5.70 3.86 0.25 6.60 8.99 9.83 8.55 0.54 2.07 4.44 5.58 1.42 |
W dalszej części artykułu będziemy wykorzystywali klasę szablonową z odpowiednimi modyfikacjami, ponieważ jest najbardziej ogólna.
Podamy tutaj proste sposoby wprowadzania danych do programu przetwarzającego macierze. Dane można umieszczać bezpośrednio w programie, w pliku lub wprowadzać je przez strumień wejścia.
Dane umieszczone w programie nie są specjalnie wygodnym sposobem definiowania zawartości macierzy, ponieważ zmiana danych wymaga modyfikacji programu. Niemniej jednak ten sposób może być czasem przydatny.
Poniższy program tworzy macierz jednostkową i wyświetla jej zawartość:
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int n,m,s; // Rozmiar macierzy
T * A; // Elementy
public:
matrix(int r, int c); // Konstruktor
~matrix(); // Destruktor
void makeIdent(void); // Macierz jednostkowa
T getv(int r, int c);
};
// Konstruktor - tworzy macierz o podanych wymiarach:
// r - liczba wierszy
// c - liczba kolumn
//---------------------------------------------------
template <class T> matrix<T>::matrix(int r, int c)
{
n = r;
m = c;
s = n * m;
A = new T [s];
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Tworzy macierz jednostkową
//-------------------------
template <class T> void matrix<T>::makeIdent()
{
int i;
for(i = 0; i < s; i++) A[i] = (T) 0;
for(i = 0; i < n; i++) A[i * m + i] = (T) 1;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Inicjujemy generator pseudolosowy
srand(time(NULL));
// Generujemy rozmiar macierzy:
// n - liczba wierszy i kolumn: 10...20
int n,i,j;
n = 10 + rand() % 11;
// Tworzymy macierz kwadratową
matrix<int> A(n,n);
// Tworzymy macierz jednostkową
A.makeIdent();
// Wyświetlamy macierz
setlocale(LC_ALL,"");
cout << "Macierz jednostkowa o rozmiarze " << n << "x" << n << endl
<< "-------------------------------------" << endl << endl;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++) cout << setw(2) << A.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Macierz jednostkowa o rozmiarze 20x20 ------------------------------------- 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 |
Następne dwie metody odczytują dane dla macierzy ze strumienia, Pierwsza metoda odczytuje dane z pliku dane.txt, który należy umieścić w katalogu projektowym, jeśli pracujesz w edytorze Code Blocks, lub w katalogu z programem, jeśli uruchamiasz program z poziomu konsoli lub menedżera plików.
Dane są skonstruowane następująco:
Przykładowe dane:
Przekopiuj plik dane.txt do odpowiedniego katalogu.
Poniższy program tworzy macierz na podstawie danych z pliku. Zakładamy, że dane są liczbami całkowitymi bez znaku ( typ macierzy musi się zgadzać z typem danych w pliku ). Następnie program wyświetla zawartość wczytanej macierzy.
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int n,m,s; // Rozmiar macierzy
T * A; // Elementy
public:
matrix(); // Konstruktor
~matrix(); // Destruktor
T getv(int r, int c);
int rows(); // Zwraca liczbę wierszy macierzy
int cols(); // Zwraca liczbę kolumn macierzy
};
// Konstruktor - tworzy macierz z pliku dane.txt
//----------------------------------------------
template <class T> matrix<T>::matrix()
{
ifstream fin; // Strumień wejścia z pliku
fin.open("dane.txt",ifstream::in); // Otwieramy strumień do odczytu
fin >> n >> m; // Odczytujemy ze strumienia wymiary macierzy
s = n * m;
A = new T [s]; // Rezerwujemy pamięć na macierz
for(int i = 0; i < s; i++) fin >> A[i]; // Wczytujemy wyrazy do macierzy
fin.close(); // Zamykamy strumień
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
// Zwraca liczbę wierszy w macierzy
//---------------------------------
template <class T> int matrix<T>::rows()
{
return n;
}
// Zwraca liczbę kolumn w macierzy
//---------------------------------
template <class T> int matrix<T>::cols()
{
return m;
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Tworzymy macierz
matrix<int> A;
// Wyświetlamy macierz
int i,j;
setlocale(LC_ALL,"");
cout << "Macierz z pliku o rozmiarze " << A.rows() << "x" << A.cols() << endl
<< "---------------------------------" << endl << endl;
for(i = 0; i < A.rows(); i++)
{
for(j = 0; j < A.cols(); j++) cout << setw(4) << A.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Macierz z pliku o rozmiarze 10x15 --------------------------------- 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 7 0 9 6 4 7 2 5 3 1 0 2 8 2 3 8 8 6 2 3 1 0 8 5 4 8 2 9 9 2 9 6 9 2 3 2 1 9 6 8 2 3 4 5 1 8 9 5 6 3 2 2 2 6 11 5 7 9 12 6 0 7 8 2 7 3 5 5 1 8 9 3 3 2 0 9 7 2 5 5 5 2 2 2 1 9 8 0 0 0 4 444 7 6 8 9 2 3 6 8 8 888 92 43 15 1 3 66 87 51 62 88 92 83 99 11 13 6 55 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Kolejny program jest właściwie identyczny z poprzednim. Różnica polega na tym, iż dane dla macierzy odczytywane są ze standardowego strumienia. Poniższe dane skopiuj do schowka, uruchom program i wklej je do okna konsoli ( Windows: Ctrl+V, Linuks Ctrl+Shift+V ):
|
Dane wejściowe:
10 15 126 22 36 4 54 6 7 88 96 0 13 25 3 47 52 75 0 95 62 46 73 21 5 32 17 0 27 8 29 34 82 85 6 21 343 16 28 8 5 44 83 29 911 93 23 99 655 96 222 32 24 1 96 68 8 21 3 4 53 18 81 93 598 6 32 25 29 21 63 11 56 71 92 12 6 0 734 8 27 7 37 5 53 1 89 9 34 37 22 0 929 7 26 5 533 5 2 29 22 15 92 83 47 28 0 4 444 7 6 8 9 26 3 69 86 87 888 92 43 15 51 34 66 87 51 62 88 92 83 99 11 13 6 55 6 19 2 3 4 5 6 74 8 9 10 11 12 13 14 15 |
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int n,m,s; // Rozmiar macierzy
T * A; // Elementy
public:
matrix(); // Konstruktor
~matrix(); // Destruktor
T getv(int r, int c);
int rows(); // Zwraca liczbę wierszy macierzy
int cols(); // Zwraca liczbę kolumn macierzy
};
// Konstruktor - tworzy macierz ze strumienia cin
//-----------------------------------------------
template <class T> matrix<T>::matrix()
{
cin >> n >> m; // Odczytujemy ze strumienia wymiary macierzy
s = n * m;
A = new T [s]; // Rezerwujemy pamięć na macierz
for(int i = 0; i < s; i++) cin >> A[i]; // Wczytujemy wyrazy do macierzy
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
// Zwraca liczbę wierszy w macierzy
//---------------------------------
template <class T> int matrix<T>::rows()
{
return n;
}
// Zwraca liczbę kolumn w macierzy
//---------------------------------
template <class T> int matrix<T>::cols()
{
return m;
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Wyświetlamy macierz
int i,j;
setlocale(LC_ALL,"");
cout << "Wpisz dane dla macierzy:" << endl;
// Tworzymy macierz z wczytaniem jej ze strumienia
matrix<int> A;
cout << endl
<< "Macierz ze strumienia o rozmiarze " << A.rows() << "x" << A.cols() << endl
<< "---------------------------------------" << endl << endl;
for(i = 0; i < A.rows(); i++)
{
for(j = 0; j < A.cols(); j++) cout << setw(4) << A.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Wpisz dane dla macierzy: 10 15 126 22 36 4 54 6 7 88 96 0 13 25 3 47 52 75 0 95 62 46 73 21 5 32 17 0 27 8 29 34 82 85 6 21 343 16 28 8 5 44 83 29 911 93 23 99 655 96 222 32 24 1 96 68 8 21 3 4 53 18 81 93 598 6 32 25 29 21 63 11 56 71 92 12 6 0 734 8 27 7 37 5 53 1 89 9 34 37 22 0 929 7 26 5 533 5 2 29 22 15 92 83 47 28 0 4 444 7 6 8 9 26 3 69 86 87 888 92 43 15 51 34 66 87 51 62 88 92 83 99 11 13 6 55 6 19 2 3 4 5 6 74 8 9 10 11 12 13 14 15 Macierz ze strumienia o rozmiarze 10x15 --------------------------------------- 126 22 36 4 54 6 7 88 96 0 13 25 3 47 52 75 0 95 62 46 73 21 5 32 17 0 27 8 29 34 82 85 6 21 343 16 28 8 5 44 83 29 911 93 23 99 655 96 222 32 24 1 96 68 8 21 3 4 53 18 81 93 598 6 32 25 29 21 63 11 56 71 92 12 6 0 734 8 27 7 37 5 53 1 89 9 34 37 22 0 929 7 26 5 533 5 2 29 22 15 92 83 47 28 0 4 444 7 6 8 9 26 3 69 86 87 888 92 43 15 51 34 66 87 51 62 88 92 83 99 11 13 6 55 6 19 2 3 4 5 6 74 8 9 10 11 12 13 14 15 |
W dalszej części artykułu będziemy stosować tę ostatnią metodę do wprowadzania danych macierzowych w przykładowych programach.
Na macierzach można wykonywać różne operacje arytmetyczne, które krótko opisujemy poniżej:
Jeśli w macierzy zamienimy wiersze z kolumnami to otrzymamy macierz transponowaną. Operację transponowania macierzy ( ang. matrix transposition ) zapisujemy dużą literą T w indeksie górnym:

Poniższy program wczytuje macierz ze standardowego wejścia i dokonuje jej transpozycji. Dane dla macierzy są pobierane ze strumienia wejściowego.
Przykładowe dane ( przekopiuj je do schowka i wklej w programie ):
Macierz:

|
Dane wejściowe: 4 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
Przykładowy program w języku C++ // Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int s; // Rozmiar macierzy
T * A; // Elementy
public:
int n,m; // Liczba wierszy i kolumn
matrix(); // Konstruktor
~matrix(); // Destruktor
T getv(int r, int c);
void transpose(); // Dokonuje transpozycji macierzy
};
// Konstruktor - tworzy macierz ze strumienia cin
//-----------------------------------------------
template <class T> matrix<T>::matrix()
{
cin >> n >> m; // Rozmiar macierzy
s = n * m;
A = new T [s]; // Rezerwujemy pamięć na macierz n x m
for(int i = 0; i < s; i++) cin >> A[i]; // Wczytujemy wyrazy macierzy
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
// Transponuje macierz
//--------------------
template <class T> void matrix<T>::transpose()
{
T * B = new T[s]; // Tymczasowa macierz o tej samej liczbie elementów
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++) B[j * n + i] = A[i * m + j];
delete [] A; // Usuwamy starą macierz
A = B; // Podmieniamy ją macierzą transponowaną
swap(n,m); // Zamieniamy wiersze z kolumnami
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Wczytujemy dane dla macierzy
setlocale(LC_ALL,"");
cout << "Wpisz dane dla macierzy:" << endl << endl;
matrix<int> A;
cout << endl
<< "Macierz przed transponowaniem ma wymiary " << A.n << " x " << A.m << endl
<< "----------------------------------------------" << endl << endl;
for(int i = 0; i < A.n; i++)
{
for(int j = 0; j < A.m; j++) cout << setw(6) << A.getv(i,j);
cout << endl;
}
// Transponujemy macierz
A.transpose();
cout << endl << endl
<< "Macierz po transponowaniu ma wymiary " << A.n << " x " << A.m << endl
<< "------------------------------------------" << endl << endl;
for(int i = 0; i < A.n; i++)
{
for(int j = 0; j < A.m; j++) cout << setw(6) << A.getv(i,j);
cout << endl;
}
cout << endl << endl;
return 0;
} |
| Wynik |
| Wpisz dane dla macierzy: 4 6 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Macierz przed transponowaniem ma wymiary 4 x 6 ---------------------------------------------- 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Macierz po transponowaniu ma wymiary 6 x 4 ------------------------------------------ 1 7 13 19 2 8 14 20 3 9 15 21 4 10 16 22 5 11 17 23 6 12 18 24 |
Macierze można mnożyć przez liczbę. Wynikiem takiego mnożenia jest macierz, której wszystkie elementy zostały pomnożone przez daną liczbę:

Dodawać można macierze o tych samych wymiarach. Wynikiem dodawania jest macierz, której elementy są sumami odpowiadających sobie elementów obu macierzy:

Mnożenie w przypadku macierzy jest trochę bardziej skomplikowane. Aby można było pomnożyć dwie macierze, muszą one spełniać pewien warunek, mianowicie, jeśli pierwsza macierz A ma m kolumn, to druga macierz B musi posiadać m wierszy:
Macierz wynikowa C posiada tyle wierszy, ile miała macierz A i tyle kolumn, ile miała macierz B.
Zasadę mnożenia najlepiej jest zrozumieć na prostym przykładzie. Mamy dwie macierze:

Macierz A ustawiamy po lewej stronie macierzy C, a macierz B ustawiamy ponad macierzą C:
| 1 | 3 | 5 | 7 | 9 | ||||||||||
| B = | 11 | 13 | 15 | 17 | 19 | |||||||||
| 21 | 23 | 25 | 27 | 29 | ||||||||||
| 31 | 33 | 35 | 37 | 39 | ||||||||||
| 0 | 2 | 4 | 6 | ? | ? | ? | ? | ? | ||||||
| A = | 8 | 10 | 12 | 14 | C = | ? | ? | ? | ? | ? | ||||
| 16 | 18 | 20 | 22 | ? | ? | ? | ? | ? |
Kolejne elementy cij macierzy C obliczamy jako sumę iloczynów kolejnych elementów z wiersza i-tego macierzy A przez kolejne elementy z kolumny j-tej macierzy B. Na przykład:

| 1 | 3 | 5 | 7 | 9 | ||||||||||
| B = | 11 | 13 | 15 | 17 | 19 | |||||||||
| 21 | 23 | 25 | 27 | 29 | ||||||||||
| 31 | 33 | 35 | 37 | 39 | ||||||||||
| 0 | 2 | 4 | 6 | 292 | ? | ? | ? | ? | ||||||
| A = | 8 | 10 | 12 | 14 | C = | ? | ? | ? | ? | ? | ||||
| 16 | 18 | 20 | 22 | ? | ? | ? | ? | ? |
W ten sam sposób obliczamy pozostałe elementy macierzy C.
| 1 | 3 | 5 | 7 | 9 | ||||||||||
| B = | 11 | 13 | 15 | 17 | 19 | |||||||||
| 21 | 23 | 25 | 27 | 29 | ||||||||||
| 31 | 33 | 35 | 37 | 39 | ||||||||||
| 0 | 2 | 4 | 6 | 292 | 316 | 340 | 364 | 388 | ||||||
| A = | 8 | 10 | 12 | 14 | C = | 804 | 892 | 980 | 1068 | 1156 | ||||
| 16 | 18 | 20 | 22 | 1316 | 1468 | 1620 | 1772 | 1924 |
Poniższy program mnoży dwie macierze i wyświetla wynik mnożenia. Dane wejściowe są odczytywane ze strumienia wejściowego. Dane macierzy poprzedzone są dwoma liczbami, które oznaczają liczbę wierszy i kolumn. Za tymi liczbami należy umieścić odpowiednią liczbę elementów dla macierzy. Elementy są liczbami całkowitymi. Program nie sprawdza poprawności danych.
Przykładowe dane ( przekopiuj je do schowka i wklej w programie ):
Macierze:

|
Dane wejściowe:
3 4 0 2 4 6 8 10 12 14 16 18 20 22 4 5 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 |
|
Przykładowy program w języku C++
// Macierze
// (C)2019 mgr Jerzy Wałaszek
// Metody numeryczne
//---------------------------
#include <iostream>
#include <iomanip>
using namespace std;
// Definicja klasy, może być w pliku nagłówkowym
//----------------------------------------------
#ifndef _matrix_class
#define _matrix_class
template <class T> class matrix
{
private:
int s; // Rozmiar macierzy
T * A; // Elementy macierzy A
public:
int n,m; // Liczba wierszy i kolumn
matrix(); // Konstruktor
matrix(int r, int c); // Konstruktor
~matrix(); // Destruktor
T getv(int r, int c);
void multiply(matrix<T> & a, matrix<T> & b);
};
// Konstruktor - tworzy macierz ze strumienia cin
//-----------------------------------------------
template <class T> matrix<T>::matrix()
{
cin >> n >> m; // Rozmiar macierzy
s = n * m;
A = new T [s]; // Rezerwujemy pamięć na macierz n x m
for(int i = 0; i < s; i++) cin >> A[i]; // Wczytujemy wyrazy macierzy
}
// Konstruktor - tworzy pustą macierz na podstawie wymiarów
//---------------------------------------------------------
template <class T> matrix<T>::matrix(int r, int c)
{
n = r;
m = c;
s = n * m;
A = new T [s]; // Rezerwujemy pamięć na macierz n x m
}
// Destruktor - usuwa macierz i zwraca zajętą przez nią pamięć
//------------------------------------------------------------
template <class T> matrix<T>::~matrix()
{
delete [] A;
}
// Zwraca wartość elementu
// r - numer wiersza
// c - numer kolumny
//-------------------------
template <class T> T matrix<T>::getv(int r, int c)
{
return A[r * m + c];
}
// Mnoży macierze
//--------------------
template <class T> void matrix<T>::multiply(matrix<T> & a, matrix<T> & b)
{
T sum;
int i,j,k;
for(i = 0; i < n; i++)
for (j= 0; j < m; j++)
{
sum = 0;
for(k = 0;k < a.m; k++) sum += a.getv(i,k) * b.getv(k,j);
A[i * m + j] = sum;
}
}
#endif // _matrix_class
// Program główny
//---------------
int main()
{
// Wczytujemy dane dla macierzy
setlocale(LC_ALL,"");
cout << "Wpisz dane dla macierzy:" << endl << endl;
matrix<int> A;
matrix<int> B;
// Ustawiamy macierz wyniku
matrix<int> C(A.n,B.m);
cout << endl
<< "Mnożenie macierzy" << endl
<< "-----------------" << endl << endl;
cout << "Macierz A" << A.n << "x" << A.m << endl;
for(int i = 0; i < A.n; i++)
{
for(int j = 0; j < A.m; j++) cout << setw(6) << A.getv(i,j);
cout << endl;
}
cout << endl;
cout << "Macierz B" << B.n << "x" << B.m << endl;
for(int i = 0; i < B.n; i++)
{
for(int j = 0; j < B.m; j++) cout << setw(6) << B.getv(i,j);
cout << endl;
}
cout << endl;
// Mnożymy macierz A przez macierz B i wynik wpisujemy do macierzy C
C.multiply(A,B);
cout << "Wynik mnożenia w macierzy C" << C.n << "x" << C.m << endl;
for(int i = 0; i < C.n; i++)
{
for(int j = 0; j < C.m; j++) cout << setw(6) << C.getv(i,j);
cout << endl;
}
cout << endl;
return 0;
}
|
| Wynik |
| Wpisz dane dla macierzy: 3 4 0 2 4 6 8 10 12 14 16 18 20 22 4 5 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 Mnożenie macierzy ----------------- Macierz A3x4 0 2 4 6 8 10 12 14 16 18 20 22 Macierz B4x5 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 Wynik mnożenia w macierzy C3x5 292 316 340 364 388 804 892 980 1068 1156 1316 1468 1620 1772 1924 |
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.