Let’s talk about data types in programming languages. There are two categories: primitive types and reference types. In the article we will analyze each of the categories.
Primitive data types
Primitive data types are the basic data types of a programming language. Their key feature is that the data in them, unlike reference types, is located directly [“in the variable.”] in the area of computer memory in which the variable is located. Let’s list and describe the main primitive data types in programming.
- Boolean data type or just bool. Variables of this type can take only two values: true (or 1) or false (or 0). In various programming languages, boolean variables are declared using the bool or boolean keyword. The logical data type has the widest usage (as well as other types). For example, it appears in conditional branch statements (if) and loop statements (for, while, do-while).
- Integer data type. Usually declared with the keyword int or integer. Variables of this type can only take integer values. Often the int type occupies four bytes (232 = 4 294 967 296), so variables can take values from – 2 147 483 648 to 2 147 483 647 in the case where the integer type can be negative and positive. If you use an unsigned integer data type (unsigned int), then its value range is from 0 to 4 294 967 295. In the Java programming language, an integer type is always 4 bytes. In the C and C# languages, the estimated size is also 4 bytes, but in reality it all depends on the specific implementation of the language on the software platform.
This thesis applies not only to the int type. The size of each primitive data type in any implementation of the Java language is always strictly defined and the same. In C-like languages, the size may not always be the same.
- Integer type byte. Based on the name of the type, it occupies one byte in memory, that is, eight bits. 28 = 256 – this is the number of values it can contain. Speaking specifically, if the byte type is signed, then the range is from -128 to 127 (do not forget that there is also the number zero); when byte is unsigned, then from 0 to 255.
- Integer type short. In memory, 2 bytes = 16 bits are allocated for it (216 = 65536). The range of values for signed short is [-32768; 32767].
- Integer type long. A long integer type occupies 8 bytes in memory, that is, 64 bits. 264 = 1.8446744 × 1019. The range of values is very large: in the case of a signed type, this is [-9223372036854775808; 9223372036854775807]. In addition, the long modifier can be used in combination with other types (long is written before the type name, for example: long double), increasing the range of allowed values of the type in accordance with the specification of a particular programming language.
- Floating point number. This type is declared with the float keyword, and this type is also called the single-precision real type. Float is nothing more than a decimal fraction (usual to us in writing), but in computer memory it is represented as an exponential notation: it consists of a mantissa and an exponent. For example: 0.0506 = 506.0 ⋅ 10-4, where 506 is the mantissa and -4 is the exponent of ten. The size of the float data type is not clearly defined in the C specification.
- A double precision floating point number is a double type. This type is similar to the float type, their only difference is the size in memory and, accordingly, the range of accepted values. Of course, the double type is larger; but it all depends on the implementation of the language, strictly speaking: the type double must at least be no less than float.
- The character data type occupies one byte in memory if the ASCII encoding is used and two bytes if the Unicode encoding is set. This type is, in fact, an integer. The digit stored in a character type variable is the number of the character in the encoding table. Usually declared with the char keyword. You need to clearly understand that char is a number, and working with it as a number is very convenient and efficient in some cases.
The key feature of primitive data types is that they are passed by value. This means that when a variable is passed as an argument to a function (or method), it is copied there. Therefore, manipulations performed on a variable in the called function will not affect the value of the variable in the calling function in any way.
Note: The unsigned modifier applies to any integer type (including character), and long applies to almost any type except boolean.
Reference data types
The most important feature of reference data types is that they are not passed by value, but by reference. What does it mean?
Reference data types are not primitive and their size is not fixed and can be different, in addition, they are not stored [“in the variable.”] in the variable memory area, but in a completely different place in the computer memory. Reference types, for example, are arrays. In object-oriented programming languages, these are class instances, collections, etc.
When creating a new array:
int array = new int;
Or an instance of a class:
StreamWriter sw = new StreamWriter("output.txt");
The memory in the computer for the created object is allocated using the new operator (C++, C#, Java), and only a reference to the memory area (address) in which the created object is located is stored in the object variable (in our case, mass and sw).
When passing an object as an argument to a method (or function), only a copy of the address is passed to the method, not a copy of the object. Accordingly, all changes and manipulations made to the object in the called method will be reflected in the object in the calling method, because it is the same object.
This is the difference between primitive data types and reference data types.