W szkole zaczęliśmy uczyć się języka C w tym roku, pomimo tego, że jestem znacznie przed klasą, a ja nauczyłem się Java, C ++ i C, podczas gdy klasa jest u podstawy C. W każdym razie, dokumentowałem siebie, czytając książki, artykuły, a ja zapytałam moją nauczycielkę, dlaczego mam się uczyć języka C, a ona powiedziała, że to podstawa języka C ++. Kiedy zaczynałem programować, łatwiej było mi C ++, później nauczyłem się C. Ale w książkach widać, że kod C działa w C ++, ale nie działa odwrotnie.
Moje pytanie jest dość proste ~ Czy dobrym nawykiem jest używanie wyrażeń C w C ++? Dam ci przykład:
Powinien ten kod
#include <stdio.h>
#include <iostream>
int main() {
int x;
scanf("%d", &x);
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}
Bądź bardziej wydajny lub lepszy w jakikolwiek sposób:
#include <iostream>
int main() {
int x;
cin >> x;
cout << "The number you entered is " << x << "And it's double is " << x*x;
return 0;
}
Zrobiłem już łatwą dokumentację na ten temat w niektórych zakurzonych starych książkach i z tego, co mogłem znaleźć, użycie scanf zamiast cout również opróżnia strumień lub coś takiego, więc w zasadzie pytam, czy lepiej użyć scanf i jakie konteksty
Dotyczy to również pliku IO, ponieważ zawsze uważałem, że FI IO jest łatwiejszy w C niż w C ++. To pytanie dotyczy prawie każdego ogólnego wyrażenia w C zastosowanego do C ++. Warto również zauważyć, że korzystam z nowoczesnego kompilatora, ale nie powinno to mieć znaczenia, ponieważ pytam, czy dobrym nawykiem programowania jest używanie wyrażeń C w kodzie C ++.
Prawdopodobnie są to wady i zalety, ale szukam tylko odpowiedzi typu tak / dlaczego, nie / dlaczego.
Również jeśli są jakieś szczegóły, które pominąłem, dodaj komentarz.
stdio
iiostream
. W rodzinie gwarantowana jest pewna kolejność i synchronizacja, które niekoniecznie mają zastosowanie poza nią.Odpowiedzi:
Nie, to zły nawyk. Gdy robisz to na co dzień, najprawdopodobniej skończysz z naruszeniem przewodników stylu, których przestrzega Twój zespół (lub przynajmniej zostaniesz pobity podczas recenzji kodu).
Tak, działa, ale jeśli istnieje odpowiednik c ++, użyj go. (np staram się nie mieszać
printfs
zcouts
)źródło
printf
konsekwentne korzystanie będzie działać tak samo, jakcout
konsekwentne. Jedyne problemy to mieszanie ich ze sobą i styl.Ogólnie rzecz biorąc, C i C ++ są traktowane tak, jakby były dwoma całkowicie odrębnymi językami. Dlatego można uznać za złą formę użycie składni C w programie C ++.
Masz rację; jednak ten kod C będzie dobrze się kompilował. To zależy od tego, jak elastyczna jest Twoja firma pod względem przestrzegania standardów. Gdybym kiedykolwiek zadał to pytanie w wywiadzie, z pewnością poinformowałbym ankietera, że C działa w C ++, ale także, że C i C ++ są dwoma oddzielnymi językami i prawdopodobnie nie powinny być mieszane, chyba że istnieje bardzo, bardzo dobry powód, aby to zrobić.
Inną rzeczą do rozważenia jest to, że standardy pomagają stworzyć platformę, na której więcej osób może z łatwością pracować z kodem. Chociaż miałeś szczęście, że masz nauczyciela, który zachęcał cię do nauki języka C, nie wszyscy mogą mieć tyle szczęścia. Dlatego mieszanie C w programie C ++ może być mylące dla kogoś, kto nigdy nie nauczył się C.
Podsumowując, sam fakt, że możesz coś zrobić, nie oznacza, że powinieneś, a sam fakt, że nie możesz zrobić, nie oznacza, że nie możesz :)
źródło
C ++ z założenia jest wstecznie kompatybilny z C, więc zwykle kod C będzie kompilowany przez kompilator C ++ w porządku ( zwykle dlatego, że w C ++ są dodatkowe zastrzeżone słowa, które nie są w C i mogą być użyte w kodzie C przerywającym kompilację).
Uważam to jednak za złą praktykę mieszania kodu. Jeśli używasz
scanf
- użyjprintf
, jeśli używaszoperator >>
- użyjoperator <<
. Powodem jest to, że przeciążone operatory C ++ mogą zawierać funkcjonalność, o której nie wiesz, a niedopasowanie ich spowoduje, że Twój program będzie robił rzeczy, których nie chciałeś.Nie ma szczególnego powodu, aby preferować składnię C w kodzie C ++, są to różne języki, a gdy używasz składni C w kodzie C ++ - nadal piszesz kod C ++ , po prostu nie korzystasz z wielu jego potężnych narzędzi.
źródło
Jeśli odłożymy na bok styl kodowania i problemy estetyczne, istnieją również różne problemy techniczne, które napotykasz podczas używania C w kodzie C ++:
Co to jest C? C90, C99 czy C11? Mogą występować różne problemy ze zgodnością w zależności od używanego standardu C. Typ boolowski, // komentarze, funkcje C99, takie jak VLA, wyznaczone inicjatory itp.
C ++ ma bardziej rygorystyczne pisanie niż C. Aby skompilować kod C w C ++, najprawdopodobniej musisz dodać różne typy rzutów, aby uzyskać oczekiwany typ. Oznacza to, że może być konieczne przepisanie idealnie poprawnego kodu C o jakości produkcyjnej, aby działał w C ++.
Rzutowanie typowane przez ściślejsze pisanie na ogół jest po prostu dobrą rzeczą, ale w niektórych przypadkach mogą wprowadzać lub ukrywać błędy. Weźmy na przykład niesławną obsadę wyniku z malloc (). Powinno to być zapisane w C ++, ale nigdy w C. (1)
Mieszanie funkcjonalności C i C ++ może prowadzić do błędów i nieokreślonego zachowania. Na przykład nie będzie działało przydzielanie za pomocą malloc () i zwalnianie za pomocą delete . (2)
Problemy z bezpieczeństwem wątków. Biblioteka standardowa C nie jest bezpieczna dla wątków. Standardowa biblioteka C ++ może, ale nie musi być wątkowo bezpieczna, jeśli tak, to dodanie wywołań funkcji biblioteki C do kodu zniszczy to.
Na marginesie dla programistów systemu Windows: kompilator Visual C ++ miał błąd wycieku od dłuższego czasu, gdy funkcja CreateThread () interfejsu API systemu Windows była używana w tym samym programie co biblioteka C. (3, 4)
Konwencja wywoływania może stanowić problem w niektórych kompilatorach, zmuszając ją
extern "C"
do jednoznacznego określenia, które funkcje powinny być powiązane z „konwencją wywoływania C”.Irytujące szczegóły. Operator przecinka zachowuje się inaczej. Końcowy przecinek w deklaracjach struct / enum jest dozwolony w C99 / C11, ale nie w C ++. Zakres różnych rodzajów zmiennych i funkcji jest różnie traktowany. Itd itd.
Prawdopodobnie jest jeszcze więcej przypadków.
Bibliografia:
źródło
Powodem, dla którego C ++ może kompilować C, jest tylko „kompatybilność wsteczna” (unikaj przepisywania istniejącego działającego kodu).
Ale C ++ ma inną filozofię względem c. Pomieszanie ich nie jest dobrą usługą dla obu z nich.
Sposób, w jaki C i C ++ zarządzają we / wy, może polegać na innym sposobie zarządzania stanem wewnętrznym we / wy. Więc - przynajmniej - konsekwentnie używaj wejścia i wyjścia.
A w programach C ++ przestrzega stylu C ++ (chyba że jest to specjalnie wymagane, aby robić to gdzie indziej)
źródło
Powiedziałbym, że najpierw nauka C jest, IMHO, dobrym pomysłem. W ten sposób ludzie zaczynają rozumieć sprzęt, dla którego piszą oprogramowanie.
Mieszanie tych dwóch języków nie jest jednak dobrym pomysłem. Ponieważ dostajesz szaloną złożoność C ++ w połączeniu z kręceniem się surowych bitów wspólnych dla C.
Jak widać, nawet w tak prostym przykładzie, jak twój, występują problemy z synchronizacją z różnymi typami strumieni i wewnętrznym buforowaniem. Ale również podejście C&C ++ nie jest w żaden sposób bardziej elastyczne. Przełącz się do klasy x, a nie ma operatorów, którzy mogliby korzystać z przesyłania strumieniowego i innych rzeczy.
To skomplikowane...
Naprawdę uważam, że dobry programista C ++ powinien wiedzieć, w jaki sposób bity są odrzucane za każdą konstrukcją i jakie są ukryte zachowania.
Ale nauka C ++, przynajmniej w ponad 50%, zajmuje ponad 5 lat profesjonalnego kodowania i po prostu nie możesz sobie z tym poradzić w programie nauczania, który trwa 6 miesięcy i 20 godzin praktycznego doświadczenia.
Gdybym używał konstruktorów C ++ w C, nie użyłbym strumieni, są one proste z lotu ptaka i sprawiają, że ludzie wierzą, że tworzenie oprogramowania jest łatwe, ale ukrywają dodatkowe złożoności bez wielu korzyści w wielu sytuacjach.
Klasy opakowujące RAII, szablony, przeciążenia, poprawność const i czyste klasy abstrakcyjne dla popularnych interfejsów (nie używaj tutaj f-ng Java PROSZĘ!) Są jednak dobrymi kandydatami. Ponieważ zwiększają bezpieczeństwo, ogólność i łatwość użytkowania, które są bardzo ważne w rzeczywistych projektach. Pamiętaj jednak o takich rzeczach, jak wirtualne zniszczenie, wybuchowa natura domyślnej budowy kopii, koszty działania, stała poprawność itp.
źródło