C++/Różnice między C a C++: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Derbeth (dyskusja | edycje)
+ komentarze, małe porządki
Nie podano opisu zmian
Linia 4:
 
=== Komentarze ===
W czystymANSI C (C89) nie jest dozwolone używanie komentarzy zaczynających się od <tt>//</tt>. Zostały jednak dodane w standardzie C99.
 
=== Stałe ===
 
Stałe w C++ (obiekty zadeklarowane ze słowem const) są stałe w pełnym tego słowa znaczeniu. Np. stałe typów całkowitych mogą być stosowane tam, gdzie wymaga się stałych wyrażeń (tzn. jako etykiety case, jako rozmiar tablic itp.). W C już nie i tam do takich stałych trzeba stosować dyrektywę [[Programowanie:C:Preprocesor|preprocesora]] '''#define'''. W C stała jest dokładnie tym samym co zmienna, z tym tylko zastrzeżeniem, że nie można jej modyfikować.
Kompilator C++ traktuje stałe inaczej niż kompilator C. Jeśli to możliwe, stała nie jest trzymana w pamięci; zamiast tego do kodu może być wstawiona bezpośrednio jej wartość. Dzięki temu możliwe jest używanie stałych np. przy określaniu rozmiarów tablic, do czego w C konieczna była dyrektywa [[Programowanie:C:Preprocesor|preprocesora]] '''#define'''.
 
Konsekwencją tego po części jest fakt, że globalnie deklarowane stałe w języku C mają to samo wiązanie (ang. linkage) co zmienne, czyli zewnętrzne. W języku C++ stałe mają domyślnie wiązanie lokalne i aby były one zewnętrzne (dzielone między jednostkami kompilacji), muszą być zadeklarowane razem z inicjalizacją i słowem '''extern'''.
 
=== Zmienne ===
 
* możliwość deklarowania zmiennych np. w instrukcji sterującej petli for
* możliwość mieszania instrukcji i deklaracji zmiennych w jednym bloku kodu (w ANSI C zmienne muszą być deklarowane przed pierwszą instrukcją)
 
=== Wiązanie (ang. linkage) i obiekty niejawne ===
=== Typ char ===
 
W języku C wiązanie symboli z obiektami, które są przez nie oznaczane, czyli odwoływanie się w jednych jednostkach kompilacji do obiektów lub funkcji z innych jednostek kompilacji, jest opisane luźniejszymi regułami, niż w C++.
 
W języku C obowiązuje "słabe wiązanie" (ang. vague linkage), przy czym nie istnieją w tym języku żadne obiekty niejawne. To oznacza, że funkcja lub zmienna globalna o określonej nazwie może wystąpić dowolną ilość razy w całym zbiorze kompilacji (zbiorze jednostek kompilacji składających się na jeden plik wykonywalny lub bibliotekę dynamiczną). Podczas procesu wiązania wybierany jest w takim wypadku "pierwszy lepszy" ze wszystkich takich obiektów. Język C pozwala również na wielokrotne definicje zmiennej globalnej w tym samym pliku - definicje te, jak też definicje zmiennej o tej samej nazwie w innych jednostkach kompilacji będą się odnosić do dokładnie tej samej zmiennej. Właściwosć ta pochodzi prawdopodobnie z czasów, gdy w C nie było słowa extern, więc deklarację zmiennej globalnej można było bez dodatkowych oznaczeń zamieścić w pliku nagłówkowym.
 
W języku C++ obowiązuje "silne wiązanie" (ang. strict linkage) dla obiektów jawnych, natomiast słabe dla obiektów niejawnych. Obiekty niejawne w C++ to są tablice metod wirtualnych tworzonych dla określonej klasy oraz funkcje inline. Silne wiązanie oznacza, że jeśli w zbiorze kompilacji zostaną znalezione dwa obiekty o tej samej nazwie, to linker zgłosi błąd i odmówi wiązania.
 
=== Typ charstałej znakowej ===
 
W języku [[Programowanie:C|C]] literał znakowy (stała znakowa), np. 'a' jest traktowana jako '''int''', natomiast w C++ jest uważana za '''char'''.
Linia 20 ⟶ 31:
=== Typ bool ===
 
W C++ istnieje oficjalny typ '''bool''' i dwie stałe tego typu '''true''' i '''false''', które służą do przechowywania wartości logicznych. Jest typem zwracanym operatorów porównawczych i relacji oraz typem przyjmowanym i zwracanym przez operatory && i ||. Ten typ musi mieć również wyrażenie podawane do '''if''', '''while''' i drugiego wyrażenia w '''for'''.
Bool to nowy typ wprowadzony w C++ przechowujący wyniki wyrażeń logicznych. Przyjmuje dwie predefiniowane wartości - true (prawda) i false (fałsz). Jest to zmiana w stosunku do języka C, gdzie nie było osobnego typu i każda liczba mogła być interpretowana jako wartość logiczna. W C++ pozostała taka możliwość - liczby różne od 0 (czyli również ujemne) są traktowane jako prawda, zero jako fałsz. I odwrotnie: true może być traktowane jako jedynka, false jako zero.
 
Ze względu na wsteczną zgodność jednak pozostawiono domyślną konwersję typu bool na int, przy czym false i true są konwertowane odpowiednio na 0 i 1, natomiast w drugą stronę 0 konwertuje się na false i każda inna wartość całkowita na true.
 
=== Alternatywne słowa kluczowe ===
 
W języku C++ dodano dodatkowe słowa kluczowe opisujące niektóre operatory. Operatory <tt>&&</tt>, <tt>||</tt> i <tt>!</tt> możemy też zapisywać jako <b>and</b>, <b>or</b> i <b>not</b>. Istnieją także słowa dla operatorów bitowych &, | i ^: '''bitand''', '''bitor''' i '''xor'''. Podobnie również dla operatorów połączonych z przypisaniem: ''' and_eq ''', ''' or_eq ''' i ''' xor_eq '''. Istnieje także, choć szczerze nie wiem po co, ''' not_eq '''.
 
=== Biblioteka standardowa ===
C++ używa innych nazw plików nagłówkowych dla biblioteki standardowej odziedziczonej z języka C - np. <tt>cstdio</tt> zamiast <tt>stdio.h</tt>. Zobacz też rozdział [[C++:Przestrzenie nazw#Korzystanie z biblioteki standardowej C|Przestrzenie nazw]].
 
=== Funkcje ===
 
Gdy napiszemy <tt>funkcja() {}</tt> to w C funkcja ta będzie miała [[Programowanie:C:Funkcje#Zmienna liczba parametrów|zmienną listę argumentów]] a w C++ będzie miała pustą listę argumentów.
W języku C pusta lista argumentów: () oznacza, że prototyp nie precyzuje argumentów przyjmowanych przez funkcję, natomiast deklaracja '''funkcja(void)''' oznacza, że funkcja nie przyjmuje argumentów. W języku C++ puste nawiasy są tożsame z (void).
 
W języku C++ można jednak uzyskać ten sam efekt, co puste nawiasy w C poprzez '''(...)''', czyli [[Programowanie:C:Funkcje#Zmienna liczba parametrów|zmienną listę argumentów], ale bez określania argumentów początkowych (to z kolei nie jest dostępne w języku C).
 
Należy zwrócić szczególną uwagę, że jest to w istocie dość uciążliwe ułatwienie, że () jest tożsame z (void). W konsekwencji bowiem o ile wyrażenie '''(a)''' (gdzie 'a' jest jakąś zmienną) można odróżnić od nazwy typu w nawiasach, np. '''(int)''', to w przypadku () jest to nie do odróżnienia. Stąd mała niekonsekwencja w deklarowaniu obiektów wraz z argumentami konstruktora:
Klasa x( arg1, arg2 );
ale bez argumentów musi być deklarowane jako
Klasa x;
czyli bez nawiasów.
 
Należy też pamiętać, że odróżnianie argumentu w nawiasach od typu w nawiasach źle działa w przypadku obiektów tymczasowych:
Klasa1 obiekt( Klasa2() );
które, wbrew pozorom, nie deklaruje obiektu klasy Klasa1 z podaniem obiektu tymczasowego typu Klasa2 do konstruktora, lecz deklaruje funkcję o nazwie 'obiekt', która przyjmuje typ Klasa2 i zwraca typ Klasa1.
 
=== Manglowanie nazw funkcji ===
 
W związku z przeciążaniem funkcji, każda funkcja w C++ ma unikalną identyfikację, niezależną od jej nazwy. Ten identyfikator służy również do rozpoznania odpowiedniej wersji funkcji na poziomie wiązania - nawet jeśli istnieje prototyp funkcji o określonej nazwie, ale z innymi parametrami, niż te, z którymi została ta funkcja zdefiniowana, to błąd przy próbie wywołania takiej funkcji zostanie wykryty na etapie wiązania (w przypadku języka C nie zostałby wykryty w ogóle).
 
To spowodowało niezgodność sposobu wiązania funkcji z językiem C. Żeby móc w C++ użyć funkcji zdefiniowanej w języku C, to jej prototyp musi być poprzedzony '''extern "C"'''. Taka funkcja nie może wtedy podlegać przeciążaniu (tzn. może być wiele funkcji o takiej nazwie, ale tylko jedna z nich może być extern "C").
 
=== Struktury ===
Jeśli mamy strukturę Struktura to w C zmienne definiujemy <tt>struct Struktura s1, s2;</tt>. W C++ możemy pominąć słowo kluczowe <tt>struct</tt> (i podobnie jest z union, enum i class). Dla zgodności z językiem C jednak nie jest zabronione ponowne użycie nazwy struktury w innym znaczeniu (np. funkcji, co ma miejsce w przypadku standardowej funkcji z języka C '''stat'''), tyle że jeśli się tak stanie, to wtedy nie można już pominąć słowa <tt>struct</tt>, jeśli się ma na myśli określony typ strukturalny.
 
[[Kategoria:C++]]