Dużo koduję zarówno w C, jak i C ++, ale nie spodziewałem się, że C będzie drugim najpopularniejszym językiem, nieco za Javą.
Indeks społeczności programistycznych TIOBE
Ciekawe, dlaczego w tym wieku OOP C jest nadal tak popularny? Zauważ, że 4 z 5 najpopularniejszych języków programowania to „nowoczesne”, zorientowane obiektowo języki.
Teraz zgadzam się, że możesz do pewnego stopnia używać OOP w C, ale jest to trochę bolesne i nieeleganckie (przynajmniej w porównaniu z C ++, jak sądzę). Co sprawia, że C jest tak popularny? Czy to wydajność; będąc na niskim poziomie; zdecydowana większość bibliotek, które już istnieją, czy coś jeszcze?
programming-languages
object-oriented
c
GradGuy
źródło
źródło
+"<language> programming"
w popularnych wyszukiwarkach. W blogu „Dlaczego nikt już nie programuje C” liczy się C w tym indeksie. Cholera, nawet to pytanie może zrobić, gdy tylko Google go odbierze.Odpowiedzi:
Kilka czynników, które przyczyniają się:
źródło
Zawsze obwiniałem popularność C o potrzebę uniwersalnego języka asemblera. Jego połączenie specyfiki na poziomie maszyny, standaryzacji i ekstremalnej przenośności pozwala C funkcjonować jako de facto uniwersalny język asemblerowy i z tego powodu podejrzewam, że jego rola będzie istnieć w nieskończoność.
Powinienem wspomnieć, że zawsze jestem nieco zaskoczony, gdy OOP jest prezentowany na kursach programistycznych jako rodzaj „ostatecznego modelu”, który jest jedynym możliwym punktem końcowym dobrego programowania. Podobnie jak wiele innych aspektów programowania, wartość OOP stanowi kompromis między wieloma konkurującymi ze sobą czynnikami, w tym sposobem, w jaki mózg ludzki organizuje informacje, jak grupy społeczne wspierają oprogramowanie w dłuższej perspektywie, a w przypadku programowania obiektowego niektóre dość głębokie aspekty jak działa sam wszechświat.
I ten ostatni punkt warto trochę wbić. Czytaj dalej, jeśli jesteś zainteresowany badaniem na poziomie fizyki, dlaczego istnieją pewne style programowania, jak one działają razem i gdzie może zmierzać świat w przyszłości, gdy będziemy dalej rozwijać takie koncepcje ...
Obiekt w fizyce to wszystko, co utrzymuje rozpoznawalną spójność w czasie. To z kolei pozwala prostym stworzeniom, takim jak my, uciec przed przedstawieniem obiektu przy użyciu tylko niewielkiej liczby bitów, bez narażania naszego życia na zbyt duże straty. Ale jeśli chodzi o fizykę w ogóle, liczba rzeczy, które musisz dokładnie zrobić, aby uprościć i uprościć tego rodzaju uproszczenia, jest niezwykle duża. Jako ludzie nie myślimy o tym tyle, ponieważ szczerze mówiąc, nie byłoby nas tutaj, gdyby to nie była prawda.
Brzmi zbyt abstrakcyjnie? To naprawdę nie jest. Wyobraź sobie na przykład, że próbujesz nawigować drogą do domu znajomego, jeśli zamiast samochodów napotkasz gwałtownie oscylujące pola plazmy i chwilowe kondensacje materii poruszającej się z ogromnym zakresem prędkości. Taki scenariusz mógłby raczej głęboko wpłynąć na możliwości socjalizacji, tak? Musimy obiekty, my są obiekty, oraz istnienie obiektów daje nam ogromną i krytycznie ważny poziom uproszczenia otoczenia wokół nas.
Wróćmy więc do oprogramowania. Co obiekty w świecie rzeczywistym mają do powiedzenia na temat obiektów w zakresie programowania?
Cóż, z jednej strony oznacza to, że to, co definiuje „dobry” obiekt w oprogramowaniu, powinno naprawdę oznaczać, czy rodzaj danych, którymi się posługujesz, z łatwością wspiera ideę rozpoznawalnego uporczywości w czasie .
Dzięki tej definicji najłatwiejsze formy OOP są łatwe do rozpoznania. Są to te, które trochę sobie radzą, używając tylko danych, które są już „dołączone” lub zdefiniowane przez jakiś rzeczywisty, prawdziwie fizyczny obiekt, taki jak osoba, dom lub samochód. Nawet dzisiaj jest to zbyt często jedyna definicja obiektów, które ludzie zdobywają na kursach oprogramowania. To niedobrze, ponieważ nawet trywialne programy obiektowe potrzebują szerszej definicji niż to.
Druga i znacznie bardziej interesująca kategoria obiektów obejmuje to, co nazywam unieśmiertelnionymi wydarzeniami ze świata rzeczywistego . Przez „unieśmiertelniony” rozumiem rzeczy, które przynajmniej krótko istnieją jako dobrze zdefiniowane byty lub kolekcje w realnym świecie, ale które następnie rozpraszają się i przestają istnieć jako kolekcje mające znaczenie fizyczne. Sympozjum jest doskonałym przykładem: sympozjum istnieje przez krótki czas jako przyzwoicie dobrze zdefiniowana kolekcja miejsc i ludzi. Ale niestety nawet najlepsze konferencje muszą się zakończyć, a poszczególne części, które je stworzyły, przechodzą do innych działań.
Ale za pomocą komputerów i sieci możemy sprawić, że takie przejściowe sympozjum będzie wyglądać jak obiekt długoterminowy, przechwytując i utrzymując jego pamięć jako obiekt oprogramowania. Wiele rzeczy, które robimy z komputerami i bazami danych, sprowadzają się do tego rodzaju unieśmiertelnienia zdarzeń przejściowych, w których w rzeczywistości staramy się wzbogacić nasz prawdziwy wszechświat, wychwytując go i rozszerzając w sposób, który nie mógłby istnieć fizycznie. Np. Czy widziałeś ostatnio prawdziwą Pandorę? Takie przechwytywanie i rozszerzanie realnych dzieł pomaga wzbogacić i przedłużyć nasze życie, ekonomię i wybory w niezwykły sposób. To jest dla mnie centrum programowania obiektowego, miejsce, w którym wywarło i nadal ma najbardziej niezwykłe skutki.
Ostatnia kategoria OOP składa się z obiektów, które nie mają ścisłego związku ze zdarzeniami zewnętrznymi, ale są infrastrukturąpotrzebne do wspierania naszego ciągłego rozszerzania rzeczywistości za pomocą unieśmiertelnionych obiektów ze świata rzeczywistego. To tutaj możesz zejść aż do (pół) metalu komputera, tworząc kawałki trwałej rzeczywistości, które podobnie jak pierwiastki chemiczne w prawdziwym świecie można szybko łączyć i w ciekawy sposób budować nowe światy wewnętrzne. Komputery mobilne pomogły promować rozwój tego rodzaju wysoce rekombinacyjnego podejścia, które ponownie na wiele sposobów naśladuje rekombinacyjne cechy świata fizycznego. Jest to również trudne: to, co może wydawać się dobrym wyborem, może z czasem okazać się nieoczekiwanie złe, zwykle dlatego, że zamiast blokować, blokuje różnorodność i ekspansję.
Ta ostatnia kategoria wskazuje również na ryzyko związane z użyciem tylko jednego modelu do programowania, ponieważ podobnie jak świat rzeczywisty, światy programowane również potrzebują procesów, które niedobrze odpowiadają względnie niezmiennym przedmiotom. Ziemia jest pełna obiektów, ale słońce jest pełne bardzo dynamicznych przepływów energii, które ostatecznie są potrzebne do „napędzania” obiektów i działań na ziemi o niższej energii. Podobnie przy tworzeniu światów obliczeniowych zdarzają się przypadki, w których trzeba sobie radzić z przepływami i transformacjami oraz szybko zmieniającymi się kontekstami, które, choć same w sobie nie są bardzo podobne do obiektów, są jednak absolutnie niezbędne do umożliwienia prostszych, bardziej przyjaznych człowiekowi obiektów używanych na wyższych poziomach. . To nie przypadek, że znaczna część programowania wykonywanego na poziomie jądra nie jest wyraźnie podobna do obiektów lub że w dużej mierze opiera się na językach takich jak C, które są bardziej zorientowane na przetwarzanie. Są to głębsze dziedziny, które uzupełniają fascynującą różnorodność, którą widzimy wyżej w światach generowanych komputerowo.
Innym obszarem, w którym OOP może się nie udać, jest zbytnie skupianie się na starych koncepcjach obiektów.
Przedmioty w świecie rzeczywistym, a zwłaszcza żywe , mają absolutnie zadziwiający poziom umiejętności interakcji ze środowiskiem w skomplikowany i subtelny sposób. Widżety nadające się do wzajemnego przeglądania, sprawdzające zgodność i sprawdzanie poprawności, a może nawet wymyślające nowe sposoby interakcji są bardzo zbliżone do rzeczywistej koncepcji biologicznej obiektów niż proste ramy i schematy dziedziczenia, które mamy tendencję skupić się (zwykle z konieczności!) na poziomie kodu. Jest to jeden z obszarów wzrostu obiektów w świecie cybernetycznym, im bardziej „agresywne” podejście, w którym reaktywność na środowisko jest normą nawet w ramach samego programowania.
I tyle za moją „krytykę” OOP! Mam jednak nadzieję, że wskazałem, dlaczego stworzenie bogatszego cyberprzestrzeni oznacza uwzględnienie różnorodności stylów programowania, zamiast zakładać, że „tylko jeden” jest wszystkim, czego potrzeba. Mam wrażenie, że naprawdę interesujące rzeczy dopiero nadejdą, bez względu na to, jak przyziemna jest większość naszych działań!
źródło
Po pierwsze, nie potrzebujesz OOP do wszystkiego, pomimo wszelkich dogmatów na ten temat, które zostały spopularyzowane. W przeciwieństwie do Java, C pozwala na wskaźniki funkcji, a nawet zamknięcia, które otwierają drzwi do programowania funkcjonalnego i rozwiązują dość część uchwytów OOP przestrzeni problemowej, ponieważ zapewniają środki wstrzykiwania zależności. Również ostrożne stosowanie makr może faktycznie stworzyć kilka bardzo ciekawych rzeczy, jak sglib dowodzi.
W dziwny sposób można postrzegać C jako dobry kompromis między Javą a C ++. Pamiętaj, że nie mówię, że C jest w jakikolwiek sposób mieszanką obu. Ale w przeciwieństwie do Javy, jest to dość potężny język, podczas gdy w przeciwieństwie do C ++ ma złożoną obsługę.
Jest to stary język, który stał się niezawodny i spójny, a jednocześnie nie bardziej skomplikowany. Poza tym ma gigantyczny ekosystem i po prostu działa wszędzie.
źródło
C ma ABI (Application Binary Interface), a C ++ nie. To sprawia, że C jest bardziej użyteczny niż C ++ w niektórych przypadkach. Jeśli mam napisać bibliotekę i móc wysyłać pliki binarne do użytku innych osób, C ++ jest niewłaściwym narzędziem do tego zadania. Jeśli mam zamiar napisać biblioteki, które będą używane przez inny język, C jest właściwym narzędziem do tego zadania. Nigdy nie słyszałem o języku, który nie obsługiwał FFI (Interfejs funkcji zagranicznej) do C, z drugiej strony C ++ nie będzie działał z bibliotekami napisanymi w C ++, jeśli zostaną użyte różne kompilatory.
Zasadniczo sprowadza się do C, wypełniając rolę, dla której C ++ nie jest odpowiedni.
źródło
Jedną z zalet używania C w językach takich jak C ++ lub Java jest to, że pod maską nie dzieje się wiele magii. Żadne konstruktory nie są uruchamiane, gdy elementy są przydzielane, i nie są uruchamiane żadne destruktory, gdy obiekty wykraczają poza zakres. Nie ma mangowania nazw ani vtabeli. Wydajność jest łatwiejsza do przewidzenia; nie musisz się martwić o to, że śmieciarz zakłóci rutynę i skróci czas jej działania.
Konstruktory, destruktory, zmienianie nazw, vtable, śmieciarze itp. Mogą złagodzić złożoność kodu, który tworzysz, ale wtedy złożoność ta staje się częścią samego języka, w którym nie masz nad nim żadnej kontroli . Możesz skończyć z dłuższym czasem kompilacji (irytującym, ale znośnym), większym obciążeniem pamięci środowiska wykonawczego (może być lub nie być tolerowanym) lub wolniejszym działaniem. Dzięki C możesz zmniejszyć część tej złożoności, dopóki nie pozostaniesz z potrzebną funkcjonalnością .
Na przykład
string
typ danych C ++ jest o lata świetlne łatwiejszy do pracy niż ciągi w stylu C, ale jest to dość ciężki fragment kodu i dodaje pewnej wagi do rozmiaru obrazu. Rzadko widuję, by ktokolwiek w pełni korzystał zstring
możliwości dowolnego programu. Ciągi w stylu C, choć trudniejsze do pracy, nakładają mniejszą karę pod względem czasu działania i rozmiaru obrazu, a dla konkretnego problemu mogą być z tego powodu bardziej atrakcyjne.źródło
std
.string
, które nie są używane, jeśli statycznie łączysz CRT, to łańcuch narzędzi, który nie jest tego wart.std::string
nie jest wystarczająco wyrafinowana . Jeśli naprawdę poważnie podchodzisz do łańcuchów, zarówno pod względem wydajności, jak i możliwości, wrócisz do korzystania z C i robienia tego wszystkiego samemu, choćchar*
na pewno nie używasz zwykłych starych s. (Struny są zaskakująco skomplikowane, nawet jeśli oczekujesz, że będą skomplikowane.)Systemy osadzone i sterowniki są zwykle programowane w C. Oprócz tego istnieje mnóstwo starszych systemów C, które są nadal utrzymywane i rozbudowywane.
źródło
To samo, co sprawia, że młot ręczny jest popularny w czasach młotów pneumatycznych (młotów pneumatycznych): C jest nadal właściwym narzędziem do niektórych prac.
źródło
Prostota, spójność i precyzja.
To proste - nie potrzebujesz złożonego środowiska programistycznego, obszernych bibliotek ani maszyny wirtualnej.
Jest spójny - większość C napisanych 10 lat temu mogłaby się dziś skompilować.
Precyzja - pozwala zejść na poziom maszyny, znając w razie potrzeby lokalizację pamięci. Jest to świetne rozwiązanie dla wydajności i wbudowanego sprzętu.
To nie jest na wszystko, ale nadal jest to przydatne narzędzie.
źródło
Przytaczam dwa punkty z innej odpowiedzi, ponieważ zawierają dokładne powody, dla których wciąż używam C od czasu do czasu (chociaż nie jest to mój główny język wyboru):
Myślę, że to bardzo prawda. Nauczyłem się C we wczesnych latach nocnych: było proste, mało słów kluczowych i konstrukcji, większość pracy wykonywanej przez biblioteki. Potem nie używałem C przez kilka lat. Około 2002 roku potrzebowałem szybkiej implementacji algorytmu, zainstalowałem kompilator C i zaimplementowałem go. Znam język, wiem do czego służy, do czego nie jest odpowiedni ( nigdy nie wdrożyłbym aplikacji internetowej w C!) I jest tam, kiedy jej potrzebuję. Bez niespodzianek.
Z C ++ miałem inne doświadczenie. Nauczyłem się go około 1995 roku i oznaczało to dużą zmianę paradygmatu z trybu imperatywnego na OOP. Wspaniały! Używałem go do kilku projektów do 1999 roku. Przez kilka lat nie używałem C ++, a kiedy go ponownie wziąłem (2008), znalazłem wiele nowych funkcji już w języku, a nawet bardziej planowanych (tymczasem wprowadzonych w C ++ 11). Mam wrażenie, że muszę znów nauczyć się języka.
Jako programista wolę dojrzałe, stabilne języki. Lubię raz nauczyć się języka, rozumieć jego zasady projektowania, do czego jest dobry, i używać go, gdy uważam, że jest to właściwe narzędzie do pracy. Lubię też uczyć się różnych języków i wybierać język, który odpowiada moim potrzebom (C, C ++, Java, Scala, Haskell i tak dalej). Nie podoba mi się to, że muszę ciągle uczyć się tego samego języka, ponieważ rozwija się on coraz bardziej i nigdy nie osiąga dojrzałości.
IMHO, język programowania powinien mieć przejrzysty, spójny i stabilny wygląd. Lubię podejście projektantów takich jak Niklaus Wirth: za każdym razem, gdy odczuwał potrzebę innego języka, projektował nowy (Pascal, Modula-2, Modula-3, Oberon). Nie lubię języków, które przechodzą ważne zmiany co 5–10 lat: są jak ruchome cele i nigdy nie uważam, że warto poświęcić swój czas na ich dogłębną naukę, ponieważ wersja, której się teraz uczę, prawdopodobnie stanie się przestarzała w każdym razie lata.
W tym sensie C jest zwycięzcą IMO: jest dobre dla niektórych aplikacji i mniej odpowiednie dla innych, ale ma tę zaletę, że jest proste i względnie stabilne.
źródło
Dziwi mnie, że nikt jeszcze nie wspominał o gorszej jakości . W tej chwili ma ponad 20 lat, ale nadal jest warty przeczytania. Niekiedy wprawia w osłupienie, ale bardzo dobrze opisuje, w jaki sposób i dlaczego celownik często wygrywa z ideałem, używając C (w porównaniu z LISP) jako jednego z głównych przykładów.
źródło
Prawdopodobnie chciałeś zapytać, dlaczego ludzie używają C zamiast C ++, mimo że gdy masz kompilator C, zwykle masz też kompilator C ++.
źródło
Nic. TIOBE jest bezwartościowym indeksem. Jeśli faktycznie spojrzysz na ich pomiar, to w najlepszym razie absolutne przypuszczenie.
źródło
Dużo starszego oprogramowania
Wiele firm nie może zmienić, natychmiast cały swój kod na C ++ lub podobny.
Wiele firm nie stać na zmianę kodu.
Wiele firm może sobie pozwolić na zmianę kodu, ale nie obchodzi ich to, że są „tanie”.
Wiele firm jest w trakcie migracji, ale jeszcze się nie zakończyło.
Orientacja ukrytych obiektów
(Non Object Oriented) Kod źródłowy C zaprojektowany jako kod źródłowy Object Oriented C, aplikacje, które są modelowane za pomocą Object Orientation i kodowane za pomocą „czystego C” lub narzędzia, które tłumaczą z „C ++” lub innego programu OO. lang do C.
Słyszałem, że niektóre gry wideo są robione w ten sposób. Niektóre narzędzia między platformami oraz biblioteka wizualnego interfejsu GTK (GObject, GLibrary) dla dystrybucji GNOME Linux OS.
źródło
Widzę, że niektórzy respondenci podają, dlaczego C jest najbardziej popularny, istnieje już od dłuższego czasu, jest dostępny na większości platform, bezpłatny itp.
To samo można powiedzieć o innych językach, na przykład darmowym Pascalu - jest bezpłatny i obsługiwany przez prawie wszystkie platformy.
Pascal został wynaleziony około 1970 roku, C został wynaleziony około 1972 roku, więc myślę, że Pascal istnieje już od C.
Osobiście uważam, że C jest najpopularniejszym językiem, ponieważ dostępny jest po prostu więcej otwartego kodu źródłowego do ponownego wykorzystania przez każdego. I tak, jest na niższym poziomie niż Pascal, więc zbliża się do złożenia, ale jest o wiele bardziej czytelny niż montaż.
Myślę, że jest po prostu zbyt wiele języków programowania. Jako programiści musimy znać większość najważniejszych, ale na koniec nie powinno być takiej potrzeby. W tym celu można wdrożyć jeden język programowania, od tworzenia stron internetowych po gry komputerowe na iOS.
C wydaje się być globalnym językiem, ale chciałbym, żeby był to coś w rodzaju Object Pascal. Dlaczego Object Pascal, jest to bardziej czytelny język programowania, kod OOP jest zwykle bardziej przydatny i mniej podatny na błędy (moim zdaniem) niż C.
Bardzo duże aplikacje są łatwiejsze w zarządzaniu dzięki Object Pascal niż C / C ++.
Co do posiadania języka programowania, który był taki od lat 70., i nie lubienia języków, które zmieniają się co 5 lub 10 lat. Z biegiem czasu postęp technologiczny i metody programowania są ulepszane. Jeśli język zmienia się drastycznie co kilka lat, to prawdopodobnie nie został dobrze przemyślany przez jego projektanta. Ale lata 1970–2012 to prawie pół wieku, w tym czasie można wprowadzić zmiany w języku, aby uwzględnić postępy w rozwoju oprogramowania.
Samo C zostało kilkakrotnie poprawione. Nie jest to więc lepsze niż inne języki z tego punktu widzenia.
źródło
Ponieważ C ma ogromną bazę użytkowników. Tak, to trochę kłopot 22, ale kiedy zadaję pytanie o C w StackOverflow, otrzymuję odpowiedź prawie natychmiast. Odpowiedzi na to samo pytanie dotyczące Pythona mogą zająć godziny.
W przypadku C ++ nauka IMO jest trudniejsza. Co więcej, po wypróbowaniu OOP przez 10 lat uważam, że nie zawsze jest to przydatne i często łatwiej jest zamiast tego korzystać z programowania procedur.
źródło