Wyrażenia
Rozważmy następującą serię instrukcji, z których każda definiuje zmienną i inicjuje ją:
// five() is a function that returns the value 5
int five()
{
return 5;
}
int main()
{
int a{ 2 }; // initialize variable a with literal value 2
int b{ 2 + 3 }; // initialize variable b with computed value 5
int c{ (2 * 3) + 4 }; // initialize variable c with computed value 10
int d{ b }; // initialize variable d with variable value 5
int e{ five() }; // initialize variable e with function return value 5
return 0;
}Należy zauważyć, że powyższe inicjatory wykorzystują wiele różnych jednostek: literały, zmienne, operatory i wywołania funkcji. W jakiś sposób C++ konwertuje wszystkie te różne rzeczy na jedną wartość, która może być następnie użyta jako wartość początkowa zmiennej.
Co mają wspólnego wszystkie te inicjatory? Używają wyrażenia.
W ogólnym programowaniu wyrażenie to niepusta sekwencja literałów, zmiennych, operatorów i wywołań funkcji, która oblicza wartość. Nazywa się proces wykonywania wyrażenia oceną, a uzyskana w ten sposób wartość nazywana jest wyniku wyrażenia (czasami zwanego także wartość zwracana).
Dla zaawansowanych czytelników
W C++ wynikiem wyrażenia jest jeden z następujących:
- Wartość (najczęściej)
- Obiekt lub funkcja. Na lekcji omawiamy wyrażenia zwracające obiekty 12.2 — Kategorie wartości (lwartości i rwartości).
- Nic. Są to wyniki wywołań funkcji, które nie zwracają wartości (omówionych w lekcji 2.3 — Funkcje puste (funkcje nie zwracające wartości)), które są nazywane tylko ze względu na ich skutki uboczne
Na razie, dla uproszczenia, założymy, że wyrażenia są oceniane w celu wygenerowania wartości.
Podczas oceniania wyrażenia oceniany jest każdy termin znajdujący się w wyrażeniu, aż do pozostawienia pojedynczej wartości. Oto kilka przykładów różnych rodzajów wyrażeń wraz z komentarzami wskazującymi sposób ich oceny:
2 // 2 is a literal that evaluates to value 2
"Hello world!" // "Hello world!" is a literal that evaluates to text "Hello world!"
x // x is a variable that evaluates to the value held by variable x
2 + 3 // operator+ uses operands 2 and 3 to evaluate to value 5
five() // evaluates to the return value of function five()Jak widać, literały wyznaczają swoje własne wartości. Zmienne wyznaczają wartość zmiennej. Operatorzy (np operator+) używają swoich operandów do obliczenia innej wartości. Nie omówiliśmy jeszcze wywołań funkcji, ale w kontekście wyrażeń wywołania funkcji wyznaczają dowolną wartość zwracaną przez funkcję.
Dla zaawansowanych czytelników
Wyrażenia zawierające operatory z efektami ubocznymi są nieco trudniejsze:
x = 5 // x = 5 has side effect of assigning 5 to x, evaluates to x
x = 2 + 3 // has side effect of assigning 5 to x, evaluates to x
std::cout << x // has side effect of printing value of x to console, evaluates to std::coutKluczowa informacja
Gdziekolwiek w C++ oczekiwana jest pojedyncza wartość, można zamiast tego użyć wyrażenia generującego wartość, a wyrażenie zostanie ocenione pod kątem wygenerowania pojedynczej wartości.
Wyrażenia nie kończą się średnikiem i nie mogą być kompilowane samodzielnie. Na przykład, jeśli chcesz spróbować skompilować wyrażenie x = 5, Twój kompilator narzekałby (prawdopodobnie z powodu brakującego średnika). Raczej wyrażenia są zawsze oceniane jako część instrukcji.
Weźmy na przykład to stwierdzenie:
int x{ 2 + 3 }; // 2 + 3 is an expression that has no semicolon -- the semicolon is at the end of the statement containing the expressionJeśli rozbić to stwierdzenie na składnię, wyglądałoby to tak:
type identifier { expression };
typ może być dowolnym prawidłowym typem (wybraliśmy int). identyfikatorem może być dowolną poprawną nazwą (wybraliśmy x). I wyrażenie może być dowolnym prawidłowym wyrażeniem (wybraliśmy 2 + 3, który używa dwóch literałów i operatora).
Wyrażenia wyrażeń
Niektóre wyrażenia (np x = 5) są używane przede wszystkim ze względu na ich skutki uboczne (w tym przypadku do przypisania wartości 5 do zmiennej x), a nie wartość, którą wytwarzają.
Powiązana treść
Na lekcjach omawiamy skutki uboczne 1.9 -- Wprowadzenie do literałów i operatorów).
Jednakże wspomnieliśmy powyżej, że wyrażenia nie mogą być wykonywane samodzielnie — muszą istnieć jako część instrukcji. Na szczęście przekształcenie dowolnego wyrażenia w równoważną instrukcję jest banalne. Jakiś instrukcja wyrażenia to instrukcja składająca się z wyrażenia, po którym następuje średnik. Kiedy instrukcja wyrażenia zostanie wykonana, wyrażenie zostanie ocenione.
Zatem możemy przyjąć dowolne wyrażenie (np x = 5) i zamień go w instrukcję wyrażenia (x = 5;), który się skompiluje.
Kiedy wyrażenie jest użyte w instrukcji wyrażenia, każdy wynik wygenerowany przez to wyrażenie jest odrzucany (ponieważ nie jest używany). Na przykład, gdy wyrażenie x = 5 ocenia, wartość zwracana przez operator= zostaje odrzucony. I to jest w porządku, ponieważ i tak chcieliśmy po prostu przypisać 5 Do x .
Bezużyteczne instrukcje wyrażeń
Możemy również tworzyć instrukcje wyrażeń, które kompilują się, ale nie dają żadnego efektu. Na przykład instrukcja wyrażenia (2 * 3;) jest instrukcją wyrażenia, której wyrażenie daje w wyniku wartość 6, która jest następnie odrzucana. Choć składniowo poprawne, takie wyrażenia są bezużyteczne. Niektóre kompilatory (takie jak gcc i Clang) będą generować ostrzeżenia, jeśli wykryją, że instrukcja wyrażenia jest bezużyteczna.
Podwyrażenia, wyrażenia pełne i wyrażenia złożone
Czasami musimy porozmawiać o określonych rodzajach wyrażeń. W tym celu zdefiniujemy kilka powiązanych terminów.
Rozważmy następujące wyrażenia:
2 // 2 is a literal that evaluates to value 2
2 + 3 // 2 + 3 uses operator+ to evaluate to value 5
x = 4 + 5 // 4 + 5 evaluates to value 9, which is then assigned to variable xW pewnym uproszczeniu, podwyrażenie jest wyrażeniem używanym jako operand. Na przykład podwyrażenia x = 4 + 5 są x i 4 + 5. Podwyrażenia 4 + 5 są 4 i 5.
A pełne wyrażenie to wyrażenie, które nie jest podwyrażeniem. Wszystkie trzy powyższe wyrażenia (2, 2 + 3, I x = 4 + 5) są wyrażeniami pełnymi.
W języku potocznym wyrażenie złożone jest wyrażeniem zawierającym dwa lub więcej zastosowań operatorów. x = 4 + 5 jest wyrażeniem złożonym, ponieważ zawiera dwa zastosowania operatorów (operator= i operator+). 2 i 2 + 3 nie są wyrażeniami złożonymi.
Czas quizu
Pytanie nr 1
Jakie jest wyrażenie złożone różnica między instrukcją a wyrażeniem?
Pytanie nr 2
Wskaż, czy każdy z poniższych wierszy jest instrukcjami niezawierającymi wyrażeń, instrukcjami zawierającymi wyrażenia, lub are Instrukcja wyrażeniowa.
A)
int x;B)
int x = 5;C)
x = 5;d) Dodatkowy kredyt:
foo(); // foo is a functione) Dodatkowe zasługi:
std::cout << x; // Hint: operator<< is a binary operator.Pytanie nr 3
Określ, jakie wartości wyprowadza następujący program. Nie kompiluj tego programu. Po prostu przeanalizuj to wiersz po wierszu w głowie.
#include <iostream>
int main()
{
std::cout << 2 + 3 << '\n';
int x{ 6 };
int y{ x - 2 };
std::cout << y << '\n';
int z{};
z = x;
std::cout << z * x << '\n';
return 0;
}
