Czy jest jakiś powód, aby używać C ++ zamiast C, Perl, Python itp.? [Zamknięte]


164

Jako programista Linux (po stronie serwera) nie wiem, gdzie i dlaczego powinienem używać C ++.

Kiedy idę na występ, pierwszym i ostatnim wyborem jest C.

Gdy „wydajność” nie jest głównym problemem, dobrym wyborem są języki programowania takie jak Perl i Python.

Prawie wszystkie aplikacje open source, które znam w tej dziedzinie, zostały napisane w języku C, Perl, Python, skrypt Bash, AWK, a nawet PHP, ale nikt nie używa C ++.

Nie omawiam innych dziedzin, takich jak GUI lub aplikacje internetowe, mówię tylko o Linuksie, CLI i demonach.

Czy istnieje zadowalający powód do używania C ++?


5
Rozważam C ++ tylko z powodu STL.
dan_waterworth

46
Więc coś, co można zrobić za pomocą C, Perla i Pythona razem, można zrobić tylko przy użyciu C ++. A ty pytasz, dlaczego używać C ++?
Manoj R

36
«Kiedy idę na występ, pierwszym i ostatnim wyborem jest C.» tak, na pewno: D To niepotwierdzone i trywialnie błędne stwierdzenie.
deadalnix,

16
@deadalnix: Nie powiedziałbym tego. C ++ ma złożone reguły, które mogą przynieść odwrót w optymalizatorze, ponieważ nie wolno robić pewnych rzeczy. I bardzo łatwo jest wejść w niewidzialnego zabójcę wydajności. Jest to prawie aksjomatyczne, a zatem prawdziwe: D W rzeczywistości kod C ++ czasami będzie szybszy, ponieważ będziesz używał bardziej efektywnych algorytmów i struktur danych, a i tak nikt nie zoptymalizuje kodu C. Więc jeśli poprawnie wykonane, C ++ jest bezpieczniejsze i bardziej efektywne C, i powinieneś wybrać C ++ zamiast C, gdy nie ma problemów ze zgodnością lub wymagań dotyczących oprogramowania zapewniającego 100% dostępności.
Koder,

4
Najlepszy powód, nieuwzględniony w opublikowanych odpowiedziach, odnosi się bezpośrednio do pytania OP. ZALEŻNOŚCI !!!!, Nie to, że przeciętny system nie ma bibliotek c ++, ale system wbudowany może ich nie mieć. Jedynym sposobem, aby uzyskać program w każdym systemie, jest napisanie programu w zwykłym C. Cała reszta dotyczy tylko tego, dlaczego nie powinieneś używać C ++. Nic z tego nie wyjaśnia, dlaczego C ++ nie jest używany częściej i niezależnie od zasług, przyczyną są zależności… O, a także słynna reguła c ++ Linusa.
JM Becker,

Odpowiedzi:


308

Kiedy idę na występ, pierwszym i ostatnim wyborem jest C.

I tam powinieneś wykonać kopię zapasową. Teraz nie mogę w ogóle mówić za rozwojem serwerów. Być może nie ma istotnego powodu, by preferować C ++ zamiast alternatyw.

Ale ogólnie rzecz biorąc, powodem używania C ++ zamiast innych języków jest rzeczywiście wydajność. Powodem tego jest to, że C ++ oferuje sposób abstrakcji, który, w przeciwieństwie do wszystkich innych języków, które znam, nie ma narzutu wydajności w czasie wykonywania.

Pozwala to na pisanie bardzo wydajnego kodu, który wciąż ma bardzo wysoki poziom abstrakcji.

Rozważ zwykłe abstrakty: funkcje wirtualne, wskaźniki funkcji i idiom PIMPL. Wszystkie opierają się na pośredniczeniu, które w czasie wykonywania jest rozwiązywane przez arytmetykę wskaźnika. Innymi słowy, wiąże się to z kosztem wydajności (jakkolwiek może być niewielkim).

Z drugiej strony C ++ oferuje mechanizm pośredni, który nie wiąże się z żadnymi kosztami (wydajności): szablonów. (Za tę korzyść płaci się (czasem znacznie) dłuższy czas kompilacji.)

Rozważ przykład ogólnej funkcji sortowania.

W C funkcja qsortprzyjmuje wskaźnik funkcji, który implementuje logikę, według której elementy są uporządkowane względem siebie. Arrays.sortFunkcja Java występuje w kilku wariantach; jeden z nich sortuje dowolnych obiektów i wymaga Comparatorobiekt przekazany do niego, który działa podobnie do wskaźnika funkcji w C użytkownika qsort. Ale istnieje jeszcze kilka przeciążeń dla „rodzimych” typów Java. I każdy z nich ma własną kopię sortmetody - okropne kopiowanie kodu.

Java ilustruje tutaj ogólną dychotomię: albo masz duplikację kodu, albo nakładasz na siebie czas działania.

W C ++ sortfunkcja działa podobnie jak qsortw C, z jedną małą, ale zasadniczą różnicą: komparator przekazywany do funkcji jest parametrem szablonu . Oznacza to, że wezwanie może być wstawiane . Do porównania dwóch obiektów nie jest wymagana żadna pośrednictwo. W ciasnej pętli (jak ma to miejsce w tym przypadku) może to naprawdę zrobić znaczącą różnicę.

Nic dziwnego, że sortfunkcja C ++ przewyższa C, sortnawet jeśli podstawowy algorytm jest taki sam. Jest to szczególnie widoczne, gdy rzeczywista logika porównywania jest tania.

Teraz jestem nie mówiąc, że C ++ jest a priori bardziej wydajny niż C (lub innych językach), ani że a priori oferuje większą abstrakcją. To, co oferuje, to abstrakcja, która jest jednocześnie bardzo wysoka i niesamowicie tania, dzięki czemu często nie trzeba wybierać między wydajnym a wielokrotnego użytku kodem.


16
Wiem teraz wystarczająco dużo o C ++, aby wiedzieć, czy jesteś na miejscu, czy nie. Ale chcę też dodać, że otrzymałeś tylko 1 ocenę, więc zrelaksuj się. To jest internet i zdarzają się przegłosowania. Świetna odpowiedź, jeśli jest to technicznie poprawne!
Chris

46
brak narzutu wydajności w czasie wykonywania - to nie zawsze prawda. Jeśli spojrzysz na implementacje wektorowe STL, zobaczysz, że nie wykorzystują one realloc () (nie mogą ze względu na wskaźniki, długą historię), podczas gdy wszystkie znane mi języki wyższego poziomu mogą używać realloc ( ) w wektorowym impl. To tylko jeden przykład, że nie jest to tak oczywiste i całkowicie czarno-białe.
mojuba

19
@Jaroslaw, @Steve: ale to samo (= rozdęcie kodu, pominięcie pamięci podręcznej instrukcji) jest prawdziwe dla kodu zoptymalizowanego ręcznie, który jest dostosowany do każdego typu danych (zobacz różne Arrays.sortimplementacje Javy ). Tylko Ty tracisz przewagę wysokiej abstrakcji. To nie jest szczególna wada szablonów, to wada duplikacji kodu w ogóle. Co więcej, zwykle nie ma to znaczenia, ponieważ w ciasnych pętlach zwykle jest zawsze ładowany ten sam kod.
Konrad Rudolph,

18
@Jarosław: zabawną rzeczą w buforze instrukcji jest to, że jest to pamięć podręczna . Oznacza to, że nie próbuje przechowywać wszystkiego , tylko ostatnio używany kod . Szablony mogą generować wiele podobnego kodu dla różnych typów (a vector.push_backdla vector<int>i inny dla vector<float>, ale podczas pracy z a vector<int>, nie ma żadnego powodu, dla którego vector<float>kod byłby w pamięci podręcznej instrukcji. Nie wiem więc, jak to naprawdę ma znaczenie. tworzenie pojedynczych szablonów jest wysoce zoptymalizowane i zazwyczaj bardziej kompaktowe niż ogólne implementacje typu catch-all
lipiec

29
@ Steve314: To, co nazywasz „wzdęciem”, jest wykonywane ręcznie dla C i Java. W C ++ można go zautomatyzować, a kompilatory mogą być tak inteligentne, jak producenci odważą się je zmusić, aby uniknąć wzdęć. Jeśli muszę zdecydować, czy będę powolny (jak w C), czy użyję zduplikowanego kodu (jak w Javie), posiadanie kompilatora wykonującego duplikację (i być może rozsądnego) wydaje się całkiem niezłe, prawda?
sbi

166

Widzę zbyt wielu programistów C, którzy nienawidzą C ++. Zajęło mi sporo czasu (lat), aby powoli zrozumieć, co jest dobre, a co złe. Myślę, że najlepszym sposobem na wyrażenie tego jest:

Mniej kodu, brak narzutu w czasie wykonywania, większe bezpieczeństwo.

Im mniej kodu piszemy, tym lepiej. Szybko staje się to jasne u wszystkich inżynierów dążących do doskonałości. Naprawiasz błąd w jednym miejscu, nie w wielu - raz wyrażasz algorytm i ponownie go używasz w wielu miejscach, itd. Grecy mają nawet powiedzenie wywodzące się od starożytnych Spartan: „powiedzieć coś krótszymi słowami, znaczy znaczy że jesteś o tym mądry ”. Faktem jest, że przy poprawnym użyciu C ++ pozwala wyrazić się w znacznie mniejszym kodzie niż C, bez kosztowania szybkości działania, a jednocześnie jest bezpieczniejszy (tzn. Wychwytuje więcej błędów w czasie kompilacji) niż C.

Oto uproszczony przykład z mojego renderera : Podczas interpolacji wartości pikseli na linii skanowania trójkąta. Muszę zacząć od współrzędnej X x1 i osiągnąć współrzędną X x2 (od lewej do prawej strony trójkąta). I na każdym kroku, na każdym mijanym pikselu muszę interpolować wartości.

Kiedy interpoluję światło otoczenia docierające do piksela:

  typedef struct tagPixelDataAmbient {
      int x;
      float ambientLight;
  } PixelDataAmbient;

  ...
  // inner loop
  currentPixel.ambientLight += dv;

Kiedy interpoluję kolor (nazywany cieniowaniem „Gouraud”, gdzie pola „czerwony”, „zielony” i „niebieski” są interpolowane wartością kroku na każdym pikselu):

  typedef struct tagPixelDataGouraud {
      int x;
      float red;
      float green;
      float blue;  // The RGB color interpolated per pixel
  } PixelDataGouraud;

  ...
  // inner loop
  currentPixel.red += dred;
  currentPixel.green += dgreen;
  currentPixel.blue += dblue;

Kiedy renderuję w cieniu „Phong”, nie interpoluję już intensywności (ambientLight) ani koloru (czerwony / zielony / niebieski) - interpoluję normalny wektor (nx, ny, nz) i na każdym kroku muszę ponownie -obliczyć równanie oświetlenia w oparciu o interpolowany wektor normalny:

  typedef struct tagPixelDataPhong {
      int x;
      float nX;
      float nY;
      float nZ; // The normal vector interpolated per pixel
  } PixelDataPhong;

  ...
  // inner loop
  currentPixel.nX += dx;
  currentPixel.nY += dy;
  currentPixel.nZ += dz;

Pierwszym instynktem programistów C byłoby „cholera, napisz trzy funkcje interpolujące wartości i wywołaj je w zależności od ustawionego trybu”. Przede wszystkim oznacza to, że mam problem z typem - z czym mam pracować? Czy moje piksele to PixelDataAmbient? PixelDataGouraud? PixelDataPhong? Och, czekaj, sprawny programista C mówi: użyj unii!

  typedef union tagSuperPixel {
      PixelDataAmbient a;
      PixelDataGouraud g;
      PixelDataPhong   p;
  } SuperPixel;

... a następnie masz funkcję ...

  RasterizeTriangleScanline(
      enum mode, // { ambient, gouraud, phong }
      SuperPixel left,
      SuperPixel right)
  {
      int i,j;
      if (mode == ambient) {
          // handle pixels as ambient...
          int steps = right.a.x - left.a.x;
          float dv = (right.a.ambientLight - left.a.ambientLight)/steps;
          float currentIntensity = left.a.ambientLight;
          for (i=left.a.x; i<right.a.x; i++) {
              WorkOnPixelAmbient(i, dv);
              currentIntensity+=dv;
          }
      } else if (mode == gouraud) {
          // handle pixels as gouraud...
          int steps = right.g.x - left.g.x;
          float dred = (right.g.red - left.g.red)/steps;
          float dgreen = (right.g.green - left.a.green)/steps;
          float dblue = (right.g.blue - left.g.blue)/steps;
          float currentRed = left.g.red;
          float currentGreen = left.g.green;
          float currentBlue = left.g.blue;
          for (j=left.g.x; i<right.g.x; j++) {
              WorkOnPixelGouraud(j, currentRed, currentBlue, currentGreen);
              currentRed+=dred;
              currentGreen+=dgreen;
              currentBlue+=dblue;
          }
...

Czy odczuwasz chaos?

Po pierwsze, jedna literówka jest wszystkim, co jest potrzebne do awarii mojego kodu, ponieważ kompilator nigdy nie zatrzyma mnie w sekcji „Gouraud” funkcji, aby faktycznie uzyskać dostęp do „.a”. wartości (otoczenia). Błąd, który nie został przechwycony przez system typu C (to znaczy podczas kompilacji), oznacza błąd, który pojawia się w czasie wykonywania i będzie wymagał debugowania. Czy zauważyłeś, że korzystam left.a.greenz obliczeń „dgreen”? Kompilator na pewno ci tego nie powiedział.

Potem wszędzie jest powtórzenie - forpętla istnieje tyle razy, ile jest trybów renderowania, cały czas wykonujemy „prawo minus lewo podzielone przez kroki”. Brzydki i podatny na błędy. Czy zauważyłeś, że porównuję za pomocą „i” w pętli Gourauda, ​​kiedy powinienem był użyć „j”? Kompilator znów jest cichy.

Co z instrukcją if / else / ladder dla trybów? Co jeśli dodam nowy tryb renderowania za trzy tygodnie? Czy będę pamiętać, aby obsługiwać nowy tryb we wszystkich „if mode ==” w całym moim kodzie?

Teraz porównaj powyższą brzydotę z tym zestawem struktur C ++ i funkcją szablonu:

  struct CommonPixelData {
      int x;
  };
  struct AmbientPixelData : CommonPixelData {
      float ambientLight;
  };
  struct GouraudPixelData : CommonPixelData {
      float red;
      float green;
      float blue;  // The RGB color interpolated per pixel
  };
  struct PhongPixelData : CommonPixelData {
      float nX;
      float nY;
      float nZ; // The normal vector interpolated per pixel
  };

  template <class PixelData>
  RasterizeTriangleScanline(
      PixelData left,
      PixelData right)
  {
      PixelData interpolated = left;
      PixelData step = right;
      step -= left;
      step /= int(right.x - left.x); // divide by pixel span
      for(int i=left.x; i<right.x; i++) {
          WorkOnPixel<PixelData>(interpolated);
          interpolated += step;
      }
  }

Teraz spójrz na to. Nie produkujemy już zupy typu uni: mamy określone typy dla każdego trybu. Ponownie używają swoich wspólnych elementów (pola „x”), dziedzicząc po klasie bazowej ( CommonPixelData). A szablon sprawia, że ​​kompilator UTWORZA (czyli generuje kod) trzy różne funkcje, które sami napisalibyśmy w C, ale jednocześnie bardzo rygorystycznie pod względem typów!

Nasza pętla w szablonie nie może goof i uzyskiwać dostępu do nieprawidłowych pól - jeśli to zrobimy, kompilator będzie szczekał.

Szablon wykonuje wspólną pracę (pętla, za każdym razem zwiększając się o „krok”) i może to zrobić w sposób, który po prostu NIE MOŻE powodować błędów w czasie wykonywania. Interpolacja od rodzaju ( AmbientPixelData, GouraudPixelData, PhongPixelData) odbywa się za operator+=()które dodamy w elemencie - co w zasadzie dyktują jak każdy typ jest interpolowana.

Czy widzisz, co zrobiliśmy z WorkOnPixel <T>? Chcemy wykonać inną pracę dla każdego typu? Po prostu nazywamy specjalizację szablonu:

void WorkOnPixel<AmbientPixelData>(AmbientPixelData& p)
{
    // use the p.ambientLight field
}


void WorkOnPixel<GouraudPixelData>(GouraudPixelData& p)
{
    // use the p.red/green/blue fields
}

To znaczy - funkcja do wywołania jest ustalana na podstawie typu. W czasie kompilacji!

Aby ponownie sformułować:

  1. minimalizujemy kod (poprzez szablon), ponownie wykorzystując wspólne części,
  2. nie używamy brzydkich hacków, utrzymujemy ścisły system typów, dzięki czemu kompilator może nas zawsze sprawdzać.
  3. a co najważniejsze: żadne z naszych działań nie miało ŻADNEGO wpływu na środowisko uruchomieniowe. Ten kod będzie działał TYLKO tak szybko, jak równoważny kod C - w rzeczywistości, jeśli kod C używał wskaźników funkcji do wywoływania różnych WorkOnPixelwersji, kod C ++ będzie SZYBSZY niż C, ponieważ kompilator wprowadzi WorkOnPixelspecjalizację szablonu specyficzną dla typu połączenie!

Mniej kodu, brak narzutu w czasie wykonywania, większe bezpieczeństwo.

Czy to oznacza, że ​​C ++ jest językiem typu „wszystko na końcu”? Oczywiście nie. Nadal musisz mierzyć kompromisy. Ignoranci używają C ++, kiedy powinni napisać skrypt Bash / Perl / Python. Zadowoleni z wyzwalaczy nowicjusze C ++ utworzą głęboko zagnieżdżone klasy z wirtualnym wielokrotnym dziedziczeniem, zanim będzie można je zatrzymać i wysłać. Będą używać złożonego metaprogramowania Boost, zanim zdadzą sobie sprawę, że nie jest to konieczne. Będą nadal używać char*, strcmpi makr zamiast std::stringi szablonów.

Ale to nic więcej niż ... patrz, z kim pracujesz. Nie ma języka, który chroniłby cię przed niekompetentnymi użytkownikami (nie, nawet Java).

Studiuj i używaj C ++ - po prostu nie przesadzaj.


18
+1 za „nie, nawet Java” :)
Nathan Osman

53
+1 na przykład. To był długi post, ale porównanie między C i C ++ jest imponujące.
paercebal

To właśnie, panie i panowie, istnieje lex / yacc. Z tego samego powodu nigdy nie zdawałem sobie sprawy, że części c ++ są zgodne z tą samą filozofią generowania kodu. Będę musiał kiedyś jeszcze raz na to spojrzeć.
Spencer Rathbun

2
Napisałem dużo kodu do renderowania 2D (ponad dekadę temu) i napotkałem ten problem podczas przenoszenia z C do C ++: jak zdefiniować strukturę pikseli, jeśli twoja linia skanowania składa się z pikseli 1-bitowych (8 pikseli w bajt)? A kiedy twoja linia skanowania składa się z bajtów R, G i B (3 bajty na piksel)? A kiedy masz trzy oddzielne bufory dla R, G i B? Znasz odpowiedź: C ++ nie pomaga, a naleganie na użycie szablonów sprawi, że stracisz dużo optymalizacji przestrzeni i czasu
Walter Tross,

Dlaczego używasz do tego szablonów w C ++? Twoja metoda deklaruje parametr klasy bazowej, więc z mojego punktu widzenia [programisty C #] wygląda na to, że możesz po prostu przekazać instancję typu pochodnego do parametru typu bazowego. Nie znam C ++, czy mógłbyś wyjaśnić?
Vlad

79

RAII dla zwycięskiego dziecka.

Poważnie, deterministyczne zniszczenie w C ++ sprawia, że ​​kod jest znacznie bardziej przejrzysty i bezpieczny, bez żadnych kosztów ogólnych.


20
„C ++: jedyna poważna deterministyczna opcja. Zapytaj dziś swojego lekarza.”
Kyle Strand

2
Dalsze działania: Rdza jest teraz pretendentem w tej dziedzinie. Zobacz podstawowy przykład RAII i dokumentację na temat metod Destruktora Rust .
Kyle Strand,

1
C będzie jako deterministyczny, ale wymaga więcej pracy, aby upewnić się, że rzeczywiście się dzieje, gdy używana jest pamięć malloc-ED
Baldrickk

1
@Baldrickk w C musisz pisać kod czyszczenia wszędzie tam, gdzie używasz zasobu. W C ++ piszesz go raz , w definicji zasobu. Zarówno C, jak i Java cierpią z powodu błędów „zasobów używanych po usunięciu” i „wycieków zasobów”, ponieważ czyszczenie nie jest automatyczne . Pamięć nie jest jedynym zasobem.
Caleth,

70

Czy istnieje zadowalający powód do używania C ++?

  1. Szablony i STL. Wymieniasz trochę czasu kompilacji (i niektóre potencjalnie niezrozumiałe komunikaty o błędach) na wiele użytecznych narzędzi abstrakcyjnych i oszczędzających pracę, bez zauważalnego spadku wydajności w czasie wykonywania (chociaż binarny ślad może być nieco większy).

    Zajmuje trochę czasu (zajęło mi to kilka lat, zanim kliknęło), ale kiedy to zrobisz, życie może być znacznie prostsze.

  2. Przetwarzanie tekstu w C ++ jest o rząd wielkości mniej bolesne niż w C.


35
+1 za przetwarzanie tekstu, o którym całkowicie zapomniałem w swojej odpowiedzi.
Konrad Rudolph,

8
Heh Uważam, że przetwarzanie tekstu jest szczególnie bolesne w porównaniu do powiedzmy Python ..
Nils,

7
Boost jest jedynym powodem, dla którego wciąż używam C ++.
Ferruccio,

33
@Nils: W skali od 1 do bezsensownego przetwarzanie tekstu w C ++ jest zdecydowanie gorsze niż w bardziej współczesnych językach, takich jak Python. Po prostu przetwarzanie tekstu w C definiuje ból w dupie. Jeśli wybór dotyczy C i C ++ dla tej konkretnej aplikacji, wtedy C ++ wygrywa łatwo.
John Bode

8
Nie wiem, dlaczego ludzie mają takie trudności z przetwarzaniem tekstu w C / C ++. Po prostu skorzystaj z biblioteki lub napisz własną. Po napisaniu funkcji niskiego poziomu (jednorazowy ból) zyskujesz ogromną wydajność, ścisły kod i większą elastyczność. Tak, użyję Pythona do szybkich / brudnych narzędzi wiersza poleceń, ale do poważnego kodu produkcyjnego jest to C / C ++.

41

Tak.

Jeśli szukasz wydajności wykonywalnej, wybierasz C lub C ++, więc skupię się na tym.

Nawet zanim szablony stały się popularne, wolałem używać C ++ niż C do rodzajów plików wykonywalnych, które omawiasz już w połowie lat 90. z dwóch bardzo prostych powodów: polimorfizmu obiektów i RAII .

Użyłem polimorficznych obiektów C ++ do wszelkiego rodzaju interesujących rzeczy. Na przykład pracowałem nad wbudowanym systemem Linux z nakładkami bufora ramek na procesorach OMAP i XScale ARM. Dwie architektury sprzętowe mają różne funkcje nakładania z bardzo różnymi interfejsami API. Użyłem wspólnej wirtualnej klasy podstawowej „Nakładka”, aby wyświetlić wyidealizowany widok nakładek, a następnie napisałem klasy „OmapOverlay” i „XScaleOverlay”, które zostały odpowiednio utworzone w czasie wykonywania, w zależności od architektury, na której wykrył kod.

Aby nadmiernie uprościć, RAII jest pomysłem, że alokujesz zasoby podłączone do obiektu podczas konstruktora obiektu, a może później w trakcie życia obiektu, a zasoby są zwalniane lub zwalniane w destruktorze obiektu. To naprawdę miłe w C ++, ponieważ obiekty, które są zmiennymi automatycznymi, są niszczone, gdy wykraczają poza zakres. Dla kogoś, kto jest równie kompetentny w C i C ++, o wiele łatwiej jest uniknąć wycieków zasobów i pamięci w C ++. Nie widzisz również zbyt wiele kodu C ++ z bardzo popularnym memem C etykiety na końcu funkcji poprzedzającej kilka wywołań do free(), a różne gotow bloku funkcyjnym tam skaczą.

Jestem w pełni świadomy, że możesz robić wszystkie te rzeczy za pomocą C - to po prostu dużo więcej pracy, znacznie więcej linii kodu, a to, co kończysz, jest o wiele brzydsze i często trudniejsze do zrozumienia. Istnieje kod polimorfizmu na wszystkich wewnętrznych elementach X serwera , a człowieku, jest niezręcznie i dziwnie i często trudny do prześledzenia.

Dużo pracuję również z technologiami GNOME, takimi jak GTK + i Clutter, z których wszystkie są napisane w C przy użyciu systemu GObject. GObject jest jak system obiektowy C ++ ze zdjętą ładną osłoną i odsłoniętymi wszystkimi brzydkimi elementami wewnętrznymi, i zwykle wymaga pół tuzina wierszy kodu, aby zrobić to, co zrobiłaby jednowierszowa metoda wywołania metody C ++. Obecnie piszę trochę ClutterActorsi chociaż matematyka jest naprawdę interesująca, ciągle myślę: „To wszystko byłoby o wiele bardziej zwięzłe i zrozumiałe w C ++”.

Często też myślę: „Wiesz, gdybym pisał to w C ++ zamiast C, byłbym w salonie, oglądając MythBusters z żoną, zamiast siedzieć w biurze o 21:00”.


9
Mogę naprawdę odnieść się do tego, co tu mówisz, szczególnie 1) kwestii RAII i 2) myśli „Wiesz, gdybym pisał to w C ++ zamiast C ...” Robię dużo rozwoju systemów wbudowanych , a nawet jeśli zespół jest raczej sklepem typu „C” lub „C z klasami”, naprawdę staram się zachęcić RAII do takich rzeczy, jak manipulowanie przerwaniami, operacje mutexów i śledzenie / rejestrowanie (zwłaszcza takie jak przełączanie We / Wy linie). A twój opis polimorficznych buforów ramek przypomniał mi o moim zastosowaniu polimorficznych buforów komunikatów w systemie rozproszonym.
Radian,

29

C ++ jest mniej więcej tak szybki jak C (niektóre rzeczy są szybsze, niektóre wolniejsze) i oferuje lepsze abstrakcje i organizację. Klasy działają podobnie jak prymitywne typy, pozwalając na użycie dużej ilości kodu bez konieczności pamiętania o tym. Przeciążenie operatora i szablony umożliwiają pisanie kodu, który działa lepiej w przypadku zmiany reprezentacji danych. Wyjątki mogą umożliwić łatwiejszą obsługę błędów. Kompilatora można używać do sprawdzania większej liczby rzeczy w czasie kompilacji.

Cena za to jest dość nieprzyjemną krzywą uczenia się i łatwiej jest popełnić w niej subtelne błędy niż w większości innych języków, które znam.

Nie mogę więc powiedzieć, czy warto nauczyć się tego, co robisz teraz. Z pewnością można sobie poradzić z kombinacjami Pythona lub Perla i C, ale C ++ oferuje zarówno abstrakcję, jak i wydajność w jednym trudnym do przyzwyczajenia pakiecie.


13
Nie ma przypadku, w którym C ++ jest wolniejszy niż C, ponieważ zawsze możesz użyć sposobu C, jeśli jest on szybszy (i zależy ci).
Jack Aidley

1
@JackAidley - z wyjątkiem tego, że C ++ nie obsługuje ograniczonych i statycznych parametrów tablicy. I poza tym użycie stylu C ++ w jednym miejscu zmusza do użycia go w innych miejscach.
martinkunev

@martinkunev restrictsłuży do wykluczania optymalizacji aliasingu, więc jak to przyspiesza działanie ? a czym jest „parametr tablicy statycznej”? i jak „styl” wpływa na wydajność?
underscore_d

1
@underscore_d ograniczenie pozwala na optymalizacje w oparciu o gwarancję braku aliasingu; parametry tablicy statycznej pozwalają kompilatorowi założyć, że argument wskaźnika nie ma wartości NULL i że wskaźnik ten wskazuje na co najmniej określoną liczbę elementów; słowo „styl” ma kilka znaczeń, a usunięcie go z kontekstu zmienia jego znaczenie - mówię o tym, jak na przykład wyjątki wymuszają użycie inteligentnych wskaźników.
martinkunev 21.04.16

1
@martinkunev Hmm, więc zastanawiam się, czy parametr tablicy statycznej umożliwia funkcjonalnie coś innego niż szablon C ++ przy użyciu T (&arr)[n]lub std::array<T, n>- będzie musiał to jeszcze zbadać, ponieważ nie ma tam wielu informacji. Ma to sens w przypadku inteligentnych wskaźników, zdecydowanie dobry przykład. Jeśli kodujemy na równych zasadach, nie wykorzystalibyśmy wyjątków, więc żaden potencjalny koszt nie zostałby poniesiony ... jednak podejrzewam, że możesz mieć na myśli aluzje, w jaki sposób, kiedy biblioteki stron trzecich wejdą na obraz, wiele założeń Są zagrożone.
underscore_d

27

Uważam C ++ za język lat 90., język minionej epoki.

Wtedy był duży, ponieważ oferował konstrukcje i mechanizmy języka wyższego poziomu przy niższych kosztach pod względem wydajności. Było to uniwersalne narzędzie do opracowywania wszystkiego, od aplikacji książki adresowej po oprogramowanie awioniki, co zainspirowało szał OO. OOP rozwiązało głód i AIDS, i tak, obwiniam C ++ za próbę prania mózgu pod koniec lat 90., kiedy zacząłem programować, że żaden język inny niż OO nie jest wart nauki.

Teraz, gdy sprzęt jest tak zaawansowany i pojawiły się nowsze, pojawiły się nowoczesne języki, nie widzę, aby C ++ pozostawał odpowiednim wyborem dla większości programowania aplikacji, z wyjątkiem oprogramowania wymagającego intensywnych obliczeń, w którym wciąż potrzebujesz pewnej abstrakcji (gry, symulacje fizyki, systemy CAD itp. ). Tego drugiego można uniknąć, jeśli napiszesz kompaktowy, modułowy silnik w języku C, a logikę aplikacji wyższego poziomu przekażesz porządnemu językowi skryptowemu.

Jeśli chcesz przejść do metalu, użyj C, a kiedy chcesz przejść na wyższy poziom, zrób to w nowoczesnym języku, który nie reklamuje enkapsulacji, podczas gdy możesz swobodnie zmieniać każdy bajt za pomocą wskaźnika.


11
Więc nie zmieniaj losowych bajtów za pomocą wskaźników. Nie jest to takie trudne do uniknięcia, prawda?
David Thornley,

11
@Blagovest: Zgadzam się z Tobą co do złożoności C ++ i nigdy nie użyłbym jej do zastąpienia języka zorientowanego obiektowo. Ale pomimo złożoności nadal wygrywa dla mnie z C ze względu na wiele zalet wyrażonych w różnych odpowiedziach (abstrakcja, przekazywanie zasobów, obsługa ciągów znaków ...). W rzeczywistości wymieniłeś kilka ważnych obszarów, w których C ++ jest nadal aktualny i gdzie jest znacznie lepszy od C.
Konrad Rudolph,

6
@Blagovest: Dlatego trzymam się z dala od ciemnych kątów. Łatwiej jest dostać się tam w C ++ niż w jakimkolwiek innym języku, który znam. Korzystając z niego, czerpię korzyści z RAII, znacznie lepszej obsługi ciągów niż C, klas szablonów typu STL, funkcji OO i innych zalet, które ma w stosunku do C.
David Thornley,

24
@Blagovest: Nie, ty nie. Na przykład to, co wspomniałeś, jest niewystarczające do osiągnięcia RAII, a klasy kontenerów mają funkcjonalność wykraczającą poza proste ręcznie tworzone struktury danych. Jeśli uważasz, że to możliwe, nigdy nie nauczyłeś się dobrze C ++.
David Thornley,

5
@Jaroslaw Nie rozumiem, dlaczego maszyny wielordzeniowe doprowadziłyby OOP do grobu. Jeśli masz na myśli C ++, mogę zobaczyć, skąd pochodzisz. OOP jest podstawową koncepcją w wielu współczesnych językach programowania, zwłaszcza językach wysokiego poziomu. Nawet C może być OO, jeśli zaprogramujesz to w ten sposób. To po prostu nie tak wygodne jak C ++ IMO.
vedosity

21

Według Linusa nie:

Kiedy po raz pierwszy spojrzałem na kod źródłowy Gita, dwie rzeczy wydawały mi się dziwne: 1. Czyste C w przeciwieństwie do C ++. Nie mam pojęcia dlaczego. Proszę nie mówić o przenośności, to BS.

TY jesteś pełen bzdur.

C ++ to okropny język. Staje się to jeszcze bardziej przerażające, ponieważ używa go wielu programistów, którzy nie spełniają norm, do tego stopnia, że ​​znacznie łatwiej jest wygenerować z nim totalne badziewie. Szczerze mówiąc, nawet gdyby wybór C nie miał nic innego, jak tylko powstrzymać programistów C ++, to samo w sobie byłoby ogromnym powodem do użycia C.

Innymi słowy: wybór C jest jedynym rozsądnym wyborem. Wiem, że Miles Bader żartobliwie powiedział „wkurzyć cię”, ale to prawda. Doszedłem do wniosku, że każdy programista, który wolałby projekt w C ++ niż C, jest prawdopodobnie programistą, którego naprawdę wolałbym wkurzyć, aby nie przyszedł i nie spieprzył żadnego projektu, w który jestem zaangażowany z.

C ++ prowadzi do naprawdę bardzo złych wyborów projektowych. Niezmiennie zaczynasz używać „ładnych” funkcji bibliotecznych języka, takich jak STL i Boost oraz innych totalnych badziewów, które mogą „pomóc” w programowaniu, ale powodują:

  • nieskończone ilości bólu, kiedy nie działają (i każdy, kto mówi mi, że STL, a zwłaszcza Boost są stabilne i przenośne, jest tak pełen BS, że nawet nie jest zabawny)

  • niewydajne abstrakcyjne modele programowania, w których dwa lata później zauważasz, że niektóre abstrakty nie były bardzo wydajne, ale teraz cały twój kod zależy od wszystkich ładnych modeli obiektowych wokół niego i nie możesz go naprawić bez przepisywania aplikacji.

Innymi słowy, jedynym sposobem na zrobienie dobrego, wydajnego, przenośnego C ++ na poziomie systemowym jest ograniczenie się do wszystkich rzeczy, które są zasadniczo dostępne w C. Ograniczenie projektu do C oznacza, że ​​ludzie tego nie zepsują a także oznacza, że ​​masz wielu programistów, którzy faktycznie rozumieją problemy niskiego poziomu i nie psują rzeczy żadnym idiotycznym bzdurnym „modelem obiektowym”.

Przykro mi, ale dla czegoś takiego jak git, w którym wydajność była głównym celem, „zalety” C ++ to tylko wielki błąd. Fakt, że wkurzamy również ludzi, którzy tego nie widzą, to duża dodatkowa zaleta.

Jeśli chcesz VCS napisany w C ++, zagraj w Monotone. Naprawdę. Używają „prawdziwej bazy danych”. Używają „ładnych bibliotek obiektowych”. Używają „ładnych abstrakcji C ++”. I szczerze mówiąc, w wyniku wszystkich tych decyzji projektowych, które brzmią tak atrakcyjnie dla niektórych osób z CS, efekt końcowy jest okropnym i niemożliwym do utrzymania bałaganem.

Ale jestem pewien, że bardziej ci się spodoba.

      Linus

62
Nie sądzę, że Linus powinien być facetem, z którym można się tutaj spierać. Jego tyrady są okropnie subiektywne i niedojrzałe. W rzeczywistości ma kilka dobrych punktów, ale są one tak głęboko zakopane (poniżej „bzdur”, jak i bzdur), że bardzo trudno je znaleźć.
Konrad Rudolph,

19
Haha, to był dobry śmiech. Nigdy nie chcę spotkać tego faceta.
Felix Dombek

30
Linus przypomina mi bardzo utalentowanego dekarza, który nigdy nie wisiał sheetrock, ale nazywa facetów sheetrock bratkami, ponieważ używają śrub zamiast gwoździ.
Bob Murphy,

8
Linus ma rację, ale wyraża to zbyt surowo, by traktować ją poważnie.
Blagovest Buyukliev

39
Zgadzam się z @Daniel, jeśli jest ktoś, kto może mówić o przekraczaniu granic sprzętowych, to John Carmack jest twórcą doom, quake i innych gier oraz założycielem oprogramowania Id. Kilka miesięcy temu pisze o C i C ++ na Twitterze: „IMO, dobry kod C ++ jest lepszy niż dobry kod C, ale zły C ++ może być znacznie gorszy niż zły kod C”. twitter.com/#!/ID_AA_Carmack/status/26560399301
Onema

18

Nie sądzę, żeby istniał jakiś ważny powód, aby używać C ++. Jeśli chcesz programować OO, możesz zamiast tego użyć Pythona i napisać części wymagające szybkiej wydajności w C.

EDYCJA: Istnieją inne języki, które dobrze współpracują z C, więc jeśli nie lubisz Pythona, istnieją alternatywy.


3
Co z wbudowanym programowaniem? Python nie zawsze jest dostępny, a różnica prędkości między C a dobrze napisanym C ++ jest nieistotna na urządzeniach, które osiągnęły pewien poziom mocy obliczeniowej. Oczywiście przypuszczam, że kompilator C ++ nie zawsze byłby dostępny ...
James

6
@James „dobrze napisane C ++” - jest haczyk :(
dss539

5
Zgadzam się z tą odpowiedzią, rób wysoki poziom pythonem, ponieważ napiszesz coś około 3 razy szybciej, profilujesz, a następnie zwolnisz wąskie gardła, zastępując je C / C ++. Nadmiarowe jest mówienie „zamień wąskie gardło kodem C ++”, ponieważ nie zrobisz żadnego wysokiego poziomu kodem, który musisz być szybki, ponieważ będzie to kod niskiego poziomu. Jest jedna rzecz: nie wiem, jak połączyć c ++ z python: /. ale jeśli chodzi o czas spędzony przed ekranem i wydajność, myślę, że to najlepsze rozwiązanie, ponieważ większość kodu C ++ będzie działać szybko!
Jokoon

8
Idź do pracy dla dużej firmy finansowej i zbuduj złożony system finansowy w dużym rozproszonym zespole w Pythonie i zobacz, jak ci się podoba. Doświadczenie nauczy Cię: a) zalet bezpieczeństwa typu, b) zalet kompilatorów oszczędzających tyłek, c) LUDICROUS kod, który Python pozwala na pisanie noobów. Ludzie mówią, że łatwo jest strzelać w C ++ -> niektóre rzeczy w Pythonie mogą działać, ale mogą być szaleństwem na granicy. W tej chwili wolałbym raczej pracować w C ++ ...
MrFox

1
@suslik: Wow, jestem zszokowany, że ktoś faktycznie używałby Pythona w tego rodzaju systemie. Zgadzam się z tobą w sprawie złego kodu pytona noob; Sam trochę widziałem.
Larry Coleman,

13

Czy istnieje powód do używania C ++? Na pewno.

Niektóre osoby mogą po prostu preferować używanie C ++ niż inne opcje. Pytanie, czy istnieje powód do używania C ++, jest jak pytanie, dlaczego musimy mieć setki smaków lodów. Nie każdy lubi po prostu trzymać się wanilii.

Jeśli programiści są już bardzo biegli w posługiwaniu się C ++, pytanie może nie brzmieć „dlaczego z niego korzystać?”, A raczej „dlaczego nie?”. Wydaje się, że w SO dzieje się teraz modna anty-C ++, ale wierzcie lub nie, nie wszyscy się na to zgadzają. Niektórzy ludzie mogą po prostu lubić C ++ lepiej niż inne języki.

Czy C ++ trzeba być wykorzystywane do aplikacji? Oczywiście nie. Ale to samo dokładne pytanie można zadać również w innym języku. Jest bardzo, bardzo niewiele przypadków, w których należy użyć określonego języka dla aplikacji.


12

Właśnie przechodzę z C na C ++ i myślę, że zysk jest znaczny, nawet jeśli nie potrzebujesz szablonów i OOP.

  • Lepsze zarządzanie pamięcią
  • Silniejszy system typów
  • Lepsza standardowa biblioteka
  • Przestrzenie nazw
  • itp.

8

Dziwię się, że nikt jeszcze o tym nie wspominał, ale C ++ wprowadził nas do referencji , które prawie rozwiązały wszystkie problemy i pułapki wskaźników:

void ModifyVar(int& var)
{
    var = 5;
}

int test = 4;
ModifyVar(test);

Zamiast:

void ModifyVar(int * var)
{
    *var = 5;
}

int test = 4;
ModifyVar(&test);

O wiele bezpieczniejsze i łatwiejsze ... i bez dodatkowych kosztów.


3
Również znacznie mniej elastyczny. Odniesienia (w stylu C ++) dobrze upraszczają niektóre popularne konstrukcje w języku, który również zawiera wskaźniki, ale jak dotąd nie zastępują wskaźników, nie jest nawet zabawne. Twój przykład wcale nie jest dobrym przykładem na referencje.
Ben Voigt,

3
@Ben: Czy możesz zatem wyjaśnić, dlaczego jest to zły przykład?
Nathan Osman

6
@George: Ponieważ nic się nie zmieniło, z wyjątkiem tego, że są dwa (liczą) znaki krótsze? Nie rozwiązuje żadnych problemów, nie uwypukla żadnych pułapek, nie robi nawet nic fajnego, jak przedłużyć żywotność zmiennej tymczasowej (w której referencje są dobre).
Ben Voigt,

@Ben: Coś zapomniałeś - referencja jest zawsze aktualna. Wskaźniki mogą wskazywać na wszystko (w tym NULL), co może prowadzić do różnego rodzaju błędów pamięci, jeśli coś nie zostanie zrobione dobrze. Odwołania nigdy nie mogą mieć wartości NULL, a adresu, na który wskazują, nigdy nie można zmienić.
Nathan Osman

5
@George: „odwołanie jest zawsze ważne” jest błędne. Podam przykład, jeśli będziesz go potrzebować, ale mam nadzieję, że jesteś wystarczająco ekspertem, aby już o tym wiedzieć. Nie mówię też o tworzeniu nieprawidłowego odwołania za pomocą nieprawidłowego wskaźnika. Funkcje korzystające ze wskaźników wymagają dokumentacji określającej warunki wstępne argumentów. Ale praktycznie wszystkie funkcje wymagają tego poziomu dokumentacji, więc absurdem jest nazywać to atakiem na wskaźniki.
Ben Voigt,

5

Gdzie i dlaczego zwykle będą:

  • znajomość
  • pożądane funkcje językowe
  • określone biblioteki, których chcesz użyć
  • wymagania dotyczące wydajności

Do programowania po stronie serwera często możesz wybierać spośród wielu różnych języków, skompilowanych lub zinterpretowanych. Zwykle wybór języka zależy od platformy, na której Ty lub Twój zespół będziecie najbardziej efektywni. Lub jeśli nie masz jeszcze zespołu, dostępność umiejętności na rynku.

Na marginesie, naprawdę nie rozumiem decydowania o użyciu C / C ++ na podstawie wydajności (tylko), ponieważ wiele języków skryptowych jest rozszerzalnych z C / C ++. Korzyści płynące z szybkiego języka programowania w połączeniu z możliwością migracji wolnych części do rozszerzeń C / C ++. Z pewnością jeśli twoje programowanie systemów, w których liczy się każda operacja, jest zrozumiałe, ale w większości aplikacji nie rozumiem tego.


2
Znajomość jest powodem numer jeden i jestem zaskoczony, że jako pierwszy o niej wspominasz.
Paul Butcher,

4

C ++ vs Python vs Perl nie można łatwo ocenić. To zależy od projektu i wymagań.

C ++ ma arsenał narzędzi z dawnych czasów, działających na wielu platformach. Ale bolesne jest rozpoczynanie przechodzenia przez strumienie, aby po prostu przekazać String do liczby całkowitej i odwrócić.

Z drugiej strony, C ++ ma okropne problemy z zależnością od bibliotek. Gdy skompilujesz coś w GCC X lub VC ++ Y, nie możesz polegać na tym, że kod będzie działał w następnej wersji tych narzędzi. To samo piekło jest w systemie Windows, to samo piekło jest również w systemie Unix.

Perl czerpie swoją moc ze świata uniksowego, ale przede wszystkim jako narzędzie do wyrażeń regularnych. To jest używane przez większość czasu. Wraz z kilkoma poważnymi narzędziami, których nawet Java nie może zrobić w normalny sposób (sprawdź, jak przesłać plik na serwer WWW), Perl „po prostu zrób to”.

Python jest łatwym, elastycznym i dynamicznym językiem. Skrypt jest tak łatwy, że możesz wysłać liczbę całkowitą do funkcji, oczekuje łańcucha, ale możesz uzyskać wynik! Nieoczekiwany, ale wynik. Dlatego programista musi być bardzo ostrożny. IDLE oferuje pewne debugowanie, ale kiedy masz TELNET do systemu lub SSH'ed na trzech poziomach w dół i chcesz znaleźć swój problem, debugger nie będzie tam, aby stać obok ciebie. Ale potrafi szybko wykonać świetną pracę matematyczną.

Java to ekosystem modnych słów, obcych technologii i wielkich słów, a gdy chcesz po prostu przesłać plik na serwer WWW, możesz to zrobić tylko wtedy, gdy serwer ma JSP . Jeśli chcesz wywoływać biblioteki systemowe lub funkcje systemowe, takie jak monitorowanie, okazuje się, że musisz dużo wykopać. A może, aby dotrzeć do JNI i OK… myślisz wtedy… „Dlaczego, Panie?”

Poza tym Java jest świetnym narzędziem dla pakietów biznesowych, a wielowątkowość bardzo mi się podobała.

Szybko utwórz program i pokaż swoje CV: „Och, ja też wiem, że ta technologia” i twój niedoszły szef, bądźcie zaskoczeni! Chociaż technologia może nie być potrzebna ... (OK, ludzie, nienawidzę Spring Framework ....)


1
niestety, musisz wziąć pod uwagę, że Python ma zależności wersji - szczególnie po migracji do Pythona 3, to samo z Perlem ... czy ktoś jeszcze próbował przejść na Perla 6? Wszystko ma nieprzyjemne zależności :(
gbjbaanb

3

Wybierając język, należy pamiętać o korzyściach płynących z jego używania oraz o tym, ile czasu to zajmie.

Główną ideą między językami takimi jak Python i Perl jest zrobienie więcej przy mniejszym czasie pracy, ale przy większej ilości procesora. W rzeczywistości poświęcisz więcej czasu na kodowanie skryptu python lub perl, niż zostanie on wykonany, ale rozumiesz.

Zaletą C / C ++ jest to, że są szybkie, ale kosztem składni i silnego pisania: musisz wiele zrobić sam, aby komputer nie wybrał tego w czasie kompilacji.

Kiedy tworzysz kod, niektóre wiersze będą uruchamiane o wiele bardziej niż inne, a te wiersze stanowią problem. Z drugiej strony cała reszta kodu, nad którą spędziłeś dużo czasu, jest wykonywana znacznie rzadziej. Być może słyszałeś o tym, ale jest to niesławna reguła 80/20 i nie będziesz w stanie ominąć takiej reguły.

Rozwiązaniem tego problemu jest użycie prostszego języka (przez łatwiejsze rozumiem bardziej przyjazny dla programistów: mniej pisania, leniwa interpretacja, wiele wcześniejszych procedur i innych rzeczy itp.) Do zrobienia całego kodu.

Zrobisz to tak szybko w porównaniu do tego, co zrobiłbyś z C lub C ++, zajęłoby to znacznie więcej bólu mózgu.

Twój program będzie działał wolno, ale dzięki profilerowi izolujesz część, która jest uruchamiana przez 80% czasu i robisz to za pomocą C lub C ++.

W ten sposób zaoszczędziłeś dużo czasu, a Twój program jest tak samo wydajny, szybki, ma znacznie mniejsze szanse na wyciek pamięci i zaoszczędziłeś czas.

Języki skryptowe zostały zaprojektowane po stronie programisty, ale optymalizacja jest nadal możliwa. Oczywiście możesz być magikiem wzorniczym, voodoo STL, a nawet wojownikiem seplenieckim, a może mnichem haskell. Ale języki zmuszają nas do rozmawiania z komputerami, języki nie są stworzone dla nas, aby być komputerami!



2

Używam C ++ nazywa się C z klasami!


8
Brawo, użyłeś słowa kluczowego „klasa”. Teraz rozumiesz projekt OO!
dss539,

Mój C ++ nazywa się C z przestrzeniami nazw.
jsz

6
Mój C ++ nazywa się, umm .. C ++ Manoj.
Manoj R

+1 Klasy to jedyny powód, dla którego używam C ++.
mbq

... ok, także wyjątki.
mbq

0

W rzeczywistości istnieje jedna odpowiedź na wszystkie tak utworzone pytania. Najlepszym powodem, aby użyć technologii X zamiast technologii Y (gdzie X i Y są mniej więcej na tym samym poziomie [jak prawie wszystkie współczesne języki programowania]) jest to, że już znasz X i nie znasz Y.

(ale po przybyciu Haskella nie było powodu, aby używać czegokolwiek innego)


0

Nie, wcale nie. Jeśli nie potrzebujesz wydajności i istnieje biblioteka, której możesz użyć w innym języku, nie przejmuj się C / C ++. Robię to teraz tylko wtedy, gdy kieruję reklamy na systemy wbudowane, które nie mogą (łatwo?) Obsługiwać języków. Czasami używam C, ponieważ piszę wtyczkę, ale naprawdę nie.

Jednak nie używałbym Pythona, Perla itp., Aby uniknąć używania C. Moje preferencje to w rzeczywistości C #, ponieważ lubię dobrą bibliotekę (która jest siłą .NET) i lubię języki o typie statycznym. Boo to dobra alternatywa. Ale tak naprawdę Haskell , OCaml , D , ML i takie są w porządku.


7
Nie trafiłeś w sedno.
Matt Joiner,

@Matt Joiner: Jestem pewien, że nie. Co mnie ominęło?

Pytanie dotyczy nie używania C ++.
Matt Joiner

@Matt Joiner: hmm, po kolejnym spojrzeniu widzę, że jest o to poproszony. Ale wygląda na to, że ja też na to odpowiedziałem (powiedziałem, że nie przejmuj się i alternatyw, których używam)

Prawie chcę to głosować z powodu C # ...
Vreality
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.