1.11 — Tworzenie pierwszego programu

Poprzednie lekcje wprowadziliśmy wiele terminologii i koncepcji, których będziemy używać w niemal każdym programie, który tworzymy. Na tej lekcji omówimy proces włączania tej wiedzy do naszego pierwszego prostego programu.

Pomnóż przez 2

Najpierw utwórzmy program, który poprosi użytkownika o wprowadzenie liczby całkowitej, poczeka, aż wprowadzi liczbę całkowitą, a następnie powie mu, ile wynosi 2 razy ta liczba. Program powinien wygenerować następujący wynik (zakładając, że jako dane wejściowe wpisałem 4):

Enter an integer: 4
Double that number is: 8

Jak sobie z tym poradzić? Krokami.

Najlepsza praktyka

Nowi programiści często próbują napisać cały program na raz, a potem czują się przytłoczeni, gdy pojawia się wiele błędów. Lepszą strategią jest dodawanie pojedynczych elementów, upewnianie się, że się skompilowano i testowanie. Następnie, gdy będziesz mieć pewność, że wszystko działa, przejdź do następnego elementu.

Wykorzystamy tutaj tę strategię. Podczas wykonywania każdego kroku wpisz (nie kopiuj/wklej) każdy program do edytora kodu, skompiluj go i uruchom.

Najpierw utwórz nowy projekt konsoli.

Teraz zacznijmy od podstawowego szkieletu. Wiemy, że będziemy potrzebować funkcji main() (ponieważ wszystkie programy C++ muszą ją mieć), więc jeśli Twoje IDE nie utworzyło pustej funkcji podczas tworzenia nowego projektu, utwórzmy ją:

int main()
{
	return 0;
}

Wiemy, że będziemy musieli wyprowadzić tekst do konsoli i pobrać tekst z klawiatury użytkownika, więc musimy dołączyć iostream, aby uzyskać dostęp do std::cout i std::cin.

#include <iostream>

int main()
{
	return 0;
}

Powiedzmy teraz użytkownikowi, że musi wprowadzić liczbę całkowitą:

#include <iostream>

int main()
{
	std::cout << "Enter an integer: ";

	return 0;
}

W tym momencie Twój program powinien wygenerować następujący wynik:

Enter an integer:

a następnie zakończyć.

Następnie uzyskamy dane wprowadzone przez użytkownika. Użyjemy std::cin i operator>> , aby uzyskać dane wejściowe użytkownika. Ale musimy także zdefiniować zmienną do przechowywania tych danych wejściowych do późniejszego wykorzystania.

#include <iostream>

int main() // note: this program has an error somewhere
{
	std::cout << "Enter an integer: ";

	int num{ }; // define variable num as an integer variable
	std::cin << num; // get integer value from user's keyboard

	return 0;
}

Czas na skompilowanie naszych zmian… i…

Och, och! Oto, co autor uzyskał w Visual Studio 2017:

1>------ Build started: Project: Double, Configuration: Release Win32 ------
1>Double.cpp
1>c:\vcprojects\double\double.cpp(8): error C2678: binary '<<': no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
1>c:\vcprojects\double\double.cpp: note: could be 'built-in C++ operator<<(bool, int)'
1>c:\vcprojects\double\double.cpp: note: while trying to match the argument list '(std::istream, int)'
1>Done building project "Double.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Wystąpił błąd kompilacji!

Po pierwsze, ponieważ program skompilował się przed wprowadzeniem najnowszej aktualizacji i nie kompiluje się teraz, błąd muszą znajduje się w właśnie dodanym kodzie (wiersze 7 i 8). To znacznie zmniejsza ilość kodu, który musimy przeskanować, aby znaleźć błąd. Linia 7 jest całkiem prosta (tylko definicja zmiennej), więc prawdopodobnie nie ma tam błędu. To sprawia, że ​​prawdopodobnym winowajcą jest linia 8.

Po drugie, ten komunikat o błędzie nie jest łatwy do odczytania. Rozróżnijmy jednak kilka kluczowych elementów: kompilator informuje nas, że napotkał błąd w linii 8. Oznacza to, że rzeczywisty błąd prawdopodobnie występuje w linii 8 lub być może w linii poprzedzającej, co potwierdza naszą wcześniejszą ocenę. Następnie kompilator informuje, że nie mógł znaleźć operatora „<<”, który ma lewy operand typu std::istream (który jest typem std::cin). Inaczej mówiąc, operator<< nie wie, co zrobić ze std::cin, więc błąd musi wynikać albo z użycia std::cin, albo z operatora<<.

Widzisz teraz błąd? Jeśli nie, poświęć chwilę i zobacz, czy uda ci się go znaleźć.

Oto program zawierający poprawiony kod:

#include <iostream>

int main()
{
	std::cout << "Enter an integer: ";

	int num{ };
	std::cin >> num; // std::cin uses operator >>, not operator <<!

	return 0;
}

Teraz program się skompiluje i będziemy mogli go przetestować. Program będzie czekał, aż wprowadzisz liczbę, więc wpiszmy 4. Wynik powinien wyglądać następująco:

Enter an integer: 4

Już prawie gotowe! Ostatnim krokiem jest podwojenie liczby.

Gdy zakończymy ten ostatni krok, nasz program zostanie pomyślnie skompilowany i uruchomiony, dając żądany wynik.

Są (co najmniej) 3 sposoby, aby to zrobić. Przejdźmy od najgorszego do najlepszego.

Niedobre rozwiązanie

#include <iostream>

// worst version
int main()
{
	std::cout << "Enter an integer: ";

	int num{ };
	std::cin >> num;

	num = num * 2; // double num's value, then assign that value back to num

	std::cout << "Double that number is: " << num << '\n';

	return 0;
}

W tym rozwiązaniu używamy wyrażenia do mnożenia num o 2, a następnie przypisz tę wartość z powrotem do num. Od tego momentu num będzie zawierać naszą podwójną liczbę.

Dlaczego jest to złe rozwiązanie:

  • Przed instrukcją przypisania num zawiera dane wprowadzone przez użytkownika. Po przypisaniu zawiera inną wartość. To mylące.
  • Nadpisaliśmy dane wprowadzone przez użytkownika, przypisując nową wartość do zmiennej wejściowej, więc jeśli chcielibyśmy rozszerzyć nasz program, aby później zrobić coś innego z tą wartością wejściową (np. potrojenie danych wejściowych użytkownika), zostało to już utracone.

W większości dobre rozwiązanie

#include <iostream>

// less-bad version
int main()
{
	std::cout << "Enter an integer: ";

	int num{ };
	std::cin >> num;

	int doublenum{ num * 2 }; // define a new variable and initialize it with num * 2
	std::cout << "Double that number is: " << doublenum << '\n'; // then print the value of that variable here

	return 0;
}

To rozwiązanie jest dość proste do odczytania i zrozumienia oraz rozwiązuje oba problemy napotykane w najgorszych przypadkach rozwiązanie.

Główną wadą jest to, że definiujemy nową zmienną (co zwiększa złożoność) do przechowywania wartości, której używamy tylko raz. Możemy zrobić lepiej.

Preferowane rozwiązanie

#include <iostream>

// preferred version
int main()
{
	std::cout << "Enter an integer: ";

	int num{ };
	std::cin >> num;

	std::cout << "Double that number is: " <<  num * 2 << '\n'; // use an expression to multiply num * 2 at the point where we are going to print it

	return 0;
}

To jest preferowane rozwiązanie ze wszystkich. Kiedy std::cout zostanie wykonane, wyrażenie num * 2 zostanie ocenione, a wynikiem będzie podwójna numwartość. Wartość ta zostanie wydrukowana. Wartość w num nie ulegnie zmianie, więc jeśli chcemy, możemy jej później użyć ponownie.

Ta wersja jest naszym rozwiązaniem referencyjnym.

Nota autora

Pierwszym i głównym celem programowania jest zapewnienie działania programu. Program, który nie działa, nie jest użyteczny niezależnie od tego, jak dobrze jest napisany.

Jednak jest takie powiedzenie, które lubię: „Musisz raz napisać program, aby wiedzieć, jak powinieneś go napisać za pierwszym razem”. Świadczy to o tym, że najlepsze rozwiązanie często nie jest oczywiste i że nasze pierwsze rozwiązania problemów zwykle nie są tak dobre, jak mogłyby być.

Kiedy skupiamy się na zastanawianiu się, jak sprawić, by nasze programy działały, nie ma większego sensu inwestowanie dużej ilości czasu w kod, którego nawet nie wiemy, czy będziemy przechowywać. Dlatego idziemy na skróty. Pomijamy takie rzeczy, jak obsługa błędów i komentarze. Do całego naszego rozwiązania dodajemy kod debugowania, który pomaga nam diagnozować problemy i znajdować błędy. Uczymy się w miarę upływu czasu — rzeczy, o których myśleliśmy, że mogą zadziałać, mimo wszystko nie działają, więc musimy się wycofać i wypróbować inne podejście.

Efekt końcowy jest taki, że nasze początkowe rozwiązania często nie są dobrze ustrukturyzowane, solidne (odporne na błędy), czytelne i zwięzłe. Zatem kiedy Twój program zacznie działać, Twoja praca tak naprawdę nie jest skończona (chyba że program jest jednorazowy/wyrzucony). Następnym krokiem jest oczyszczenie kodu. Obejmuje to takie czynności, jak: usuwanie (lub komentowanie) kodu tymczasowego/debugowania, dodawanie komentarzy, obsługa przypadków błędów, formatowanie kodu i zapewnienie przestrzegania najlepszych praktyk. Nawet wtedy Twój program może nie być tak prosty, jak mógłby być — być może istnieje nadmiarowa logika, którą można skonsolidować, wiele instrukcji, które można połączyć, lub zmienne, które nie są potrzebne, lub tysiąc innych drobnych rzeczy, które można uprościć. Zbyt często nowi programiści skupiają się na optymalizacji pod kątem wydajności, podczas gdy powinni optymalizować pod kątem łatwości konserwacji.

Bardzo niewiele rozwiązań przedstawionych w tych samouczkach wyszło świetnie za pierwszym razem. Są raczej wynikiem ciągłego udoskonalania, dopóki nie można znaleźć nic innego, co można by ulepszyć. W wielu przypadkach czytelnicy wciąż znajdują mnóstwo innych rzeczy do zaproponowania jako ulepszenia!

Wszystko to tak naprawdę oznacza: nie frustruj się, jeśli Twoje rozwiązania nie wyjdą cudownie zoptymalizowane prosto z Twojego mózgu. To normalne. Perfekcja w programowaniu to proces iteracyjny (wymagający powtarzalnych przejść).

Nota autora

Jeszcze jedna rzecz: możesz pomyśleć: "C++ ma tak wiele zasad i koncepcji. Jak mam to wszystko zapamiętać?".

Krótka odpowiedź: Nie. C++ to jedna część wykorzystująca to, co wiesz, i dwie części, w których sprawdzane jest, jak zrobić resztę.

Gdy czytasz tę witrynę po raz pierwszy, skup się mniej na zapamiętywaniu szczegółów, a bardziej na zrozumieniu, co jest możliwe. Następnie, gdy zajdzie potrzeba zaimplementowania czegoś w pisanym programie, możesz wrócić tutaj (lub do witryny referencyjnej) i odświeżyć wiedzę, jak to zrobić.

Czas quizu

Pytanie nr 1

Zmodyfikuj rozwiązanie do programu „najlepszego rozwiązania” powyżej, tak aby jego wynik był następujący (zakładając wprowadzenie danych przez użytkownika 4):

Enter an integer: 4
Double 4 is: 8
Triple 4 is: 12

Pokaż rozwiązanie

guest
Twój adres e-mail nie zostanie wyświetlony
Znalazłeś błąd? Zostaw komentarz powyżej!
Komentarze związane z poprawkami zostaną usunięte po przetworzeniu, aby pomóc zmniejszyć bałagan. Dziękujemy za pomoc w ulepszaniu witryny dla wszystkich!
Awatary z https://gravatar.com/ są połączone z podanym adresem e-mail.
Powiadamiaj mnie o odpowiedziach:  
496 Komentarze
Najnowsze
Najstarsze Najczęściej głosowane
Wbudowane opinie
Wyświetl wszystkie komentarze