Odpowiedź na to pytanie zależy od tego, czego dokładnie chcesz się nauczyć.
Python i Ruby
Często sugerowane są języki wysokiego poziomu, takie jak Python i Ruby, ponieważ mają wysoki poziom, a składnia jest całkiem czytelna. Jednak wszystkie te języki mają abstrakcje dla wspólnych struktur danych. Nic nie stoi na przeszkodzie, aby wdrożyć własne wersje jako ćwiczenie edukacyjne, ale może się okazać, że budujesz struktury danych wysokiego poziomu na podstawie innych struktur danych wysokiego poziomu, co niekoniecznie jest przydatne.
Ponadto Ruby i Python są językami z typami dynamicznymi. Może to być dobre, ale może być również mylące dla początkujących i (początkowo) może być trudniejsze do wykrycia błędów, ponieważ zazwyczaj nie są one widoczne do czasu uruchomienia.
do
C jest na drugim biegunie. To dobrze, jeśli chcesz nauczyć się naprawdę niskopoziomowych szczegółów, takich jak sposób zarządzania pamięcią, ale zarządzanie pamięcią nagle staje się ważną kwestią, jak w przypadku prawidłowego użycia malloc () / free (). To może być rozpraszające. Ponadto C nie jest zorientowany obiektowo. To nie jest złe, ale po prostu warte odnotowania.
C ++
Wspomniano o C ++. Jak powiedziałem w komentarzu, uważam, że to okropny wybór. C ++ jest okropnie skomplikowany, nawet w prostym użyciu i zawiera absurdalną liczbę „pułapek”. Ponadto C ++ nie ma wspólnej klasy bazowej. Jest to ważne, ponieważ struktury danych, takie jak tabele skrótów, polegają na istnieniu wspólnej klasy bazowej. Możesz zaimplementować wersję dla nominalnej klasy bazowej, ale jest ona trochę mniej przydatna.
Jawa
Wspomniano również o Javie. Wiele osób lubi nienawidzić Javy i prawdą jest, że język jest niezwykle rozwlekły i brakuje mu niektórych nowocześniejszych funkcji językowych (np. Zamknięć), ale nic z tego nie ma znaczenia. Java jest wpisywana statycznie i ma czyszczenie pamięci. Oznacza to, że kompilator Javy wychwyci wiele błędów, których języki dynamicznie wpisywane nie będą (do czasu uruchomienia) i nie ma do czynienia z błędami segmentacji (co nie znaczy, że nie można przeciekać pamięci w Javie; oczywiście można). Myślę, że Java to dobry wybór.
DO#
C # język jest jak nowocześniejsza wersja Java. Podobnie jak Java, jest to zarządzany (zbierany bezużytecznie) pośredni język kompilowany, który działa na maszynie wirtualnej. Każdy inny język wymieniony tutaj oprócz C / C ++ również działa na maszynie wirtualnej, ale Python, Ruby itp. Są interpretowane bezpośrednio, a nie kompilowane do kodu bajtowego.
C # ma zasadniczo te same wady i zalety, co Java.
Haskell (itp.)
Na koniec masz języki funkcjonalne: Haskell, OCaml, Scheme / Lisp, Clojure, F #, itd. Myślą one o wszystkich problemach w zupełnie inny sposób i warto się ich nauczyć w pewnym momencie, ale znowu sprowadza się to do tego, czego chcesz się nauczyć: programowanie funkcjonalne czy struktury danych? Wolałabym uczyć się jednej rzeczy na raz, zamiast mieszać problem. Jeśli w pewnym momencie nauczysz się języka funkcjonalnego (co poleciłbym), Haskell jest bezpiecznym i dobrym wyborem.
Moja rada
Wybierz Javę lub C #. Oba mają bezpłatne, doskonałe środowiska IDE (Eclipse, Netbeans i IntelliJ Community Edition for Java, Visual Studio Express for C #, Visual Studio Community Edition), które ułatwiają pisanie i uruchamianie kodu. Jeśli nie używasz natywnej struktury danych bardziej złożonej niż tablica i dowolny obiekt, który sam napiszesz, nauczysz się w zasadzie tego samego, co w C / C ++, ale bez konieczności faktycznego zarządzania pamięcią.
Pozwólcie, że wyjaśnię: rozszerzalną tabelę skrótów należy zmienić, jeśli dodana zostanie wystarczająca liczba elementów. W każdej implementacji będzie to oznaczać wykonanie czegoś takiego jak podwojenie rozmiaru struktury danych bazowych (zazwyczaj tablicy) i skopiowanie istniejących elementów. Implementacja jest zasadniczo taka sama we wszystkich językach imperatywnych, ale w C / C ++ musisz radzić sobie z błędami segmentacji, gdy nie przydzielasz lub nie zwalniasz czegoś poprawnie.
Python lub Ruby (nie ma znaczenia, który) byłby moim następnym wyborem (i bardzo zbliżonym do pozostałych dwóch) tylko dlatego, że dynamiczne pisanie na początku może być problematyczne.