Komputery nie mówią po angielsku. Nie mówią też po chińsku, niemiecku, hiszpańsku. Nie posługują się one żadnym językiem ludzkim. Pomimo tego w jaki sposób kontaktuje się z nami Siri lub Alexa, komputery i inne gadżety posiadają swój własny, binarny język, niezrozumiały dla człowieka.
To oznacza, że jeśli chcesz zaprogramować komputer, musisz porozumieć się z nim w jego języku, ponieważ ten nie zna Twojego. Język ojczysty komputera, jedyny jaki zna, wygląda tak:
00110101101101011101010101010101110001010101011
… i tak dalej, i tak dalej. Dokładnie tak, same zera i jedynki - żadnych przecinków, spacji, czy kolorowych obrazków. Elementy te znane są jako bity (ang. bits), określenie to powstało z połączenia słów “binary digits”, oznaczających “cyfry binarne”.
Zmiana kolejności bitów sprawi, że komputer wykona inne czynności. Twoim zadaniem, jako programisty, jest ustalenie właściwej kolejności. Powodzenia.
W czasach, gdy programowanie jeszcze raczkowało, polegało ono właśnie na ustawianiu zer i jedynek w odpowiedniej kolejności. Ze względu na to, iż był to bardzo powolny proces, a błędy występowały na każdym kroku, podjęto decyzję by go skrócić i ułatwić pracę programistom wymyślając coś, co nazywamy językami programowania. Obecnie jest ich bardzo wiele: Java, C++, FORTRAN, Python, BASIC, Ada, Pascal, Rust, Swift i dziesiątki innych.
Większość programistów dobrze "mówi" w jednym lub dwóch językach programowania, a przy okazji może posiadać niewielką wiedzę na temat innych języków. Podobnie jak w przypadku języków ludzkich, wśród programistów istnieje tendencja do posiadania ulubionego języka, któremu pozostają wierni.
Jeśli napiszesz krótki program w języku C, może to wyglądać tak:
Widać różnicę, prawda? Zamiast zer i jedynek pojawiły się prawdziwe słowa, nawet jeśli są to wyrazy, które nie istnieją w normalnym użyciu, takie jak “printf”. Obecne jest również wiele znaków interpunkcyjnych rozrzuconych w różnych miejscach. Na pewno nie jest to angielski, ale jest o wiele łatwiejszy do odczytania niż wszystkie jedynki i zera. Widać zdecydowaną poprawę.
Gdybyśmy napisali ten sam kod w języku FORTRAN zamiast C, wyglądałby on tak:
Wygląda on dość podobnie. Tak jak w przypadku pierwszego kodu, kod w FORTRANIE przypomina angielski, jednak różni się od angielskiego, jakiego uczymy się w szkołach. I tak - wszyscy programiści na całym świecie programują w pseudo-angielskich językach programowania, ponieważ języki programistyczne nie są tłumaczone na języki ojczyste - nie ma polskiej wersji językowej C czy FORTRANA.
Ale co z naszym pierwotnym problemem? Jeśli komputery potrafią zrozumieć tylko jedynki i zera, jaki jest pożytek z języków programowania takich jak C? Tutaj na scenę wchodzi kompilator.
Kompilator jest tłumaczem. Tłumaczy on angielskie polecenia na zera i jedynki, które nasz komputer jest w stanie zrozumieć. Jest to jednak tłumaczenie jednokierunkowe, ponieważ kompilator nie jest w stanie przekonwertować zer i jedynek z powrotem na język C lub jakikolwiek inny język programowania, co oznacza, że kompilator nie pomoże Ci zrozumieć kodu po kompilacji.
Wiele firm tworzy i sprzedaje kompilatory, natomiast istnieją także wersje darmowe. Różne kompilatory różnie tłumaczą ten sam program, tak samo jak różne słowniki mogą definiować te same słowa na nieco inne sposoby. Nie ma w tym nic złego, o ile wynik, który otrzymamy na koniec będzie taki sam.
Kiedy dajesz komuś wskazówki, takie jak: "Idź do znaku stopu, a następnie skręć w lewo", oznacza to to samo co “Skręć w lewo na znaku stopu". Mimo, że wskazówki są sformułowane inaczej, są one w rzeczywistości takie same. To samo odnosi się do programów komputerowych. Program można napisać na wiele sposobów, tak samo jak istnieje wiele sposobów przetłumaczenia kodu na zera i jedynki. Niektóre kompilatory starają się uzyskać możliwie najkrótsze, najbardziej zwarte tłumaczenie ("Znak stop, potem w lewo."), inne są bardziej obszerne („Jedź tak szybko, jak to możliwe, w kierunku znaku stop, zaciągnij hamulec ręczny, a za hydrantem dodaj gazu i jedź dalej!”).
Ten sam kompilator może nawet wykonywać oba rodzaje tłumaczeń, a także różne wersje pomiędzy nimi. Kompilację można kontrolować za pomocą opcji kompilacji, tj. poleceń, które mówią kompilatorowi, czy chcesz mieć mały program, szybki program, czy coś pomiędzy.
Wystarczy użyć kompilatora tylko raz. Po przetłumaczeniu programu, nie ma potrzeby robić tego ponownie, jednak w przypadku dokonania zmian w kodzie, konieczna będzie ponowna kompilacja.
Jednak co w przypadku, gdy kompilator popełni błąd? Pomyli się w tłumaczeniu i stworzy wadliwy program? Co prawda może do tego dojść, ale zdarza się bardzo rzadko. Kompilatory w dzisiejszych czasach są dość niezawodne, a jeśli twój program nie działa tak, jak zamierzałeś, problem leży na ogół... gdzie indziej. Znacznie częściej to programista popełnia błąd. Na szczęście, kompilatory mogą wyłapać wiele błędów, od prostych literówek do większych problemów. Na przykład, jeśli pominąłeś pierwszą klamrę w programie C (na końcu drugiej linijki w kodzie powyżej), kompilator wyłapie błąd i powiadomi Cię o tym. Nie poprawi on jednak błędów za Ciebie, musisz to zrobić samemu. Ale przynajmniej kompilator wychwycił błąd i przestał próbować tłumaczyć coś, co nie miało dla niego sensu.
Tym, czego kompilator nie wychwyci są bardziej subtelne błędy - kompilator rozumie to co kazałeś zrobić programowi, nie to co chcesz by robił. Jeśli przypadkowo napiszesz „Help me, world!” zamiast „Hello, world!” Twój kompilator nie może tego naprawić. Zakłada, że zrobiłeś to celowo - i może to zrobiłeś.
Język programowania, w którym piszesz nazywany jest kodem źródłowym, natomiast po przetłumaczeniu go na zera i jedynki, kod ten określa się kodem wynikowym. Powyższe programy napisane w C i FORTRANIE są przykładem kodu źródłowego i oba robią w zasadzie to samo.To rodzi interesujące pytanie. Czy można napisać program używając dowolnego języka? W dużej mierze tak. Dwa powyższe programy mogły zostać napisane w Javie, Ruscie lub w jakimkolwiek innym języku i nadal działałyby w ten sam sposób. Do przetłumaczenia kodu napisanego w Ruscie na zera i jedynki użyłbyś innego kompilatora, jednak nie miałoby to żadnej różnicy dla komputera. Po przetłumaczeniu, komputer nie “widzi” kodu źródłowego i nie ma dla niego znaczenia, w jakim języku został on pierwotnie napisany. Języki programowania powstały dla wygody programisty, nie maszyny.
Czy różne komputery i różne mikroprocesory mówią różnymi językami? Nie do końca, chociaż w pewnym sensie tak - jest to trochę skomplikowane. Żaden komputer nie rozumie języków programowania, dlatego też mamy kompilatory. To, w jakim języku został napisany program nie ma znaczenia, ponieważ nie ma żadnego związku między językiem kodu źródłowego a sprzętem.
Nie jest tak, że procesory Intel x86 uruchamiają tylko programy Java, a procesory ARM tylko programy napisane w Swifcie. Języki programowania są neutralne i vice versa - każdy procesor obsługuje dowolny język, ponieważ to kompilator tłumaczy kod źródłowy na binarny kod wynikowy, który jest zrozumiały dla procesora. Mimo to, różne procesory mają różne języki binarne, które są dla nich zrozumiałe. Nazywa się to standardową architekturą przemysłową lub ISA. Na przykład wszystkie chipy oparte na architekturze ARM używają tego samego zestawu instrukcji. Ta sama sekwencja zer i jedynek będzie działać na każdym procesorze z architekturą ARM, ale nie zadziałają na procesorach Intel lub AMD x86, które mają inną ISA. Podobnie binarny kod wynikowy nie zadziała na mikroprocesorze PIC, procesorze MIPS, RISC-V ani żadnym innym ISA. Kod źródłowy jest neutralny dla procesora; kod wynikowy nie jest.
Dlatego ważne jest, aby mieć dostęp do kodu źródłowego programu. Pozwala to na przetłumaczenie jednego programu na wiele różnych procesorów, nawet tych z różnymi ISA. Kod źródłowy pozwala na nieskończoną ilość tłumaczeń, nawet dla przyszłych procesorów, które nie zostały jeszcze wynalezione. Mając kod źródłowy i odpowiedni kompilator, możesz przetłumaczyć dowolny program do uruchomienia na dowolnym komputerze. Możesz również edytować, zmieniać i aktualizować program, a następnie przekompilować (przetłumaczyć) go ponownie, aby utworzyć nowy kod wynikowy.
To część uroku stojącego za ruchem oprogramowania „open source”. Programiści swobodnie udostępniają swój kod źródłowy, aby inni programiści mogli (a) zobaczyć, jak on działa, (b) znaleźć błędy, których nie wyłapał twórca kodu, (c) dodawać własne ulepszenia do kodu źródłowego, skompilować go, i rozpowszechniać zaktualizowaną wersję programu. I to wszystko bez wydawania żadnych pieniędzy. Bez kodu źródłowego żadna z tych czynności nie byłaby możliwa.
Kontrola kodu źródłowego oznacza kontrolę komercyjną. Większość firm utrzymuje swój kod źródłowy w tajemnicy, tak jak Coca-Cola chroni swój przepis. Oni i tylko oni mogą kompilować swoje programy z kodu źródłowego do kodu wynikowego wymaganego przez różne procesory. Pozwala to firmie kontrolować, gdzie i jak będą działać jej programy. Microsoft zachowuje kontrolę nad kodem źródłowym dla Windows 10, co oznacza, że tylko Microsoft może decydować, jakie mikroprocesory ISA mogą korzystać z Windows 10. Apple kontroluje kod źródłowy dla MacOS, i tak dalej. Użytkownicy nie mają możliwości uruchomić systemu Windows lub MacOS na dowolnym komputerze, ponieważ nie mają możliwości jego kompilacji.
Kod źródłowy dla Linuksa jest natomiast dostępny za darmo. Można go skompilować na każdą maszynę, co jest jednym z powodów jego popularności. To samo dotyczy FreeRTOS, Apache, PHP i dziesiątków innych projektów open-source'owych. Oprogramowanie open-source niekoniecznie jest lepsze bądź gorsze od oprogramowania komercyjnego. Są to po prostu różne filozofie dotyczące dystrybucji, wkładu i kontroli.
#programowanie #kompilator #jezykbinarny #kodźródłowy #kodwynikowy
RaiBay - Polish Online Auction for Tech Talents
Follow us: Linkedin, Facebook, Twitter :)
Join us at raibay.com and/or check our choosen job openings https://www.raibay.com/positions