![](/edu/images/logo.png)
TI/Algorytm: Różnice pomiędzy wersjami
(Nie pokazano 19 pośrednich wersji utworzonych przez tego samego użytkownika) | |||
Linia 1: | Linia 1: | ||
− | ==[[ | + | ==[[Technologie informacyjne i komunikacyjne|⬆]] Algorytm → kod źródłowy → program wykonywalny== |
Pisząc '''program komputerowy''', chcemy stworzyć coś, co będzie zrozumiałe dla komputera, i będzie pewnego rodzaju instrukcją — dokładnym i jednoznacznym opisem tego, co komputer ma wykonywać. Programem komputerowym jest np. przeglądarka internetowa, edytor tekstów, odtwarzacz multimediów, czy też prosta aplikacja kalkulatora. | Pisząc '''program komputerowy''', chcemy stworzyć coś, co będzie zrozumiałe dla komputera, i będzie pewnego rodzaju instrukcją — dokładnym i jednoznacznym opisem tego, co komputer ma wykonywać. Programem komputerowym jest np. przeglądarka internetowa, edytor tekstów, odtwarzacz multimediów, czy też prosta aplikacja kalkulatora. | ||
Linia 7: | Linia 7: | ||
Jak opisać komputerowi skomplikowany zbiór funkcjonalności, jakich dostarcza np. przeglądarka internetowa, skoro maszyna rozumie bezpośrednio jedynie bardzo ograniczony zbiór prostych instrukcji procesora? Pisanie wszystkiego za pomocą prostych instrukcji procesora trwałoby bezsensownie długo. Z pomocą przychodzą języki programowania, w których które analizując treść programów sprowadzają je z postaci bardziej intuicyjnej dla człowieka do postaci zrozumiałej dla maszyny. | Jak opisać komputerowi skomplikowany zbiór funkcjonalności, jakich dostarcza np. przeglądarka internetowa, skoro maszyna rozumie bezpośrednio jedynie bardzo ograniczony zbiór prostych instrukcji procesora? Pisanie wszystkiego za pomocą prostych instrukcji procesora trwałoby bezsensownie długo. Z pomocą przychodzą języki programowania, w których które analizując treść programów sprowadzają je z postaci bardziej intuicyjnej dla człowieka do postaci zrozumiałej dla maszyny. | ||
--> | --> | ||
+ | Człowiek pisze tekst programu komputerowego zgodnie z regułami wybranego języka programowania. Tworzy w ten sposób kod źródłowy. Aby go uruchomić, należy, zależnie od wybranego języka: | ||
+ | *skompilować kod źródłowy do kodu maszynowego, zrozumiałego dla komputera, czyli użyć programu, zwanego kompilatorem (stworzonego dla tego konkretnego języka, w którym program napisano), który potrafi wczytać kod źródłowy i zgodnie z gramatyką danego języka programowania przetworzyć na kod maszynowy, który będzie tzw. "programem wykonywalnym". Żeby używać programu w takiej postaci nie potrzebujemu już kodu żródłowego. Wystarczy postać wykonywalna. Mówimy wtedy o '''kompilowanych językach programowania'''. | ||
+ | *użyć do wykonania napisanego przez siebie kodu "interpretera" (np. Pythona). Mówimy wtedy o '''językach interpretowanych'''. Tym, co uruchamiamy za każdym razem, jest napisany przez nas kod źródłowy, ale żeby komputer mógł go zrozumieć, używamy interpretera danego języka — programu, który analizuje kod źródłowy i od razu go wykonuje. Takie rozwiązanie jest zwykle nieco wolniejsze i pochłania więcej zasobów, niż uruchamianie skompilowanego wcześniej kodu maszynowego. Jednak do pewnych zastosowań języki interpretowane, zwane też skryptowymi, są wygodniejsze niż kompilowane. Szczególnie, gdy kod źródłowy jest często zmieniany — nie musimy za każdym razem go kompilować i uruchamiać kodu maszynowego. Tak jest np. w przypadku Pythona, którego uczycie się na ćwiczeniach. | ||
− | + | Przyjrzyjmy się, co właściwie znajduje się w kodzie źródłowym. Najczęściej jest to ciąg instrukcji, opisującym bardzo | |
− | + | dokładnie jakiś algorytm — schemat postępowania. Na przykład algorytm otwierania drzwi mógłby wyglądać tak: | |
− | |||
− | |||
− | Przyjrzyjmy się, co właściwie | ||
− | źródłowym. Najczęściej jest to ciąg instrukcji, opisującym bardzo | ||
− | dokładnie jakiś algorytm | ||
− | algorytm otwierania drzwi mógłby wyglądać tak: | ||
naciśnij klamkę | naciśnij klamkę | ||
Linia 35: | Linia 32: | ||
Tekst programu (czyli kod źródłowy) podlega ścisłej gramatyce i | Tekst programu (czyli kod źródłowy) podlega ścisłej gramatyce i | ||
ortografii danego języka — zamiana jednej litery zwykle | ortografii danego języka — zamiana jednej litery zwykle | ||
− | spowoduje, że program nie będzie działał | + | spowoduje, że program nie będzie działał — zwykle nawet nie |
da się go ''skompilować''. | da się go ''skompilować''. | ||
+ | |||
+ | ===Przykład: kod źródłowy programu obliczającego silnię w języku Python=== | ||
+ | <source lang="Python"> | ||
+ | liczba = 1 | ||
+ | wynik = 1 | ||
+ | while liczba <= 5: | ||
+ | liczba += 1 | ||
+ | wynik *= liczba | ||
+ | print('Python obliczył: 5! =', wynik) | ||
+ | </source> | ||
===Przykład: kod źródłowy programu obliczającego silnię w języku C=== | ===Przykład: kod źródłowy programu obliczającego silnię w języku C=== | ||
Linia 104: | Linia 111: | ||
Nawet dziś fachowcy uważają, że nie ma większych programów całkowicie | Nawet dziś fachowcy uważają, że nie ma większych programów całkowicie | ||
wolnych od błędów. Testowanie programów (czyli wykrywanie błędów) jest | wolnych od błędów. Testowanie programów (czyli wykrywanie błędów) jest | ||
− | co najmniej tak samo kosztowne i pracochłonne jak ich pisanie. | + | co najmniej tak samo kosztowne i pracochłonne jak ich pisanie. |
− | + | Niestety konkutencja na rynku oprogramowania wymusza przedwczesne wypuszczanie na rynek niewystarczająco przetestowanych programów. Dlatego niemal przyzwyczailiśmy się do faktu, że programy czasem "wieszają się" lub nie działają tak, jak powinny. Ale znacznie niebezpieczniejsze jest niedostateczne testowanie programów, w tym przede wszystkim systemów operacyjnych, pod kątem bezpieczeństwa. Powoduje to istnienie luk, które mogą być wykorzystane przez cybeprpzestępców do wykradania danych a nawet przejećia (zdalnie) całkowitej kontroli nad naszym komputerem, który może być w takiej sytuacji wykorzystywany do dalszych przestępstw i ataków. | |
− | |||
− | |||
− | Coraz większego znaczenia nabiera idea | + | Coraz większego znaczenia nabiera idea [[TI/Otwarte_Źródła,_GNU_i_wolność_oprogramowania|Otwartych Źródeł]] (ang. ''Open Source''), według której każdy użytkownik ma prawo wglądu w kod źródłowy |
− | której każdy użytkownik | ||
programu, którego używa, a nawet jego modyfikacji, czyli dostosowania | programu, którego używa, a nawet jego modyfikacji, czyli dostosowania | ||
do własnych potrzeb. Jednak w przypadku komercyjnych programów i | do własnych potrzeb. Jednak w przypadku komercyjnych programów i | ||
Linia 116: | Linia 120: | ||
tajemnicą producenta, a użytkownik dostaje wyłącznie programy | tajemnicą producenta, a użytkownik dostaje wyłącznie programy | ||
wykonywalne (czyli zera i jedynki). | wykonywalne (czyli zera i jedynki). | ||
+ | |||
+ | ==Linkowanie bibliotek== | ||
+ | Pisząc program komputerowy korzystamy z bibliotek gotowych funkcji, skompilowanych wcześniej dla danego systemu opercyjnego. Na przykład wypisanie na ekran wyniku w języku C wymaga użycia funkcji <code>print()</code>, która znajduje się w bibliotece <code>stdio</code>. Te biblioteki są specyficzne dla danego systemu operacyjnego i zawierają funkcjonalności, tłumaczące wysokopoziomowe komendy języka programowania na działania specyficzne dla danego systemu operacyjnego i sprzętu. W powyższym przykładzie biblioteka <code>stdio</code> (od ''standard input-output'') zawiera funkcje służące do wcztywania danych z pliku lub z klawiatury, oraz wypisywania wyników na ekran (w terminalu). Dzięki temu wypisując wynik funkcją <code>printf()</code> (od ''print formatted'', czyli wydruk sformatowany) nie musimy myśleć o tym, w którym miejscu ekranu znajduje się okienko terminala, i które piksele trzeba podświetlić a które zgasić, żeby ułożyły się w konkretne litery i cyfry. | ||
+ | |||
+ | '''Ciekawostka''': ''wyjście programu w Uniksie można w prosty sposób przekierować do pliku'' | ||
+ | <source lang="bash"> | ||
+ | % ls | ||
+ | silnia.py | ||
+ | % python3 silnia.py | ||
+ | Python obliczył: 5! = 720 | ||
+ | % python3 silnia.py > wynik.txt | ||
+ | % ls | ||
+ | silnia.py wynik.txt | ||
+ | % cat wynik.txt | ||
+ | Python obliczył: 5! = 720 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | ===virtualenv=== | ||
+ | Biblioteki są nie tylko specyficzne dla danego systemu i kompilatora — są też ciągle ulepszane, a ich funkcjonalności poszerzane. Dlatego też w nowszych wersjach bibliotek wywołania tych samych funkcji mogą mieć inną postać i formę, przez co kod napisany pod kątem starszej biblioteki może nie dać się dowiązać (zlinkować) do jej nowszej wersji, i odwrotnie. Dla uniknięcia bałaganu związanego z wieloma wersjami tych samych bibliotek w Pythonie, możemy użyć tzw. [https://virtualenv.pypa.io/en/latest/user_guide.html wirtualnego środowiska] (''virtual environment'', <code>virtualenv</code>). | ||
+ | |||
+ | Bardziej radykalnym sposobem na uruchamianie programów w osobnych środowiskach jest wirtualizacja, czyli emulowanie całego systemu operacyjnego "w okienku" — ten sposób omówimy na wykładzie o [[TI/Od_operatora_do_systemu_operacyjnego|systemach operacyjnych]]. | ||
+ | |||
+ | ==Bramki logiczne w serialu "Three Body Problem"== | ||
+ | https://youtu.be/icnQ2Fu2mZQ?si=GKh9QRh7pmhBFxF-&t=189 | ||
+ | |||
+ | |||
+ | <div align="right"> | ||
+ | [[TI/Zera i jedynki|⬅]] [[Technologie informacyjne i komunikacyjne|⬆]] [[TI/Uczenie_maszynowe|⮕]] | ||
+ | </div> |
Aktualna wersja na dzień 13:38, 5 sie 2024
Spis treści
⬆ Algorytm → kod źródłowy → program wykonywalny
Pisząc program komputerowy, chcemy stworzyć coś, co będzie zrozumiałe dla komputera, i będzie pewnego rodzaju instrukcją — dokładnym i jednoznacznym opisem tego, co komputer ma wykonywać. Programem komputerowym jest np. przeglądarka internetowa, edytor tekstów, odtwarzacz multimediów, czy też prosta aplikacja kalkulatora.
Człowiek pisze tekst programu komputerowego zgodnie z regułami wybranego języka programowania. Tworzy w ten sposób kod źródłowy. Aby go uruchomić, należy, zależnie od wybranego języka:
- skompilować kod źródłowy do kodu maszynowego, zrozumiałego dla komputera, czyli użyć programu, zwanego kompilatorem (stworzonego dla tego konkretnego języka, w którym program napisano), który potrafi wczytać kod źródłowy i zgodnie z gramatyką danego języka programowania przetworzyć na kod maszynowy, który będzie tzw. "programem wykonywalnym". Żeby używać programu w takiej postaci nie potrzebujemu już kodu żródłowego. Wystarczy postać wykonywalna. Mówimy wtedy o kompilowanych językach programowania.
- użyć do wykonania napisanego przez siebie kodu "interpretera" (np. Pythona). Mówimy wtedy o językach interpretowanych. Tym, co uruchamiamy za każdym razem, jest napisany przez nas kod źródłowy, ale żeby komputer mógł go zrozumieć, używamy interpretera danego języka — programu, który analizuje kod źródłowy i od razu go wykonuje. Takie rozwiązanie jest zwykle nieco wolniejsze i pochłania więcej zasobów, niż uruchamianie skompilowanego wcześniej kodu maszynowego. Jednak do pewnych zastosowań języki interpretowane, zwane też skryptowymi, są wygodniejsze niż kompilowane. Szczególnie, gdy kod źródłowy jest często zmieniany — nie musimy za każdym razem go kompilować i uruchamiać kodu maszynowego. Tak jest np. w przypadku Pythona, którego uczycie się na ćwiczeniach.
Przyjrzyjmy się, co właściwie znajduje się w kodzie źródłowym. Najczęściej jest to ciąg instrukcji, opisującym bardzo dokładnie jakiś algorytm — schemat postępowania. Na przykład algorytm otwierania drzwi mógłby wyglądać tak:
naciśnij klamkę jeśli drzwi się otworzą udało się - koniec. w przeciwnym razie włóż do zamka klucz, przekręć w lewo i naciśnij klamkę jeśli drzwi się otworzą udało się - koniec. w przeciwnym razie nie udało się - koniec.
Program komputerowy to zapis algorytmu w języku zrozumiałym dla komputera. Ten język składa się niestety z samych zer i jedynek (wyjaśnienie w następnym rozdziale) i nie jest dla ludzi wygodny w użyciu. Dlatego do pisania programów komputerowych stworzono języki programowania (Ada, C, Pascal, Fortran, Logo, Basic... Python :-) ).
Tekst programu (czyli kod źródłowy) podlega ścisłej gramatyce i ortografii danego języka — zamiana jednej litery zwykle spowoduje, że program nie będzie działał — zwykle nawet nie da się go skompilować.
Przykład: kod źródłowy programu obliczającego silnię w języku Python
liczba = 1
wynik = 1
while liczba <= 5:
liczba += 1
wynik *= liczba
print('Python obliczył: 5! =', wynik)
Przykład: kod źródłowy programu obliczającego silnię w języku C
#include <stdio.h>
int main()
{
long int wynik=1, liczba=1;
while (liczba < 5) {
liczba = liczba+1;
wynik = wynik*liczba;
}
printf("5! = %ld\n", wynik);
return 0;
}
Przykład: kod źródłowy programu obliczającego silnię w języku C++
#include <iostream>
using namespace std;
int main()
{
long liczba=1, wynik=1;
while (liczba < 5) {
liczba = liczba + 1;
wynik = wynik*liczba;
}
cout << "5! = "<< wynik << endl
<<"obliczone programem w C++ :-)" << endl;
}
Przykład: kod źródłowy programu obliczającego silnię w języku Java
class Silnia {
public static void main(String[] args) {
int wynik=1, liczba=1;
while(liczba<5){
liczba=liczba+1;
wynik=wynik*liczba;
}
System.out.println(wynik);
}
}
Kompilacja to zamiana kodu źródłowego na binarny (tj. zera i jedynki), wykonywalny przez komputer. Dokonuje tego program komputerowy zwany kompilatorem. Jeśli "nie zrozumie" jakiegoś słowa w kodzie źródłowym, bo np. end zamieniliśmy na edn, to po prostu odmówi kompilacji.
Niestety zdarzają się również błędy, które przechodzą przez proces kompilacji, ale powodują, że skompilowany program nie działa dokładnie według intencji autora. Takie błędy bywają trudne do wyśledzenia, szczególnie, gdy ujawniają się tylko np. w rzadko używanych funkcjach i w specyficznych sytuacjach. Mówi się o nich bugs (insekty, robaki). Nazwa pochodzi z czasów pierwszych komputerów, budowanych na lampach i zajmujących ogromne pomieszczenia. Ich programowanie polegało na przełączaniu kabelków, a zwarcia (czyli błędy) powodowały czasem ginące wśród nich ćmy.
Nawet dziś fachowcy uważają, że nie ma większych programów całkowicie wolnych od błędów. Testowanie programów (czyli wykrywanie błędów) jest co najmniej tak samo kosztowne i pracochłonne jak ich pisanie. Niestety konkutencja na rynku oprogramowania wymusza przedwczesne wypuszczanie na rynek niewystarczająco przetestowanych programów. Dlatego niemal przyzwyczailiśmy się do faktu, że programy czasem "wieszają się" lub nie działają tak, jak powinny. Ale znacznie niebezpieczniejsze jest niedostateczne testowanie programów, w tym przede wszystkim systemów operacyjnych, pod kątem bezpieczeństwa. Powoduje to istnienie luk, które mogą być wykorzystane przez cybeprpzestępców do wykradania danych a nawet przejećia (zdalnie) całkowitej kontroli nad naszym komputerem, który może być w takiej sytuacji wykorzystywany do dalszych przestępstw i ataków.
Coraz większego znaczenia nabiera idea Otwartych Źródeł (ang. Open Source), według której każdy użytkownik ma prawo wglądu w kod źródłowy programu, którego używa, a nawet jego modyfikacji, czyli dostosowania do własnych potrzeb. Jednak w przypadku komercyjnych programów i systemów operacyjnych kod źródłowy bywa wciąż pilnie strzeżoną tajemnicą producenta, a użytkownik dostaje wyłącznie programy wykonywalne (czyli zera i jedynki).
Linkowanie bibliotek
Pisząc program komputerowy korzystamy z bibliotek gotowych funkcji, skompilowanych wcześniej dla danego systemu opercyjnego. Na przykład wypisanie na ekran wyniku w języku C wymaga użycia funkcji print()
, która znajduje się w bibliotece stdio
. Te biblioteki są specyficzne dla danego systemu operacyjnego i zawierają funkcjonalności, tłumaczące wysokopoziomowe komendy języka programowania na działania specyficzne dla danego systemu operacyjnego i sprzętu. W powyższym przykładzie biblioteka stdio
(od standard input-output) zawiera funkcje służące do wcztywania danych z pliku lub z klawiatury, oraz wypisywania wyników na ekran (w terminalu). Dzięki temu wypisując wynik funkcją printf()
(od print formatted, czyli wydruk sformatowany) nie musimy myśleć o tym, w którym miejscu ekranu znajduje się okienko terminala, i które piksele trzeba podświetlić a które zgasić, żeby ułożyły się w konkretne litery i cyfry.
Ciekawostka: wyjście programu w Uniksie można w prosty sposób przekierować do pliku
% ls
silnia.py
% python3 silnia.py
Python obliczył: 5! = 720
% python3 silnia.py > wynik.txt
% ls
silnia.py wynik.txt
% cat wynik.txt
Python obliczył: 5! = 720
virtualenv
Biblioteki są nie tylko specyficzne dla danego systemu i kompilatora — są też ciągle ulepszane, a ich funkcjonalności poszerzane. Dlatego też w nowszych wersjach bibliotek wywołania tych samych funkcji mogą mieć inną postać i formę, przez co kod napisany pod kątem starszej biblioteki może nie dać się dowiązać (zlinkować) do jej nowszej wersji, i odwrotnie. Dla uniknięcia bałaganu związanego z wieloma wersjami tych samych bibliotek w Pythonie, możemy użyć tzw. wirtualnego środowiska (virtual environment, virtualenv
).
Bardziej radykalnym sposobem na uruchamianie programów w osobnych środowiskach jest wirtualizacja, czyli emulowanie całego systemu operacyjnego "w okienku" — ten sposób omówimy na wykładzie o systemach operacyjnych.
Bramki logiczne w serialu "Three Body Problem"
https://youtu.be/icnQ2Fu2mZQ?si=GKh9QRh7pmhBFxF-&t=189