Od nieco ponad roku zapoznałem się z informatyką i z mojego doświadczenia wynika, że zarówno C, jak i C ++ są uważane za języki „ultraszybkie”, podczas gdy inne, takie jak Python i takie języki skryptowe są zwykle uważane za nieco wolniejsze .
Ale widziałem również wiele przypadków, w których projekt oprogramowania lub nawet mały przeplatałby pliki, w których pewna liczba n tych plików byłaby zapisana w C, a pewna liczba m tych plików byłaby napisana w C ++.
(Zauważyłem również, że pliki C ++ prawie zawsze mają odpowiednie nagłówki, podczas gdy pliki C nie tak bardzo). Ale moim głównym pytaniem jest uzyskanie ogólnego wyczucia intuicji, kiedy należy używać C nad C ++, a kiedy lepiej jest używać C ++ nad C. Poza faktami, że (1) C ++ jest zorientowany obiektowo, podczas gdy C nie jest, a (2) składnie są bardzo podobne, a C ++ został celowo stworzony, aby pod wieloma względami przypominać C, nie jestem pewien, jakie są ich różnice. Wydaje mi się, że są (prawie) doskonale wymienne w wielu dziedzinach.
Byłoby więc mile widziane, gdyby ktoś mógł wyjaśnić sytuację! Dzięki
virtual
i kilku innych funkcji, które uniemożliwiają optymalizację, ale np. nieklasyvirtual
nie są z natury nieefektywne, a szablony są potężne narzędzie abstrakcyjne, które może faktycznie prowadzić do większej wydajności - np.qsort
vsstd::sort
). (2) Duże znaczenie prawidłowości jest to powód, aby korzystać z C ++ (typesafety,const
Nessprivate
, RAII aby zarządzanie zasobami opanowania, etc.) na C lub o to chodzi, użyj Ada albo coś w pierwszej kolejności.void*
innego typu wskaźnika w kodzie C, jest to bardzo rozpraszające i typowe dla osób, które nie znają C.Odpowiedzi:
Kiedy wybierasz C
We wszystkich innych przypadkach powinieneś wybrać C ++.
źródło
Jest kilka powodów, dla których wolę C. Najważniejsze jest to, że trudniej jest stworzyć naprawdę małe pliki wykonywalne w C ++. W naprawdę małych systemach i tak rzadko piszesz dużo kodu, a dodatkowe miejsce w pamięci ROM, które byłoby potrzebne dla C ++ zamiast C, może być znaczące.
Powinienem jednak dodać, że w naprawdę małych systemach C ma problemy z dokładnie tego samego powodu, a język asemblera jest prawie jedynym rozsądnym wyborem. Zakres rozmiarów systemu, w którym C naprawdę ma sens, jest dość mały i stale się kurczy (choć przyznaję, dość powoli).
Innym powodem / powodem użycia C jest zapewnienie zestawu funkcji, z którymi można się połączyć w zasadzie z dowolnego innego języka. Państwo może pisać te funkcje w C ++, definiując je jako
extern "C"
funkcje, ale robi tak ogranicza te funkcje do przedstawienia się „twarzą” zasadniczo C-life na świat - zajęcia, przeciążone funkcje, szablony i funkcje składowe, etc., nie trzeba zastosować. Nie musi to jednak ograniczać rozwoju do C - całkowicie uzasadnione jest korzystanie z wewnętrznych funkcji C ++ , o ile interfejs zewnętrzny wygląda jak C.Jednocześnie muszę powiedzieć, że odpowiedzi @ Toll (dla jednego oczywistego przykładu) mają pod pewnymi względami pewne cechy wstecz. Rozsądnie napisane C ++ będzie na ogół co najmniej tak szybkie jak C, a często co najmniej trochę szybsze. Czytelność jest na ogół znacznie lepsza, choćby dlatego, że nie zakopano się w lawinie całego kodu nawet dla najbardziej trywialnych algorytmów i struktur danych, obsługi błędów itp.
Szablony nie „rozwiązują problemu z systemem typów języka”, po prostu dodają szereg podstawowych możliwości prawie całkowicie nieobecnych w C i / lub C ++ bez szablonów. Jednym z pierwotnych założeń było zapewnienie pojemników bezpiecznych dla typu, ale w rzeczywistości wykraczają one daleko poza to - zasadniczo żaden z nich nie zapewnia C.
Zautomatyzowane narzędzia to w większości również czerwony śledź - choć prawdą jest, że pisanie parsera C jest mniej pracy niż pisanie parsera C ++, w rzeczywistości nie robi on praktycznie żadnej różnicy. Bardzo niewiele osób chce lub jest w stanie napisać użyteczny parser dla jednego z nich. Jako taki, rozsądnym punktem wyjścia jest Clang w obu kierunkach.
Tak się składa, że C i C ++ są dość często używane razem w tych samych projektach, prowadzonych przez te same osoby. Pozwala to na coś, co poza tym jest dość rzadkie: badanie, które bezpośrednio, obiektywnie porównuje łatwość utrzymania kodu napisanego w dwóch językach przez osoby, które są jednakowo kompetentne (tj. Dokładnie te same osoby). Przynajmniej w powiązanym badaniu jeden wniosek był jasny i jednoznaczny: „Odkryliśmy, że użycie C ++ zamiast C skutkuje lepszą jakością oprogramowania i mniejszym nakładem prac konserwacyjnych ...”
źródło
Różnice między C i C ++ zostały już tutaj szczegółowo wyliczone . Chociaż czasami ludzie mogą mieć uzasadnione powody, aby wybrać jedno lub drugie (C ++ dla OOP lub C, gdy czują, że dodatkowe funkcje C ++ wprowadzają na przykład niepożądany narzut), z mojego doświadczenia wynika, że zwykle sprowadza się to do preferencji. Co ludzie pracujący nad tym plikiem wiedzą lepiej i lubią lepiej? Uważam, że jest to najczęściej przyczyną, ponieważ prawdą jest, że oba te języki radzą sobie z aplikacjami krytycznymi pod względem wydajności.
(Uwaga dodatkowa: Sprawdź zdanie Linusa Torvadsa dotyczące tego, dlaczego woli C od C ++. Niekoniecznie zgadzam się z jego punktami, ale daje to wgląd w to, dlaczego ludzie mogą wybrać C zamiast C ++. Raczej ludzie, którzy się z nim zgadzają może wybrać C z tych powodów.)
źródło
-1
na rant Linusa. : - {Głównym problemem, którego brakuje w istniejących odpowiedziach (w chwili opublikowania tego posta), jest wybór.
To proste. Jeśli z jakiegoś zupełnie irracjonalnego powodu uważasz, że wyjątki nie są warte kosztów ogólnych, nie musisz ich używać . Nadal możesz mieć szablony i RAII oraz bibliotekę Standard i nigdy nie pisać ani jednego „rzutu”. To samo dotyczy szablonów. Jeśli z jakiegoś powodu uważasz, że powodują nieodwracalne (i faktycznie ważne, co dzieje się tylko na wbudowanym) wzdęciu wykonywalnym, to niespodzianka - możesz także używać void * i sizeof (T) przez cały dzień. Nic nie zmusza Cię do korzystania z funkcji C ++ w porównaniu do C.
Właśnie dlatego C ++ jest z natury lepszym językiem - możesz bez problemu wybierać pożądane funkcje i wracać do programowania w stylu C, jeśli nie lubisz danej funkcji. Dlatego, biorąc pod uwagę, że C ++ jest wszystkim, czym jest C i więcej, oczywistym faktem jest, że C ++ jest lepszym językiem. Sugerowanie inaczej jest jak próba zasugerowania, że 4 jest większe niż 5.
źródło
Rzeczy na temat C ++, które denerwują programistów C.
Pod maską dzieje się dużo magii; konstruktory, destruktory, wirtualne metody, szablony itp. mogą znacznie ułatwić i przyspieszyć pisanie kodu C ++ niż równoważny kod C, ale trudniej go zrozumieć i zrozumieć (w zależności od tego, jak dobrze znasz C ++ i związane z nim konwencje). Coś tak prostego, co
Foo newFoo;
może wywoływać dużo kodu, w zależności od tego, jakFoo
zdefiniowano konstruktor klasy (i dowolne klasy, od których zależy). Dlatego konwencja polega na pisaniu++it
zamiast nait++
iteracji przez kontener, ponieważ postfiks++
często wymaga kosztownej operacji kopiowania.W zależności od tego, co robisz, mogą występować pewne trywialne koszty ogólne, szczególnie w przypadku prostych zadań. Weź następujące dwa programy, pierwszy w C, drugi w C ++:
Identyczne zachowanie, niezbyt duża różnica w zakresie źródła, ale na pudełku SLES 10, nad którym pracuję z gcc 4.1.2, pierwszy generuje plik wykonywalny o wielkości ~ 9 kb, podczas gdy drugi zajmuje 12,5 kb (bez optymalizacji ), prawie 28% większy. Typ C ++
string
jest o wiele łatwiejszy do pracy z IMO niż biblioteka ciągów C, a strumienie C ++ są o wiele bardziej elastyczne i konfigurowalne niż strumienie C, ale w przypadku tak naprawdę martwego kodu, takie mogą nie być warte narzutu.C ++ to ogromny język w porównaniu do C, z pewną niezwykle złożoną semantyką. Osiągnięcie biegłości w posługiwaniu się C ++ zajmuje dużo więcej czasu, co oznacza, że wiele osób, które twierdzą, że znają C ++, nie zna go tak dobrze, jak im się wydaje.
Rzeczy na temat C, które denerwują programistów C ++
C nie jest bezpiecznym językiem programowania w żadnym stopniu wyobraźni; brak ograniczeń sprawdzania tablic prowadzi do wielu możliwych do wykorzystania zachowań (czy to poprzez martwą
gets
funkcję, czy poprzezscanf
specyfikatory%s
i%[
). C ++ daje przynajmniej kontenery, które zgłaszają wyjątki, jeśli próbujesz uzyskać dostęp poza ich obecnie zdefiniowanym zakresem; wszystko, co daje Ci, to (jeśli masz szczęście) naruszenie segmentacji.Zarządzanie pamięcią w C jest bardzo pracochłonne i podatne na błędy, w porównaniu do narzędzi, które udostępnia C ++. Jeśli budujesz swój własny kontener, jesteś odpowiedzialny za dopasowanie wszystkich połączeń
malloc
ifree
, upewnienie się, że alokacje są udane, wycofanie częściowych alokacji w przypadku błędu itp. W C ++ dodajesz elementy do lub wyjmij przedmioty z pojemnika. Jeśli wystąpi problem, zostanie zgłoszony wyjątek.Podobnie, obsługa błędów w C jest uciążliwa w porównaniu do narzędzi udostępnianych przez C ++ (mianowicie wyjątków). Naprawdę fajne jest to, że przydzieliłeś sporo pamięci, a potem uderzyłeś w ścianę podczas przetwarzania; gdy musisz się wycofać, musisz zwolnić tę pamięć we właściwej kolejności. W przypadku zasad C ++ i RAII jest to (stosunkowo) łatwe.
Więc kiedy używam jednego nad drugim?
Jeśli to, co piszesz, jest bajecznie proste, przeczytaj je / zrób z nim / pozbądź się aplikacji, której zachowanie można opisać w kategoriach danych wejściowych i wyjściowych oraz wydajności, a następnie preferuj C niż C ++. W przeciwnym razie preferuj C ++
źródło
Bjarne Stroustrup prowadzi listę aplikacji i firm korzystających z C ++; możesz kłócić się o programowanie vs programowanie OOP, ile chcesz, ale nie możesz kłócić się z wynikami branży w ciągu ostatnich 20 lat.
C ++ jest powszechnie stosowany w dużych projektach złożonych dla wielu osób, w których oddzielne osoby muszą pracować na modułowych komponentach. Oczywiście możesz budować i utrzymywać zmodularyzowany kod w C, ale wrodzona natura C ++ w OOP prowadzi do doskonałej modularyzacji, testowalności i ponownego wykorzystania kodu.
Standardowa biblioteka C ++ (STL), sama w sobie z jedynie wektorami i mapami, jest wystarczającym powodem do używania C ++.
C jest powszechnie używany w systemach wbudowanych.
Osobiście użyłbym C tylko, jeśli istnieje biblioteka, która ma tylko C API.
źródło
Powiedziałbym, że głównym powodem, dla którego wybrałem C zamiast C ++, jest tylko wtedy, gdy musiałbym uciekać się do tego typu „NASZ MUSI BYĆ 1000% stabilny”.
C ++ wynosi ~ 99% C, gdy patrzymy na wydajność, i jest o wiele bardziej produktywny. Więc nawet będąc w C możesz pisać kod, który będzie szybszy niż C ++ (możesz użyć podzbioru C ++ bez wyjątków, wirtualnych, streamingów, abstrakcji itp., Ale to w zasadzie C), czas na optymalizację każdej cholernej rzeczy podczas gdy STL jest testowany i już to robi, kosztowałoby Cię więcej niż niewielki wzrost wydajności, który możesz osiągnąć lub poświęcić, ponieważ algorytmy STL zostały napisane przez grupy ekspertów i prawdopodobnie nie jesteś ekspertem we wszystkim.
Z drugiej strony C ++ ma mnóstwo abstrakcji. Gdy w pewnych okolicznościach wyciekają, wpadasz w kłopoty. I jest niewiele osób, które znają 100% gotcha C ++, podczas gdy, myślę, że jest więcej, którzy znają wszystkie gotcha C, więc napisanie rozwiązania, w którym każdy krok jest w pełni zrozumiały dla wszystkich członków zespołu, jest znacznie łatwiejsze w C.
Przykład: Czy wiesz, kiedy
shared_ptr<smthn>
przepełni liczbę referencyjną, czy zgłosi wyjątek? Takie rzeczy nie są fajne, kiedy Shuttle musi ponownie wprowadzić atmosferę, przynajmniej tak sądzę.Ponadto obsługa wyjątków jest bardzo, bardzo trudna w porównaniu z kodami błędów. Trudno sprawdzić, czy klasa jest w 100% bezpieczna pod względem wyjątków i czy łatwo się w nią dostać. Wiele osób o wysokiej reputacji wyraziło tę opinię.
źródło
std::string
i tym podobne? Czy próbowałeś kiedyś podać platformę, na którejshared_ptr
przepełniłby się licznik? To byłaby jedna zabawna platforma. A jeśli uważasz, że obsługa wyjątków jest trudna, powinieneś rzucić okiem na kawałek kodu C, który sprawdza każdy możliwy błąd przy każdym wywołaniu funkcji. (Przyznaję, że taki kod jest trudny do zdobycia, ale to tylko mocniejszy argument przeciwko twojemu stwierdzeniu.) Przepraszam, ale to są naprawdę bydlęce odchody.std::string
jeśli nie chcesz dynamicznej alokacji. Użyłbyśstd::basic_string<char, std::char_traits<char>, some_allocator_here>
.C to przenośny zestaw z lepszą składnią, dający programatorowi pełną kontrolę nad wszystkim .
Z drugiej strony C ++ wykonuje wiele funky magii (funkcje wirtualne, przeciążanie, automatyczna konwersja itp.), Które mogą być niepożądane, jeśli chcesz się upewnić:
I chcesz czegoś naprawdę prostego w pracy, ponieważ koncentrujesz się na wydajności.
Po prostu nie ma niespodzianek, a to bardzo cenne.
Jeśli chcesz (i polecam), przeczytaj wskazówki dotyczące kodowania JSF na temat tego, o czym powinieneś pomyśleć pisząc C ++ do kontroli lotnictwa wojskowego. Jest tam wiele pułapek, o których musisz wiedzieć, i może cię złapać. Bjarne był częścią tego dokumentu, więc wie, o co chodzi.
Ponadto C kompiluje się jak oparzony troll uderzony piorunem. C ++, OTOH, był prawdopodobnie sponsorowany przez te same osoby, które inwestowały w firmy SSD. :)
(Osobiście wolałbym C ++, ale mi się nie podoba ...... też. ;-P)
źródło
int
ma 64 bity, należy rzucić co najmniej jeden operand, abyuint64_t
zapobiec nieokreślonemu zachowaniu, ale konieczność rzutowania na 64 bity w celu obliczenia wyniku 32-bitowego jest - delikatnie mówiąc - „zaskakująca”.(pod warunkiem, że znasz jednakowo oba języki)
Korzystaj z C ++, chyba że na twojej platformie nie ma kompilatora C ++. Możesz pisać kod C ++ bez jakiejkolwiek części języka, który ci się nie podoba (bez klas, wyjątków, wirtualnego dziedziczenia, jakichkolwiek osobistych ograniczeń, które chcesz zastosować), a następnie w przyszłości, jeśli zdecydujesz, że chcesz trochę te funkcje w końcu można łatwo z nich korzystać. Nic w C ++ nie uniemożliwia pisania kodu w stylu C.
(biorąc pod uwagę równoważne zestawy narzędzi i wiedzę programistów) Nie ma powodu, aby wybierać C zamiast C ++, pod warunkiem, że twoja platforma ma kompilator C ++. Możesz po prostu ograniczyć się do podzbioru języka, który chcesz dzisiaj, pozostawiając otwarte drzwi do rozszerzenia później.
źródło
Oba języki są doskonałe. Myślę, że wiele plakatów szczegółowo opisuje mocne strony i różne zastosowania każdego z nich. Po prostu dodam to:
Widzę, że język C jest idealny w 4 obszarach: 1) Myślę, że to najlepszy język, którego należy używać podczas nauki dowolnego rodzaju programowania [w połączeniu z pewnym asemblerem i znajomością kodu maszynowego], 2) doskonale nadaje się do pisania sterowników, 3) osadzony oprogramowanie oraz 4) oprogramowanie systemowe na najniższym poziomie.
C ++ jest językiem zorientowanym obiektowo, ale może być również proceduralny (bardzo podobnie jak C). Jeśli pracujesz nad dużymi projektami, oprogramowaniem opartym na graficznym interfejsie użytkownika, oprogramowaniem do gier i innymi rodzajami graficznie intensywnych programów, to C ++, Java, a nawet Objective-C to najlepszy wybór. Istnieje jednak wiele programów wiersza polecenia lub oprogramowania systemowego, w których C ++ może być tak dobry lub lepszy niż C.
źródło
Moim zdaniem w tej dyskusji brakuje jednego punktu: w C łatwiej jest zapewnić stabilny interfejs binarny z biblioteki. Zarówno do użytku z innymi językami, jak i C ++.
W C ++ różne kompilatory używają odmiennego nazewnictwa nazw, więc konsumenci biblioteki skompilowanej z innym kompilatorem niż biblioteka mogą mieć problemy z korzystaniem z niej. W przypadku C interfejs binarny jest zwykle standaryzowany dla platformy.
Wiem, że obecnie kompilatory często mają przełączniki do produkcji rzeczy kompatybilnych z gcc, ale to nie zawsze pomaga.
Stosunkowo często obserwuję to na Solarisie. Dystrybucja i różni dostawcy oprogramowania zazwyczaj używają Sun Studio, ponieważ, szczególnie w systemach Sparc, często zapewnia lepsze wyniki. Jednak projekty open source Man są napisane przy użyciu kodu specyficznego dla gcc. Może to być dość uciążliwe dla osób pracujących razem.
źródło
C jest prawdopodobnie lepiej niż C ++, gdy generowany jest kod C (np. W implementacjach języków wyższego poziomu). Na przykład istnieje kilka kompilatorów podobnych do Lisp, które emitują kod C (np. Chicken , Scheme48 ...), ale nie znam żadnego, który emitowałby prawdziwy kod C ++ (moje narzędzie MELT emituje kod C ++, ale nie nazywam tego kodu autentycznym Kod C ++, używa bardzo niewielu funkcji C ++).
Kod C jest również łatwiejszy do udowodnienia półautomatycznie. Analizatory statyczne, takie jak Frama-C (w których adnotacje do kodu C są opatrzone komentarzami ACSL w celu wyjaśnienia przyczyny twojego kodu) są dostępne dla C, ale nie tak bardzo dla pełnego C ++ 11.
źródło