fbpx

Understanding types is super critical to being able to program. Without this knowledge it would be like trying to go through life where everything you see and feel is unknown to you.

If somebody points to a random spot in a computer’s memory and asks “What’s that? Do we need it anymore?” You can’t just pick it up and look at it. It’s just some binary bits. Some values. You don’t even know how many there are or if you’re looking at the beginning, middle, or end. You might even be looking at a spot in memory that has nothing. You can’t tell because even nothing has no meaning.

What are these types that are available to you? It depends on the language. Here are 11 common types with a short description for each.

  • Integer types represent whole numbers including zero. There will usually be several sizes of this basic type available that will fit in 8, 16, 32, or 64 bytes. Some common names are short, int, and long and the specific sizes are not always fully specified by a language. There are also signed and unsigned versions of the integer types that determine if negative values are allowed.
  • Boolean types allow you to keep track of true and false values.
  • Floating point types give you the ability to approximate decimal numbers including fractional values.
  • Character types are very similar to the integer types because they only need whole numbers. The major difference is that these types use codes that map to character values. The codes are standardized and agreed on although there are multiple standards and it’s not always obvious which standard is being used.
  • Void is a special type that means there is no type.
  • String types are really just a collection of characters. There are enough special rules especially with various cultures and regions that will make you glad to have strings as their own type.
  • Pointer types need another type to be complete. This other type could even be another pointer.
  • Reference types act a lot like pointers but don’t look like them.
  • Array types also need another type to be complete and define a collection of the other type.
  • Custom types can be anything you want and are defined by including other built-in and custom types.
  • Enumeration types are custom types that allow you to give meaningful names to values.

Listen to the full episode or you can also read the full transcript below.

Transcript

Imagine picking up something and not knowing what it is. Go ahead and do this exercise right now while I’m talking. You reach up to a top shelf and feel something and take it down. You’ve never seen it before. Is it yours? Is there a label on it?

You can start making guesses but how is this possible? What clues do you have? You don’t know what it is but you can still look at it and feel it. Let’s get specific. You know it’s not very heavy and looks to be made out of plastic. You can see it’s a light grey color. If it belongs to something else, then it probably resembles that other thing. So you start thinking about all the things you might have put on that shelf that had some grey plastic pieces and you remember an old vacuum cleaner that you sold last summer in a garage sale. Huh, guess you don’t need this anymore. So you throw it away.

Now imagine a similar scenario but this time you get a call form work and the person wants to know if this “thing” from the top shelf is still needed or if it can be thrown out. You ask the obvious question, “What thing?”

“I don’t know what it is,” the other person says. “I just called to ask you if I can throw it out.”

“Well, can you describe it?” you ask.

“John’s actually the one who found it. Not me. I forgot to ask him what it looked like before he left. He took it with him so I don’t have it. I told him that I’d call him back with your answer though.”

“Okay, do you know exactly where it was found?” you ask.

“Oh yeah, it was on the third shelf of row nine. In the bin labeled “X”. John was very specific about that for some reason. He seemed to think it was important.”

Let’s stop here for a moment and introduce some important backstory. You’re an absolute genius at organization and always make sure that everything is kept in perfect order. You put stuff in bins with labels and carefully stack your boxes and make sure that everybody else follows your rules. You also keep a journal with you at all times that you can use to find out where you put something.

You flip through your journal and find an old entry for the bin X on the third shelf of row 9. It’s your vacuum cleaner attachment and you don’t need it anymore.

So what does all this have to do with programming?

If somebody points to a random spot in a computer’s memory and asks “What’s that? Do we need it anymore?” You can’t just pick it up and look at it. It’s just some binary bits. Some values. You don’t even know how many there are or if you’re looking at the beginning, middle, or end. You might even be looking at a spot in memory that has nothing. You can’t tell because even nothing has no meaning.

But if you’ve kept accurate records along the way, then just knowing the memory location or memory address will be enough for you to determine what it is. Keeping track of all this is the job of your compiler. It can help you.

Going back to a previous example, let’s say you read the value 3 from memory and know that means the number of cups of flour that you have already added to your cake.

There are two very important aspects of this that you need to be aware of. The first is what kind of thing are we expecting in memory. Is it a representation of a character? It it the first digit in pi? Or is it an integer value. In this case, it’s an integer value. But we had to know the type in order to make any sense of the memory and be able to read the value 3.

The second is what purpose does this integer value serve. In this case, we know it’s the count of cups of flour added to the mix.

What you use a particular value for is up to you.

What kind of value is it though…

That’s the topic of this episode.

Understanding types is super critical to being able to program. Without this knowledge it would be like trying to go through life where everything you see and feel is unknown to you. Just think about that for a minute. You see a new chair design that looks nothing like any other chair and know right away that you can sit on it if you want. But how do you know this? Because you know that there is a concept of a chair and what it does. You see a wall and know right away to walk around it. Or you see a puddle and know exactly how to jump in it. Now, do you think you would be able to accomplish anything without this understanding? It’s the same with programming. Types allow you to put structure around the bits in memory and give them meaning. Without this meaning, everything in a computer is just a bunch of zeros and ones.

Some languages don’t care about types at all in the sense that memory can represent whatever you feel like. At least that’s what it appears like. Behind the scenes, these languages still have to have some idea of what types are in memory or they just wouldn’t be able to function. In these languages, you can save an integer value and then later reinterpret it as something else. The language still knows it was an integer value and just does the conversion for you. This might be on purpose or an accidental bug. These languages might seem easier to learn at first but you run into problems when your application gets bigger. You end up facing the problem described earlier about trying to figure out what something is. If you don’t even know what it is, it’s a lot harder to figure out how to use it.

Other languages like C++ and C# take a much stricter approach to types. This leads to a language that looks a bit more complicated but you’ll quickly learn to appreciate the benefit of needing to specify exactly the type of everything.

What are these types that are available to you? It depends on the language really. Some languages support more built-in types than others. Some languages may only support types that the language already knows about. And some languages may allow you to define your own types. Here are 11 common types with a short description for each.

  1. Integer types represent whole numbers including zero. There will usually be several sizes of this basic type available that will fit in 8, 16, 32, or 64 bits. Some common names are short, int, and long and the specific sizes are not always fully specified by a language. There are also signed and unsigned versions of the integer types that determine if negative values are allowed.
  2. Boolean types allow you to keep track of true and false values.
  3. Floating point types give you the ability to approximate decimal numbers including fractional values.
  4. Character types are very similar to the integer types because they only need whole numbers. The major difference is that these types use codes that map to character values. The codes are standardized and agreed on although there are multiple standards and it’s not always obvious which standard is being used.
  5. Void is a special type that means there is no type.
  6. String types are really just a collection of characters but there are enough special rules especially with various cultures and regions that will make you glad to have strings as their own type.
  7. Pointer types need another type to be complete. This other type could even be another pointer.
  8. Reference types act a lot like pointers but don’t look like them.
  9. Array types also need another type to be complete and define a collection of the other type.
  10. Custom types can be anything you want and are defined by including other built-in and custom types.
  11. Enumeration types are custom types that allow you to give meaningful names to values.

Let’s talk for a moment about the return type of methods.

When you’re wrapping up a bunch of instructions into a method that has a name that you can call upon when needed, you need to specify what type of value the method will return and what types of values the method requires as input.

There will be another episode all about methods so I’m not going to spend too much time today talking about them.

A return value allows a method to return some answer to you. Let’s just look at the type of the return value for now.

You might have a method that knows all about how to calculate how many cups of flour you need. You just need to specify how many cakes you want to make, and it will return a number to you.

You might start by thinking the return type of this method should be an integer or an int as it’s normally called. This type represents a whole number and includes negative numbers as well as zero. While zero could theoretically make sense sometimes, negative numbers in this case are just nonsense. What are you going to do if this method says you should have negative one cups of flour? Maybe it would be better to specify this method to return an unsigned int. That way it will only be able to return zero or positive whole numbers. But what to do if you need 3 1/2 cups of flour? That means you would probably want the method to return a float instead of an unsigned int in order to get fractions of cups. But then you’re back to the same problem of negative values because there’s no concept of an unsigned float. This simple example might actually need a more complicated solution.

All methods need a return value type to be specified but what do you do when a method really doesn’t need to return anything? Some methods are more like, “Go do this,” or “Go do that,” and have no need to return anything. How do you declare a method that has no return type? Do you just leave it out of your source code? No. The language is probably expecting it. Both C++ and C# require a return type for all methods except in very special cases that we’ll discuss later. When you need to declare a method that has no return type, then declare that method to return void.

Some languages like C++ support pointers. We’ll discuss pointers in the next episode. As far as void goes though, C++ also allows you to use void to specify that you either don’t know or don’t care what type the pointer points to. This is called a void pointer. We know exactly what address is being pointed to but we just don’t know what exists at that location. I recommend that you AVOID this practice. Just think back to your frustration with the phone caller who thought it was okay to ask if you still needed something but had no idea what it was. Don’t be like that phone caller. It’s much better to know your types.

Why would C++ even allow void pointers? There are two reasons and neither of them really apply anymore. We’ll get into more of the history of C++ in a future episode but for now just realize that C++ inherits a lot of functionality from C. Backwards compatibility then is the first reason. The second reason has to do with something called generic programming. That’s also a really good topic for a future episode but I’ll summarize a bit here.

Let’s say you’re writing some code to work with integers and you realize that you now need almost the same code to work with characters. In fact, the only difference between these is the type. One needs ints and the other needs chars. And then you realize that you need the same code yet again for a custom type. Instead of writing the same code 3 times, what programmers used to do was change the code to work with pointers to the types instead. Then by making the pointers into void pointers, it was all the same. This puts extra burden on anybody trying to use this code because the compiler can no longer help keep the types organized. Generic programming allows you to write your source code in a generic manner as if you don’t know what the types are. But you do this in a special way that allows you to enlist the compiler’s help to keep your types straight at the point when you actually need to use your generic code. So the moment you know that you’ll be working with ints, instead of keeping it secret from your compiler, you can now tell the compiler to go grab that generic code and adapt it to work with ints.

Some languages refer to this as generic programming and some call it templates. It’s really the same thing. At this point just know that it helps you to stay away from void pointers.