- Richard Feynman -
Difference between revisions of "Chapter:Variables and types"
(→Where to go next: next page text)
|Line 30:||Line 30:|
== Goal ==
== Goal ==
The goal of this presentation is to motivate and make the student familiar with the variable concept as well as discuss the way we humans use variables in
The goal of this presentation is to motivate and make the student familiar with the variable concept as well as discuss the way we humans use variables in life.
The student shall be able:
The student shall be able:
Revision as of 01:22, 2 October 2018
- 1 Meta information about this chapter
- 2 Chapter videos
- 2.1 Variables
- 2.2 Types
- 2.3 Declaration
- 2.4 Assignment
- 2.5 Type cast
- 2.6 Variables and types in Java
- 3 Questions and Answers
- 4 Links
Meta information about this chapter
Expand using link to the right to see the full content.
Variables is a basic building block when developing software in programming languages such as Java and C. In these languages it is important to have a good understanding of what a variable is and how it relates to memory - both as a way to understand how a computer program works and when learning about pointer or references later on.
We need to give the computer a bit of help on how to interpret the variable. We do this by using the type concept, which tells how big the variable is (how much space in memory is used) and how to use the memory for a variable.
It is not enough having variables and types. We, of course, need use them to store values and later on retrieve values. In this lecture we go through how to initialize and assign variables values.
Being able to manage conversion between type, automatic and explicit, are important for a developer. This lecture gives an overview and introduction to type cast.
We've been introduced to types. These have been general so in this chapter we will focus on Java and the primitive types found in Java.
This chapter will be using Java as a basis for the syntax. Students learning C will have to adapt to this naming convention during this chapter since we (the authors) can reuse the material between courses.
To give the student a basic understanding of variables, types and type cast. This understanding will be used as a basis for future learning.
Types are used in many languages, to different degrees. Being familiar with the type concept is important regardless of language and this presentation gives the student a foundation for future studies.
Declaring variables is done all over the source code of imperative programs (since the only way to create a variable is to declare it).
Without assignment there would not be much a program written in languages such as C, C++ and Java could do. The concept is relatively easy to understand and use but important enough for a separate lecture.
Primitive types are useful in Java and a good start in understanding types, variables and expressions.
The goal of this presentation is to motivate and make the student familiar with the variable concept as well as discuss the way we humans use variables in everyday life.
The student shall be able:
- motivate why variables are needed
- use variables
- use and reflect over the type concept
- convert/cast between different types
- understand the meaning of an assignment
- know that the = sign does NOT refer to mathematical equality
- understand how to use assignments with typed variables
- use assignment when writing programs
- be familiar with the type cast concept
- know the implications of switching between types
- be able to convert between types
- know that you can represent whole numbers in Java
- know that you can represent real numbers in Java
- be familiar with boolean, int and double and know that there exist other types
Instructions to the teacher
Variables are very important to understand. Without this understanding we have found it hard for the students to:
- to understand functions and their parameter/argument list
- pointers and reference variables
It's well worth the effort to stress that Java has basically two sorts of types: Primitive types and Reference types. While it is natural to start off with the simpler (to understand and use) primitive types, it should be mentioned already that there are also reference types. One way of understanding the difference at this point could be to think of reference types as indirect types, where the value is always an address or referral to some place in the memory where actual values etc are stored. Primitive types could be said to allow values to be stored more directly "in the variable" and that this is possible because the possible values are so primitive that no special care needs to be taken to prepare the variable's memory space. Stuff that is much more complex than primitive values, need to be stored in a special place, in a special way, and the values etc stored needs to be accessed more indirectly. Therefor reference variables is a way to have variables referring to some address where more complex structures may be found.
In the chapters about objects and classes this fundamental difference, between primitive types and reference types, should be re-iterated.
All videos in this chapter:
See below for individual links to the videos.
A memory (storage location) with a name. If we want to store the current temperature in a program, we can store the value in a place in memory and name (using a programming language) that piece of memory for instance
currentTemperature. Having descriptive names of memory locations greatly helps when writing programs. When we want to use the value of the current temperature again in our program, it is easy to remember and understand what
currentTemperature stands for.
Note: If you're programming in C you would name the variable
Presentation: Variable (pdf)
A type is a classification to identify different types of data, e.g. integers. Variables in the Java programming language have types, which means that we restrict what values are legal to store in variables of certain types. If we want to store and use integer values in our program, we can use a variable of type
int (which stands for integer values) for instance. We will then only be able to store integer values in that variable, which helps us avoid storing something else in the variable by mistake. It can be argued that types help us making fewer mistakes. This is sometimes called type safety.
Presentation: Type (pdf)
- No external links for Types
Creating a variable in programming languages is done using a declaration. The declaration specifies a name and, in Java and many other programming languages, also a type. An example can be
int currentTemperature; which declares a variable with the name
currentTemperature and of the type
int. In Java,
int is the name of the type for storing integer values in a certain range.
Presentation: Declaration (pdf)
Wikipedia links for the keen student:
With assignments we can set or modify the value of a variable. An example is
currentTemperature = 12; which assigns the value
12 to the variable
currentTemperature. The assignment is done using the
= sign. On the right side of the assignment we can find a literal (e g 12), an expression such as
12*3; or as we will see later on in the course a function/method. When we talk about the
= sign, we call it "assignment operator" because its use and meaning is very different from the same character when used in mathematics, for instance.
Note: a literal is a simple form of expression
Presentation: Assignment (pdf)
Wikipedia links for the keen student:
Some types can store similar values but in different ranges. For integer values, there are more than one type, but the valid values for the different types in the integer family (byte (or char in C), short, int, long) vary. A type for storing only a small set of the integers is
byte. It can only store integer values between -128 and +127. In return, such variables occupy less space of the memory compared to, for instance,
If we want to change the type of a variable (or expression) we can do this explicitly in code by using type cast (or typecast). If we want to assign a byte (char in C) variable,
lastTemperature, with the value of a variable of int type
currentTemperature and the change the type we can write:
lastTemperature = (byte) currentTemperature; When using explicit casts like this, we must be sure that the value will fit inside the target type, or there will be unwanted results. It is always possible to cast from a "smaller type" like
byte to a "larger type" like
int, because the valid values of a smaller interval always fit in the valid range of the larger type.
There are also rules for casting between more complex types than integers etc, but that's for a later chapter!
Presentation: Type-cast (pdf)
Variables and types in Java
Primitive datatypes are a basic datatype which form a building block in Java. They serve one purpose - store a simple value. It comes with a set of predefined set of operations which you can not extend or change.
It's important to know that a literal integer such as
25 has the type
int. If you need a literal value of type long, you must append "
L" or "
l" (a lower case L) to the literal value, e.g.
55L. For floating point literals, the default type is
double. If you need a literal floating point value of type
float, you must append
f to the value, e.g.
All types that are not one of the eight primitive types are called reference types. We'll talk more about references and reference types in chapters ahead.
Note: the presentation is unclear on when so called default values are used. Local variables never get default values.
Questions and Answers
Expand using link to the right to see the full content.
The section below is for Java students.
Q: “OK, so we use variables so that we can use a name instead of some technical hardware address. Are there any rules or recommendations for what kind of names we should use?”
A: We are glad that you asked! In Java, there are some rules and some recommendations. Let’s start at what names are legal to use (the compiler will tell you when you try to violate these rules, but it is good to know the rules anyway). The name you choose for a variable must start with a letter (underscore and $ are legal but nobody uses them as the start of a variable, and you shouldn’t either!). The rest of the variable name should be a combination of letters (numbers are valid too but not as the first letter of the variable name) and you may use underscore.
The recommendation is to start with a lower case letter and if the name consists of several words such as in “number of students” you should start each word with a capital letter to make the name more readable:
numberOfStudents. Names should be short, but meaningful. Prefer
ns etc. Think that your colleagues should immediately understand the meaning of a variable (and you too should understand it when you read the code after a year or two!).
There is a special form of variables for values that do not change over time, called constants. Constants usually have names with only upper case letters and words separated by underscore such as in
Q: “Are there some words that are forbidden to use as variable names, even though they obey the lexical rules?”
A: Sure there are! There are words that are reserved as part of the language itself (or future part). There is a whole list of such reserved words here:  We have actually seen some of them already but not talked about them in detail. The reserved words you already have seen include:
class, import, package, private, public and
void. The names of the primitive types are also reserved.
Q: “In Java, where are variables declared?”
A: It’s a little early in the course to give a full answer to that without listing places that we haven’t talked about yet. But so far, we have at least seen a few places where variable names (they are also sometimes called identifiers in some sources - identifiers are names we come up with of variables, classes, methods, arguments etc but we are focusing on variables in this chapter!) are declared. The first variable name we saw was actually the parameter to the main method. The main method had parentheses, remember? And in the parentheses it said
String args where
args is a variable name. That it is called exactly
args is just a convention by the way. The next place we saw a variable name being declared was in the main method. We had some
Greeter reference variables named
hi. So, apart from being parameters, variable names can be declared inside methods. Such variables are called “local variables”. And lastly, we have already seen one more place where a variable was declared. Do you remember where?
Q: “I don’t remember the third place where a variable was declared. Where was that?”
A: The third place we have seen so far, was in the
Greeter class declararation! We said that
Greeter objects had state - a way to remember and hold data at some point of their lifetime. The
Greeter objects had an internal thing called
greeting which was a variable holding information on what
String to use when asked to
greeting variable was declared inside the class definittion of the
Greeting class in
Greeting.java but not inside any method. Variables that every object of a class has their own copy of (to hold a part of their state) are called instance variables (because an object is also called “an instance of a class”).
Q: “What was the list of primitive types?”
A: The primitive types are the following eight types:
boolean, byte, short, char, int, long, float, and,
Q: “And then there were reference types. Is there a list of them too?”
A: No, there is no list. Reference types are types storing a kind of address to objects of some type. Object types are described in classes (and constructs similar to classes such as Enum and interface and arrays). Primitive types were pretty straightforward - they had a predefined set of legal values, which is why the Java designers didn’t think that they needed normal objects described in classes in order to implement these types. The values (in the legal range for each type) can be thought of as stored directly in the variable. But objects are much more complex creatures! They have state which can be a combination of many values (even references to other objects!) and behaviour (which is expressed in so called methods like
greet() ). For this reason, it is hard to implement a reference type that would hold all of this directly in the variable. Numbers and boolean values are much easier to store than complex constructs like objects. Also, objects need to be created before they exist and can be used. So there is a need to allow for reference variables to be declared before they refer to any particular object.
But the main reason we can’t give you a list of reference types, is that much of programming in Java deals with declaring and writing code for classes. When we make a class up, like the authors did when they created the
Greeter class, we come up with a name ourselves. So the list of reference types is not fixed! You are going to write your own classes etc later in the course, and each new class is a reference type.
I think it might be good to say something about the naming conventions for reference types here, if you don’t mind! Reference types like classes should always start with a capital letter! This is only a convention and standard, but it really helps when reading some source code. Names (identifiers as some call them) that start with a capital letter signals that these are exactly that, reference types! We directly see that a variable whose type starts with a capital letter (like String) must be a reference type. We don’t have to remember the eight primitive types in order to see this. The capital S in String gives away the information we need, this must be a reference type (such as a class)!
Q: “What is a declaration of a variable and when do I need it?”
A: The declaration of a variable is a very common instruction in Java programs (and programs in many other languages). Java is a language where types are very important and thoroughly checked by the compiler and runtime system. That means that types are important in Java and the reason it is so important to check the types, is that it helps us from doing mistakes (as we humans are so prone to do). If we have a variable that we plan to use to hold some numeric information and we by mistake store a string of text in it, the program will most likely not work the way we planned and hoped. So that kind of behaviour is forbidden in the Java programming language. So, in order for the compiler to help us check things like this, we need to declare what types our variables have - that is what legal values can later be stored in the variables. So when we declare that we want to use a new variable, we also say what type it has and then what name we want to use. If we want a variable capable of storing integral numbers (in the range that matches the legal values in the int primitive type) we could say like this:
After that declaration statement (statement is just a fancy word for instruction), we are free to use the variable
numberOfLines in our program in later statements. The compiler will now help us so we don’t try anything stupid as trying to store text in the variable. Only integers in the range for the int primitive types are now possible to store in
Inside methods, it is common to start the code by declaring all the variables that will be used in the method. When we declare a class, it is common to start with variables before constructors and methods (but this is also just a convention and not a rule).
Q: “What’s the difference between declaration and initialization?”
A: Declaration is about deciding type and name of a variable before it can be used. Initialization is all about giving the variable its first value. You can do the steps one-by-one like this:
int numberOfPages; numberOfPages = 0;
Or in one statement in one go like this:
int numberOfPages = 0;
You can choose the version that you find most convenient or intuitive. However, you cannot use a local variable (as a part of an expression, that is: using it as having a value) before it has been assigned a value. Instance variables are a different story, but we’ll talk about them in chapters to come!
Q: “Is it correct that assignment is used when we want to change the value a variable holds? If so, where does the value come from? It seems odd that we already know what values a variable will hold already when we write the program...”
A: It is correct that assignment is used to store a new value in a variable. The values we know beforehand are usually the initial values. Typically, as the program is running, new situations occur and we need to change the state of the program according to external events. Depending on the domain of the program we are writing, a number of sources can be found for the new values. On program might be used to order some product. In order to process the order, the user of the program must indicate in some way what product or products is to be ordered. Depending on the user’s actions (and how we respond to them) the information about the order will probably be stored in some way using variables and assignment. When the customer wants the order to be shipped, the customer might be presented with a form where the customer enters name, address, email, phone number etc. The program would typically use the values entered by the customer and store them in variables using assignment.
Another program might be used to get information about text files. It could, perhaps, count the number of characters, words and lines of any text file the user provides as an argument. Since the number of lines, for instance, is not known beforehand, the program would probably read the file and count how many lines it can find in the file. The count of lines would typically be stored in a variable (perhaps called
numberOfLines). The value of the variable would change by being increased by one for every new line the program finds while reading through the file. That could also be accomplished using assignment.
We think it is safe to say that most assignments are results of some operation rather than typed in literally when the program is written. But since we don’t know how to get information from users, or how to read files etch, we show examples using typed in values directly in the source code. Such values are sometimes referred to as “hard coded values”.
Q: “What is the relation between assignments and types?”
A: That is an important but a little tricky to answer question. We’ll try our best! In an assignment there are two parts. The part on the left (maybe we could think of it as the assignee - the variable which is being assigned a value) is always a variable. And all variables have, as we now know, a type. The other part, on the right-hand side, is some kind of value. The value could be typed in (hard coded) or it could be something more complicated like another variable. It could also be the result of some calculations like in
numberOfChildren = numberOfSons + numberOfDaughters;
There are more things that result in a value which would fit in on the right-hand side but we haven’t learned those yet. The important thing to understand here is that not only variables have a type. In Java, values too have a type! For instance, if you type in an integer such as 7 and use that as a value in, say, an assignment, Java will consider the 7 as being of primitive type
int. If you instead type in a real number, say 3.14, that value will be interpreted as being of primitive type
double. We have already seen that variables can be used as the right-hand side of an assignment, and we know that variables have a type. Now we have also told you that even hard coded values have a type.
The relation between assignments and types is that we have type security (we get help checking types) in Java. Before we can compile some code containing an assignment, our friend, the compiler, checks the types on both sides of the assignment operator. It starts by looking at the type of the variable to be assigned, and then checks the type of the value on the right-hand side (this sometimes is non-trivial - there are rules for determining the type of a calculation for instance). If the type of the variable to be assigned can hold values of the type of the value on the right-hand side, the compiler will not complain. If, however, the value on the right-hand side is not compatible with the type of the left-hand side variable, we get a compilation error with a message describing the problem.
Q: “What is compatibility then? When is a value of some type compatible with some other type?”
A: First of all, numeric types can only hold numeric values. We can never assign for instance a
boolean value to a numeric type in Java. But there are 6 numeric types in Java. Four integer types:
byte, short, int, long and two real number types:
float, double. Why the need for four integer types, you may ask? The answer has to do with the storage space for the various types. For small values, only a smaller space in the memory is required to represent all valid values. For an integer between -128 and +127, only eight bits are required (a bit is the smallest unit of memory, a space that only can hold a 0 or a 1). The standard integer type
int has 32 bits memory space (which allows for really small and really large integer values). Since both
int are for integer values, they are compatible at least in one direction. You are always safe to assign a byte value to an int variable and the compiler will always allow this.
Now, if we want to assign a variable of type
byte (with only 8 bits space) a value of type
int, there might be a problem. It is far from certain that an
int value will be inside the allowed range of a
int type values (32 bits) that are unknown at compile time (such as variables) i.e. not hard coded, such values won’t be allowed as the right-hand side of an assignment to a byte (8 bits) or a short (16 bits). If we insist of doing so, we must first convert the value to the corresponding left-hand type of the variable to be assigned.
Q: “How does one convert a type to another type?”
A: This is done using a type-cast. To convert an expression (a value, a calculation, a variable, etc) of type
int to type
byte, for instance, we write like this:
That is, we put the target type in parentheses before the source type. Now, we must be aware that this is a risky business! To store a value from a huge storage space of 32 bits inside a small space of only 8 bits, there is a huge risk that something will go wrong and information will be lost. The problem is similar to pouring the water from a large glass into a smaller glass. If the large glass only holds a small enough amount of water to fit inside the small glass, everything is fine. But if the large glass is holding much more water than the small glass, pouring all the water into the smaller glass will result in a loss of water (and probably a wet floor).
- Oracle tutorial on primitive types (Java)
- Java Language Specification on primitive types (Java)
- Variables in C Programming wikibook (C)
Where to go next
Next page has the exercises for this chapter: Variables and types - Exercises