if
and switch
. Enumeration types.The program has to compute the roots of the quadratic equation. It should correctly identify the cases when
and report the answer accordingly.
#include <iostream>
#include <cmath>
int main() {
std::cout
<< "Solving an equation of the form ax^2 + bx + c = 0:"
<< std::endl;
int a = 5;
int b = 6;
int c = 1;
std::cout
<< "a = " << a << ", "
<< "b = " << b << ", "
<< "c = " << c << std::endl;
int d = b*b - 4*a*c;
if (d > 0) {
double x1 = (-b + sqrt(d))/(2.0*a);
double x2 = (-b - sqrt(d))/(2.0*a);
std::cout << "Two roots:" << std::endl;
std::cout << "x1 = " << x1 << std::endl;
std::cout << "x2 = " << x2 << std::endl;
}
else if (d == 0) {
std::cout << "One root of multiplicity two: " << std::endl;
std::cout << "x = " << (-b/(2.0*a)) << std::endl;
}
else {
std::cout << "No roots" << std::endl;
}
return 0;
}
Solving an equation of the form ax^2 + bx + c = 0:
a = 5, b = 6, c = 1
Two roots:
x1 = -0.2
x2 = -1
#include <iostream>
using namespace std;
int main() {
bool b1 = true;
bool b2 = false;
// Boolean operators
bool b3 = b1 && b2; // and (bool, bool -> bool)
bool b4 = b1 || b2; // or (bool, bool -> bool)
bool b5 = !b1; // not (bool -> bool)
int i = 2;
int j = 3;
// Relational operators
// (for numerical types, such as int and double)
bool b6 = i <= j; // less or equal (int, int -> bool)
bool b7 = i >= j; // greater or equal (int, int -> bool)
bool b8 = i < j; // less (int, int -> bool)
bool b9 = i > j; // greater (int, int -> bool)
// Equality operators
bool b10 = i == j; // equal (int, int -> bool)
bool b11 = i != j; // not equal (int, int -> bool)
// The equality operators == and != work not only for
// numerical types, but for comparing booleans as well
// complex boolean expression
bool c1 = (b1 || b5) && (!b2);
// mixing arithmetic and boolean operators
bool c2 =
(((0 < i) && (i < 15)) || !(-4 >= j*5 + i)) && (i != j);
return 0;
}
Observe that the division by zero (5/0 == 1
) is not evaluated in both if
statements:
#include <iostream>
using namespace std;
int main(){
if ( false && (5/0 == 1) && (0 <= 1) ) {
cout << "first" << endl;
}
if ( true || (5/0 == 1) || (0 <= 1) ) {
cout << "second" << endl;
}
return 0;
}
second
If the division by zero were evaluated, you would get a runtime error:
#include <iostream>
using namespace std;
int main(){
if ( (5/0 == 1) && (0 <= 1) ) {
cout << "first" << endl;
}
return 0;
}
Floating point exception (core dumped)
(Inclomplete) operator precedence order:
sqrt(2.0)
or abs(-5)
)+
, -
, and !
*
/
%
+
-
<
>
<=
>=
==
!=
&&
||
This order actually does make sense! After evaluating the unary operators (there is no ambiguity at this stage), the arithmetic operators compute the numbers. Then, the comparison operators compare the numbers you’ve got to produce boolean values. Then, the logical connectives (and and or) combine those boolean values.
For example, consider the following two assignment statements:
int b1 = 2 + 3 - 4 <= 1 || x == 4 && y / 2 != 0;
int b2 = (((2 + 3) - 4) <= 1) || ((x == 4) && ((y / 2) != 0));
Both statements compute the same expression, however, the first relies on the operators precedence, and the second is fully parenthesized.
Avoid excessive parentheses, where the meaning and the order is clear, however, it’s good to keep some of the parentheses to make the code more readable and reduce the chance to make a mistake:
int b3 = (2 + 3 - 4 <= 1) || ((x == 4) && (y / 2 != 0));
See pp. 51 - 52 for the full operator precedence table.
=
in place of ==
#include <iostream>
using namespace std;
int main(){
int x = 0;
cout << "x = " << x << endl;
// Instead of comparing x to 1, by mistake, we are
// assigning x = 1 (here, x actually becomes equal to 1)
if (x = 1) {
cout << "x is equal to 1!" << endl;
}
// Correct way to check equality:
if (x == 2) {
cout << "x is equal to 2!" << endl;
}
// A trick to avoid such errors:
// The compiler will complain if you try to assign 3 = x
if (3 == x) {
cout << "x is equal to 3!" << endl;
}
return 0;
}
x = 0
x is equal to 1!
int
and bool
Beware! Integers and bools can be used interchangeably! If that happens, the following type conversions are automatically executed:
true
is converted to 1
.
false
is converted to 0
.
0
is converted to false
.
any non-zero integer is converted to true
.
#include <iostream>
using namespace std;
int main() {
cout << true + 5 << endl;
cout << false + 5 << endl;
if (7) {
cout << "7 means true!" << endl;
}
if (0) {
cout << "0 is false! This will not be printed" << endl;
}
return 0;
}
6
5
7 means true!
switch
statement#include <iostream>
using namespace std;
int main() {
int i = 4;
if (0 == i) { cout << "zero"; }
else if (1 == i) { cout << "one"; }
else if (2 == i) { cout << "two"; }
else if (3 == i) { cout << "tree"; }
else if (4 == i) { cout << "four"; }
else { cout << "other"; }
cout << endl;
switch (i) {
case 0 :
cout << "zero";
break;
case 1 :
cout << "one";
break;
case 2 :
cout << "two";
break;
case 3 :
cout << "three";
break;
case 4 :
cout << "four";
break;
default:
cout << "other";
}
cout << endl;
return 0;
}
four
four
The “fall-through” behavior when break
is missing:
#include <iostream>
using namespace std;
int main() {
char c = ' ';
cout << "Enter a character: ";
cin >> c;
bool paren = false;
bool bracket = false;
bool plus = false;
switch(c){
case '(':
case ')':
paren = true;
break;
case '[':
case ']':
bracket = true;
break;
case '+':
plus = true;
break;
}
if (paren) cout << "parenthesis";
if (bracket) cout << "bracket";
if (plus) cout << "plus";
cout << endl;
return 0;
}
Enter a character: (
parenthesis
enum
) types#include <iostream>
using namespace std;
enum Token {PAREN, BRACKET, PLUS};
int main() {
char c = ' ';
cout << "Enter a character: ";
cin >> c;
Token t = PAREN;
switch(c){
case '(':
case ')':
t = PAREN;
break;
case '[':
case ']':
t = BRACKET;
break;
case '+':
t = PLUS;
break;
}
switch(t) {
case PAREN:
cout << "parenthesis";
break;
case BRACKET:
cout << "bracket";
break;
case PLUS:
cout << "plus";
break;
}
cout << endl;
return 0;
}
Enter a character: ]
bracket