Jak nauczyć się programować?

No właśnie… Moim (ale nie tylko moim) zdaniem, kod ma obrazować co zostanie zrobione, a nie jak. Abstrakcja jest ważniejsza niż szczegóły operowania na poziomie procesora, pamięci, itd. Po prostu, im kod ma więcej takich sprzętowych szczegółów, tym bardziej jest nieczytelny. A nieczytelny kod trudno się czyta.

Cóż, nawet w DSP używa sie zwykłego C. Do nauki jednak sie nadaje. W końcu od czegoś trzeba zacząć. C++ pozwala nauczyć sie dobrych nawyków pisania. Spotkałem sie z tym na uczelni - ci co chcieli związać sie bliżej z programowaniem sporo wynieśli z pisania programów w C++. Mnie rownież dał solidne podstawy. Wymaga samodyscypliny podczas pisania. I jak dla mnie jest to spory plus podczas nauki. Wymusza to jak piszemy program, dopóki nie wejdzie to w nawyk. Nie ma co, czytelność kodu zależy od osoby piszacej. Ale nie ograniczam sie tylko do C++. I to powinna być konkluzja tej rozmowy. Po to powstają osobne języki, które celuje w konkretne użycia. I choćby nie wiem co to i poczciwy ASM jest potrzebny. A C#, cóż rownież nie jest idealny. Ale jeśli potrzeba napisać program na Windowsa to z .NETem stanowi dobre rozwiazanie. Można i w Delphi - ale to przez dobrze napisana bibliotekę vcl. I warto powtórzyć najważniejsze - trzeba dobierać narzędzie do wykonywanej pracy. I lepiej mieć tych narzędzi sporo :slight_smile:

Czyt. “Dzięki C++ wyrobisz sobie nawyki będące lekarstwem na problemy w innych językach niewystępujące”. Super…

Kod ASM ciężko się czyta, ale Asembler pozwala tworzyć najwydajniejszy kod. Każdy ma inne priorytety. Dla jednych ważna jest czytelność kodu a dla innego jego wydajność. Użytkownicy programów bardziej cenią sobie to drugie, bo czytelność kodu źródłowego nic ich nie obchodzi.

Nie, nie czytaj. Po prostu C++ pomaga wyrobić sobie dobre nawyki pisania. Do nauki programowania jest bardzo dobry. Zresztą nie tylko. Będę się trzymał zdania, że pisanie w nim to nie jest katorga i najgorsza rzecz na świecie.

Nie ma czegoś takiego jak “wydajny kod”. Wydajny może być program, który jest pochodną kodu, a nie kod sam w sobie.

Ja od początku piszę o kodzie źródłowym - a ten ma być przede wszystkim czytelny.

Np. jakie? Stosowanie pseudoobiektowości, wielodziedziczenia i zaprzyjaźnianie klas? Uff, jak dobrze, że w normalnych językach tych cudów nie ma.

http://thread.gmane.org/gmane.comp.vers … ocus=57918

http://www.cpp-home.com/tutorials/244_1.htm

Oczywiście, że jest coś takiego jak wydajny kod. Program to kod zrozumiały dla procesora.

Nie wiem co takiego nieczytelnego jest w składni języka C++. Wszystko jest kwestią przyzwyczajenia. Dla mnie nieczytelne są języki, których nie znam.

Twój kod jest dla mnie nieczytelny. Pomijam już fakt, że wczytane liczby umieszczasz w tablicy, co jest niepotrzebne a wręcz niewskazane. Poniższy kod jest dla mnie dużo bardziej czytelny.

#include 

#include 

#include 


using namespace std;


int main()

{

  float maxv = numeric_limits::min();

  float minv = numeric_limits::max();

  float value, sum = 0, counter = 0;

  char key;


  do

  {

    while(true)

    {

      cout << "Podaj liczbe: "; cin >> value;

      if (cin.fail())

      {

        cin.clear();

        cin.ignore();

      }

      else break;

    }


    minv = min(value, minv);

    maxv = max(value, maxv);

    sum += value; 

    ++counter;


    do 

    {

      cout << "Czy koniec wprowadzania? [T/N]: "; cin >> key;

      key = toupper(key);

    } 

    while((key != 'T') && (key != 'N'));

  } 

  while(key != 'T');


  cout << "Najwieksza z wczytanych liczb to " << maxv << endl;

  cout << "Najmniejsza z wczytanych liczb to " << minv << endl;

  cout << "Srednia z wczytanych liczb to " << sum / counter << endl;


  return 0;

}

Twój kod nie jest dla mnie nieczytelny dlatego, że do rozwiązania problemu użyłeś tablicy. Czytelność kodu jest dla mnie kwestią przyzwyczajeń. Clojure jest dla mnie nieczytelny przez jego składnię. Python jest dla mnie mniej czytelny z uwagi na brak w tym języku znaczników wydzielających bloki kodu.

Co zaś do użycia przez Ciebie tablicy. Zgadnij co się stanie, gdy będę chciał wczytać miliard liczb do programu. Jesteś pewien, że wystarczy mi pamięci w systemie? Pomijam już fakt, że po wczytaniu wszystkich danych, czterokrotnie przechodzisz przez całą tablicę aby wyliczyć trzy parametry. W najlepszym przypadku podałeś przykład na to, jak nie powinno się rozwiązywać pewnych problemów.

W przypadku chęci dodania nowych funkcji mój kod nie będzie nadawał się wyłącznie do śmietnika. Mogę obudować pewne funkcje i zachować czytelność kodu.

Nie wiem jak Ty, ale ja piszę kod źródłowy, a nie maszynowy. :slight_smile:

Ale niech będzie, że uściślę - nie ma czegoś takiego jak “wydajny kod źródłowy”.

Dla mnie języki, których nie znam są po prostu nieznane. Chociaż widząc pierwszy raz na oczy kod jakiegoś języka, nieraz potrafię go, przynajmniej w części, zrozumieć.

Właściwie można by zrobić taki eksperyment i posadzić programistę:

  1. takiego, który nie zna C# przed kodem C#;

  2. takiego, który nie zna Javy przed kodem Javy;

  3. i takiego, który nie zna C++ przed kodem C++.

I poprosić ich o próbę zrozumienia kodu intuicyjnie. Ciekawe, któremu się to najmniej uda.

Pod warunkiem, że kod źródłowy nie jest kodem maszynowym :wink:

Im język wyższego poziomu, tym mniej wiem co i jak będzie wykonywane w danym fragmencie kodu źródłowego.

Jeżeli ktoś nie zna obiektowego modelu programowania, to w zasadzie niewiele zrozumie. Poza tym, podstawowa składnia tych trzech języków jest do siebie bardzo podobna.

Tak, utrudnia mi czytanie kodu to, czego w nim nie ma. Nie mam czasu bawić się w zgadywanie, jak będzie wykonywany dany fragment kodu i jakie typy będą używane.

Mój kod wcale nie jest dużo większy od Twojego. Chciałeś użyć funkcji, to użyłeś. Dla mnie jest to przerost formy nad treścią w przypadku tak banalnego zadania.

Nie zapamiętuję danych, jeżeli nie muszę tego robić. Nie dzielę krótkiego kodu na funkcje, jeżeli funkcje te nie są wykorzystywane w innych częściach kodu.

Tak sobie to tłumacz.

Ja nie straciłem kontroli nad kodem, gdyż dokładnie wiem co, kiedy i dlaczego się dzieje. W przypadku wystąpienia błędu mogłem usunąć pozostałe dane z bufora, ale celowo tego nie zrobiłem. Nie zakładam także tak jak Ty, że każda dana przechowywana jest w osobnym wierszu.

Tablica i wyjątki w kodzie, który tego nie wymaga - wydajnościowy koszmar. Gdybym pisał tak programy to umarłbym z głodu.

Wyjątki to tylko jeden ze sposobów obsługi błędów, bardzo kosztowny w języku C++.

Dobrze, rozważmy taki przypadek. Zachodzi potrzeba przetwarzania w programie miliarda liczb. Efekt? Twój rozwojowy kodu trzeba przepisać od nowa.

Gdybym ja miał tworzyć rozwojowy kod, utworzyłbym coś na kształt takiej klasy:

template

struct algorithm

{

  typedef std::function ftype;


  algorithm(ftype f, T v) : function(f), value(v) {}


  void calculate(T v) 

  { 

    function(value, v); 

  }


  ftype function;

  T value;

};

a następnie tak z niej skorzystał:

int main()

{

  vector> vec;

  vec.push_back(algorithm([](float& r, float v){ r = max(r, v); }, numeric_limits::min()));

  vec.push_back(algorithm([](float& r, float v){ r = min(r, v); }, numeric_limits::max()));

  vec.push_back(algorithm([](float& r, float v){ r += v; }, 0));

  vec.push_back(algorithm([](float& r, float v){ ++r; }, 0));


  do 

  {

    float v = getvalue();

    for (algorithm& a: vec) a.calculate(v); 

  } 

  while(!finish());


  cout << "Najwieksza z wczytanych liczb to " << vec[0].value << endl;

  cout << "Najmniejsza z wczytanych liczb to " << vec[1].value << endl;

  cout << "Srednia z wczytanych liczb to " << vec[2].value / vec[3].value << endl;


  return 0;

}

Mam elastyczny kod i nie muszę pamiętać wczytywanych danych.

To się zgadza. Jednak zabezpieczając się przed użytkownikiem powinieneś także pomyśleć o tym, że użytkownik może chcieć przetwarzać duże ilości danych. Twój kod ogranicza ilość możliwych do przetworzenia danych, choć nie musi tego robić.

Chętnie zobaczę jakiś zaawansowany programu do edycji zdjęć, napisany w Javie, Scali czy Clojure. Znasz taki?

Ja znam większą ilość języków kompilowanych do binarnego…

Dodane 09.04.2013 (Wt) 16:01

Ja znam większą ilość języków kompilowanych do binarnego…

Nie wiem w czym Ty widzisz problem:

vec.push_back(algorithm([](float& r, float v){ r *= v; }, 1));

...

cout << "Srednia geometryczna to " << pow(vec[4].value, 1.0f / vec[3].value) << endl;

Zmieniłem kod bo chciałeś, aby kod był rozwojowy. Nie jest dla Ciebie czytelny? Można go bardziej opakować, ale ja nie widzę takiej potrzeby.

W języku C++ mamy podany zakres na którym operujemy, oraz określony typ, na który będą rzutowane elementy kolekcji. Myślisz, że tego kodu nie da się uprościć? Można, tylko po co.

W takim przypadku zachodzi potrzeba scalania wyników cząstkowych. Mój kod znacznie lepiej się do tego nadaje, aniżeli Twój.

Taki program można napisać w czymkolwiek.

To się tyczy także projektów Open Source?

AutoCad tylko częściowo korzysta z .NET. Większość kodu została napisana w języku C++.

To, że język C++ jest wykorzystywany do tworzenia wydajnych aplikacji.

Widać, że twórcy takich aplikacji mają odmienne zdanie na ten temat.

Ja wolę dodać jedną linijkę kodu więcej i mieć wydajniejszy program. Każdy ma inne priorytety.

Gdybym chciał mieć więcej czasu na picie kawy, tobym sobie zatrudnił kogoś do wklepywania kodu.

Aż dziw bierze, że programy dekodujące strumienie wideo, nie przechowują w programie wszystkich wczytywanych danych. Przecież ktoś mógłby chcieć robić z tych danych wykresy.

Że co proszę? Poczytaj sobie o GCC.

Co ma piernik do wiatraka?

Czyli sam sobie przeczysz, bo wiele projektów Open Source jest tworzonych w języku C++.

Plik źródłowe Blendera 2.66a:

Język C/C++: 4431 plików.

Python: 884 pliki.

Platforma .NET ma bardzo bogaty i spójny zestaw bibliotek. Gdy wydajność ma drugorzędne znaczenie, prościej jest skorzystać z gotowych rozwiązań.

Twoja argumentacja jest kiepska, gdyż narzędzia pozwalające zaciemniać kod dostępne są dla wielu języków. Poza tym, gdy ktoś bardzo chce się dowiedzieć jak działa dany kod, to się tego dowie. Wystarczy przeanalizować kod maszynowy.

Język C jest podzbiorem języka C++.

Tak sobie to tłumacz.

To akurat zapewne kolejna projekcja @RaveStara, który nie od dziś twierdzi, że Windows został napisany w C++ i przez to jest nieprzenośny.

C jest prostym, ale przemyślanym językiem programowania, który pozwala pisać wydajne programy.

C++ jest nieudolną przeróbką C na język obiektowy, która wygląda jak próba zrobienia ośmiornicy z jamnika poprzez przybicie do niego czterech desek.

Możesz podać przykład na to, co można było zrobić lepiej?

@RaveStar

Widzisz w języku C++ wady tam, gdzie inni widzą zalety. Ten “śmietnik”, jak go nazwałeś, będzie jeszcze długo bardzo popularny.

Skąd ty te “fakty” wysysasz? AutoCad istnieje od 1982 roku i na początku był pisany w C.