Variables and auto
Programs need to remember things: a test score, the price of an item, a customer's name. A variable is a named box that holds one value. In C++, before you use a variable you say two things: what it's called, and what kind of value it holds.
1#include <iostream>2 3int main() {4 int score = 90;5 std::cout << "Score: " << score << '\n';6 return 0;7}
Score: 90
int score = 90; means: give me a box for a whole number (int), call it score, and put 90 in it. std::cout << score shows the value in the box, not the letters score.
The '\n' at the end has single quotes: it is one character, and it ends the line just like "\n". More on characters in a moment.
Declaring and assigning
int stock; declares a variable: it tells the compiler there is a variable that holds a whole number. stock = 12; is an assignment: it puts a value in the box. You can write the two steps apart, or join them in one line as above.
1#include <iostream>2 3int main() {4 int stock;5 stock = 12;6 std::cout << "Stock: " << stock << '\n';7 stock = 7;8 std::cout << "Stock: " << stock << '\n';9 return 0;10}
Stock: 12 Stock: 7
You can assign as many times as you like; the new value replaces the old one. In C++, = doesn't mean "equals". It means "put the value on the right into the variable on the left". Press Step and watch stock go from 12 to 7.
What does this program show?
1#include <iostream>2 3int main() {4 int a = 5;5 int b = a;6 a = 9;7 std::cout << b << '\n';8 return 0;9}
int b = a; copies the value a had at that moment, 5, into b. When a later becomes 9, the 5 in b doesn't change.
The basic types
Every variable has a fixed type, written before its name when you declare it, and it can't change later. Here are the five you'll use most:
| Type | Holds | Examples |
|---|---|---|
int | whole numbers | 90, -3, 0 |
double | numbers with a decimal point | 4.5, -0.25 |
char | one character, in single quotes | 'A', '7', '\n' |
bool | true or false | true, false |
std::string | a piece of text, in double quotes | "Ana", "apple" |
std::string comes from the standard library too, and needs #include <string>. One cout statement can show several variables in a row:
1#include <iostream>2#include <string>3 4int main() {5 std::string name = "Ana";6 int count = 3;7 double price = 4.5;8 char size = 'M';9 bool paid = true;10 std::cout << name << " bought " << count << " at " << price << " each\n";11 std::cout << "Size: " << size << ", paid: " << paid << '\n';12 return 0;13}
Ana bought 3 at 4.5 each Size: M, paid: 1
cout doesn't add extra zeros to a double: 4.5 shows as 4.5. A bool shows as 1 (true) or 0 (false); lesson 6 shows how to get true / false instead. A char holds a single letter, digit or symbol; longer text goes in a std::string.
Assign before you use
If you declare a variable but never give it a value, what's in the box? C++ doesn't say: it could be any number, and it may differ from run to run. Using such a value is undefined behavior. On an ordinary computer the program carries on and shows some strange number. Our engine stops at the line where it happens and tells you which variable it was:
1#include <iostream>2 3int main() {4 int total;5 std::cout << "Total: " << total << '\n';6 return 0;7}
Total:
use of uninitialized valueWhat happened: Stopped at line 5. A variable was used before it was given a value. In real C++ it would hold garbage, different on every run.
The fix is simple: give it a value when you declare it, such as int total = 0;. A std::string is different: without a value it is an empty string, "", and safe to use.
Tip: When you declare an int, a double and the like, give it a value right away, and this mistake can't happen.
Constants with const
Some values are set once and should never change, like the number of days in a week. Put const in front when you declare it and it becomes a constant; if anything tries to change it, the compiler refuses:
1#include <iostream>2 3int main() {4 const int DAYS_IN_WEEK = 7;5 std::cout << "A week has " << DAYS_IN_WEEK << " days\n";6 DAYS_IN_WEEK = 8;7 return 0;8}
main.cpp: In function 'int main()':
main.cpp:6:18: error: assignment of read-only variable 'DAYS_IN_WEEK'
6 | DAYS_IN_WEEK = 8;
| ~~~~~~~~~~~~~^~~A read-only variable can be read but not changed. Constants are often named in capital letters with underscores, so they stand out from ordinary variables. Remove the last assignment and the program runs.
auto: let the compiler work out the type
Write auto instead of a type, and the compiler looks at the value on the right of = to work out the variable's type:
1#include <iostream>2 3int main() {4 auto count = 3;5 auto price = 4.5;6 auto grade = 'A';7 auto total = price * count;8 std::cout << count << " " << price << " " << grade << " " << total << '\n';9 return 0;10}
3 4.5 A 13.5
3 is a whole number, so count is an int; 4.5 has a decimal point, so price is a double; 'A' is a character, so grade is a char; price * count gives a double, so total is one too. Press Step to see each variable as it appears.
auto doesn't mean "holds anything": the type is fixed the moment you declare it.
What does this program show?
1#include <iostream>2 3int main() {4 auto people = 3;5 people = 3.9;6 std::cout << people << '\n';7 return 0;8}
auto people = 3; makes people an int. When 3.9 goes in later, the decimal part is simply dropped (not rounded), so it's 3.
For short types like int and double, this course still writes them out; it reads more clearly. When you meet very long type names later, auto saves a lot of typing.
Note: auto name = "Ana"; does not give you a std::string; it gives you a C-style string. When you want a string, write std::string name = "Ana";.
Brace initialization
There is another way to give a variable its first value: put the value in curly braces, int score{90};. It works like = 90, with one extra check: if the value doesn't fit, the compiler reports an error instead of quietly dropping part of it.
1#include <iostream>2 3int main() {4 int people{3.9};5 std::cout << people << '\n';6 return 0;7}
main.cpp: In function 'int main()':
main.cpp:4:16: error: narrowing conversion of '3.8999999999999999e+0' from 'double' to 'int' [-Wnarrowing]
4 | int people{3.9};
| ^~~A narrowing conversion is one that loses information: putting the double 3.9 into an int drops the decimals, and braces don't allow that. (The 3.8999999999999999e+0 in the error is 3.9: computers don't store most decimals exactly.) In this course, plain variables use =; braces come in when we get to containers like std::vector.
Naming rules
Variable names are made of letters, digits and the underscore _, with a few rules:
| Rule | OK | Not OK |
|---|---|---|
Only letters, digits and _ | total_price | total-price |
| Can't start with a digit | day2 | 2day |
| No spaces | max_score | max score |
| Not one of C++'s own words | count | int |
Capital and small letters are different, so score and Score are two variables:
1#include <iostream>2 3int main() {4 int score = 90;5 int Score = 60;6 std::cout << score << " and " << Score << '\n';7 return 0;8}
90 and 60
That you can doesn't mean you should: two names that differ only in case are easy to mix up. Pick names that say what they hold: price beats p, and max_score beats ms.
Practice
Write the code, then press Check. A hint costs nothing; the answer is there when you need it.
One item
✓Declare three variables: a std::string name of "Milk", a double price of 6.5, and an int stock of 20. Use them to show Milk: $6.5, 20 left.
Milk: $6.5, 20 left
1#include <iostream>2#include <string>3 4int main() {5 6 return 0;7}
A total with auto
✓Declare total with auto, set to price * count, then show Total: 13.
Total: 13
1#include <iostream>2 3int main() {4 double price = 6.5;5 int count = 2;6 7 return 0;8}
Fix it: a price that doesn't fit
✓This program doesn't compile. Fix it so it shows Price: 19.9.
Price: 19.9
1#include <iostream>2 3int main() {4 int price{19.9};5 std::cout << "Price: " << price << '\n';6 return 0;7}
What you learned
- Declare a variable before you use it:
int stock;declares,stock = 12;assigns, or join them asint stock = 12;. =puts the value on the right into the variable on the left; a new assignment replaces the old value.intholds whole numbers,doubledecimals,charone character,booltrue or false,std::stringtext.- One
coutstatement with several<<shows several things in a row; aboolshows as 1 or 0. - Using an
intthat was never given a value is undefined behavior; give it a value when you declare it. constmakes a variable a constant; changing it is a compile error.autolets the compiler work out the type from the value on the right, and then the type is fixed.- Brace initialization
int n{3};doesn't allow narrowing:int n{3.5}is a compile error. - Names use letters, digits and
_, don't start with a digit, aren't C++'s own words, and case matters.