Video Coming Soon...

Created by Zed A. Shaw Updated 2024-09-06 01:36:52

06: Variables and Simple Types

Printing a bunch of strings to the screen is boring. In this exercise we'll learn to create other types of data and output them in the same way. The primary way you use data in C++ is with variables and each variable has a type that tells C++ how to work with it. Once you understand this concept it begins to open up so much more about the language.

How to Make a Variable

To create a variable you use the = (equal) symbol to set a name to a value. Here's an example:

int age = 50;

The structure of an assignment is this:

<type> <name> = <value>;
  1. The <type> is a C++ keyword like int, long, string but can be more than one word like unsigned long long.
  2. The <name> is almost any combination of letters, numbers, and _ underscore characters, with a few limitations. In general, start your variables with a lowercase letter. You can use an uppercase letter but it'll make other code confusing.
  3. = is simply the equal symbol you learned from Exercise 4.
  4. <value> is then a piece of data that matches the <type> you gave in the start. You'll (usually) get errors if you try to assign a value that doesn't match its type, so if you try to assign a string to something you said was int it will fail.

If you take this information and map it to the sample code you get this:

The auto Keyword

Modern C++ now has a new keyword called auto that uses the <value> to figure out the type. It can make writing code a lot easier, but also can make it more confusing in some situation. Let's look at an example of using auto:

auto age = 50;

The C++ compiler is smart enough to know that 50 is an integer, so it sets the type to int for you. This can be very handy when you're dealing with an API and you're not sure what type to use or if the type will change during development.

For example, you can write this:

auto foo = makeTheThing();

The problem with auto is it hides the types, which are useful information for your code. Knowing that something is an int or string is helpful when you're writing more code.

What I recommend for auto is this:

  1. Use auto when you're first writing code and don't quite know the type of something yet, or you're just prototyping the idea at first.
  2. Once your code is working well, start replacing the auto keywords with the specific types to "lock them down" or as documentation.
  3. As you gain more knowledge about the code you'll want to stop using auto and use the types directly.

There are other uses for auto but for now, just stick to using it on variables to help you write code.

lvalue and rvalue

In C++ there are two concept called the "left value" and "right value" that I've always found the terms confusing. They're supposed to tell you when you can modify something or not, but because they use "left" and "right" it's not easy to remember which is which without simply memorizing it.

Typically an "lvalue" is on the left-hand side of an assignment and can be changed. This means you can keep assigning to it and changing it as you write your code. An rvalue is usually on the right-hand side of an assignment and cannot be changed or assigned to.

Let's look at our running example again, but with another two lines of code to demonstrate:

int age = 50;
age = 100;
88 = age;

In the first line create the variable age which is an lvalue because you can assign the number 50 to it. In that case, 50 on the right side of the = is the rvalue so that means you can't assign to it. The next line demonstrates this again by assigning 100 to age, and since age is an lvalue this is allowed. The final line is an error though, because 88 is an rvalue just like 50 and 100, so you can't assign anything to it.

If you think about it, this make a lot of sense because what does 88 = age even mean? You want to change the number 88 to 100? Really? You want to break math? Just hey, for the rest of my program change all 88s to 100? It's simply nonsense, but there's a good chance you'll make this mistake until you gain experience, so now you know why it's an error. You can't assign to rvalues.

Literals

A literal is data you type into the code directly...literally...like you just put it right there. In our above examples the literals are the numbers 50, 100, and 88. Also the strings you've been typing like "Zed" are literals.

The Code

You now have enough information to type in all this code and get it working. Remember to do it a little bit at a time. If you catch yourself typing it all in before you run it then delete your work and do it again. I promise if you delete it and try again you'll do better and learn more than if you sit there banging your head on bad code for days.

View Source file ex06.cpp Only

#include <iostream>

using namespace std;

int main() {
  int age = 50;
  float height = 6.25f;
  string name = "Zed";
  char initial = 'A';
  auto last = "Shaw";
  long int big_negative = -123'456'789;
  unsigned long long lots_of_pi = 3'141'592'653'589'793'238;

  cout << "I am " << age << " years old.\n";
  cout << "I am also " << height << " length units tall.\n";
  cout << "My name is " << name << " " << initial << " " << last << endl;
  cout << "Big negative number " << big_negative << endl;
  cout << "Digits of Pi " << lots_of_pi << endl;

  return 0;
}

What You Should See

When you get it to work you should see this:

$ builddir/ex06 
I am 50 years old.
I am also 6.25 length units tall.
My name is Zed A Shaw
Big negative number -123456789
Digits of Pi 3141592653589793238

If you get different output then confirm you have the same code as mine.

Break It

There's lots of ways to break this code but here's a few suggestions:

  1. Try assigning a string to an int or other type.
  2. Try assigning integers to a string.
  3. Assign as many digits of Pi as you can to the height variable to see how much you can put in a float.
  4. Do the same with big_negative and lots_of_pi.
  5. Assign an integer to height to see what it does (for example, 6 instead of 6.25f).
  6. Try to assign to some of the rvalues in the code to see what erorrs you get.

Type Conversion Problems

One final way to break this code involves "implicit type conversions" and how to prevent them. Change the first line of code to this:

int age = {50.055f};

When you do this you should get an error that looks like this:

../ex06.cpp:6:21: error: narrowing conversion of '5.00550003e+1f' from 'float' to 'int' [-Wnarrowing]
    6 |   int age = {50.055f};
      |                     ^

Each compiler may complain differently, but generally this is saying that it won't "narrow" the type because you put {} around the 50.055f number.

If you remove the {} then the code will compile like normal, but your output will say age is 50 like before. This is because C++ has "helpful" implied conversions from some types, and in this case it's taking your 50.055f, seeing that age is an int and then converting it to an int for you. The {} tell the compiler to not let this happen if it can.

At this point we're getting into very complicated topics for just the 6th exercise of the course, so keep this as another way to "break code." You're actually "fixing" the code, but you should try adding {} around rvalues when you can to see if you get an error because of type conversions.

Further Study

  1. Convert the code to use auto instead of types. You can see an example of this on line 10.
  2. Read the documentation for Fundmental Types on cppreference.com and try to use as many as you can in this code.
  3. There is a way to find out the size of each type using the sizeof operator. Try to figure out how it works from just the name sizeof and print out the sizes of each type.
Previous Lesson Next Lesson

Register for Learn C++ the Hard Way

Register today for the course and get the all currently available videos and lessons, plus all future modules for no extra charge.