Data Types
Values
A value is a discrete quantity of data. The members of a type are the values of that type. Computer languages vary in their implementation of primitive value types, but some examples would be null, undefined, true/false, and numeric values, like the following: 1, 3.1459, "Chuck", 'D', true.
Data Types
A data type or simply type is a classification of data which tells the compiler or interpreter how the programmer intends to use the data. Data types specify the type of data that you work with in a program. The data type defines the size of memory needed to store data and the kinds of operations that can be performed on the data. Most computer programming languages support various types of data, for example: real, integer, string, or boolean. A data type provides a set of values from which an expression (i.e. variable, function...) may take its values. The type defines the operations that can be done on the data, the meaning of the data, and the way values of that type can be stored. Data types are grouped into value types and reference types. Value data types store the value on the stack, whereas reference data types write the memory address on the stack which
points to where the data value begins in dynamic memory (the heap).
Modern-day programming languages have basic data types built-in to them; these are generally referred to as their primitive data types. Meaning, the programmer does not have to write the code that defines the data type, its allowed operations, etc. Usually a simple statement like:
int myVariable;
is all that is needed to declare an integer variable to the compiler or interpreter using any modern-day programming language.
Data Types By Programming Language
Click on the links below to view the specific data types for the designated programming language.
C++ Fundamental Types
C++ Fundamental Types (official documentation)
Data types in C++ are mainly divided into two types:
Primitive Data Types: These data types are built-in or predefined data types and can be used directly by the user to declare variables. example: int, char , float, bool etc. Primitive data types available in C++ are:
- Integer
- Character
- Boolean
- Floating Point
- Double Floating Point
- Valueless or Void
- Wide Character
Abstract or user defined data type: These data types are defined by user itself. Like, defining a class in C++ or a structure.
JavaScript Built-In Data Types
JavaScript Built-In Data Types (official documentation)
In JavaScript, a primitive (primitive value, primitive data type) is data that is not an object and has no methods. There are 6 primitive data types: string, number, boolean, null, undefined, symbol (new in ECMAScript 2015).
Most of the time, a primitive value is represented directly at the lowest level of the language implementation.
All primitives are immutable, i.e., they cannot be altered. It is important not to confuse a primitive itself with a variable assigned a primitive value. The variable may be reassigned a new value, but the existing value can not be changed in the ways that objects, arrays, and functions can be altered.
Java Data Types
Java Data Types (official documentation)
The Java programming language supports the following primitive data types.
- byte
- short
- int
- long
- float
- double
- boolean
- char
Notice that the Java primitive data tyes all begin with a lowecase character. This format indicates that the data type is a primitive type, meaning that it defines the size that will be reserved in memory for that data type, but it has no associated methods. Java also has data type objects which in addition to defining the size of the data type they also have associated methods which allow for manipulation of the data type. Java object data type names are the same as the primitive type names except that they begin with a capital letter, e.g. Byte, Int, Double, etc.
Python Built-In Types
Python Built-In Types (official documentation)
Python has four primitive data types:
- Integers
- Float
- Strings
- Boolean
C# Data Types
C# Data Types (official documentation)
C# provides several built-in data types by way of the .NET framework which can be used in your programs. You can also define new data types by defining your own data structure, such as a class
or a struct
.
In this lesson we focus on some of the most commonly used data types.
Figure 2: C# Data Types
Data Type |
Size |
Range Of Values |
byte |
1 byte |
0 to 255 |
char |
2 bytes |
U+0000 to U+ffff (Unicode characters) |
short |
2 bytes |
-32,768 to 32,767 |
int |
4 bytes |
-2,147,483,648 to 2,147,483,647 |
long |
8 bytes |
-9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
float |
4 bytes |
±1.5 X 10-45 to ±3.4 X 1038 |
double |
8 bytes |
±5.0e-324 to ±1.7e308 |
bool |
2 bytes |
True or False |
string |
- |
zero or more unicode characters |
All of the data types in the table above are value types except for string
, which is a reference type. The variables which are based on value types directly contain the value on the stack. Data types which are of type reference store a reference on the stack
which points to a memory address on the heap
where the value is actually stored. This will make more sense after you learn about arrays
, stacks
, heaps
, and other data structures later on in this course. For now, just remember that the string
type is a reference type and NOT a value type.
The MSDN Web site has a more comprehensive table showing the C# integral data types. which is a subset of the simple types. You might also want to review Types for a more comprehensive overview of C# types.
⇑ Table of Contents
Variables
Variables
Figure 1: Conceptual representation of a variable.
Variables are a way of creating a temporary area of storage in computer memory for storing data while a program is running. Variables are named storage locations that hold values. We can then retrieve the value stored in memory by using the name (a.k.a. identifier) we assign to it when declaring the variable. Think of a variable as a placeholder or a box of a specific size which we can write a name on to help us to recall the data programmatically at a later time. For instance let's declare a variable named age and then later we'll store a value in it.
To do this we must follow the C# required format, data-type name;
like this:
int age;
In the C# language we are required to include one of the C# data types provided by the .NET framework to let the compiler know what kind of value it should expect when we assign a value to it. The data type also determines what kinds of operations can be performed on it. In our example we used int which represents a 32-bit value which can only be a whole number, either positive or negative. By informing the compiler that our variable will be used to store a 32-bit integer value, the compiler now knows how many bits of space it needs to reserve in memory for holding the value when we assign data to it. You can determine a C# variable's data type like this variable_name.GetType();
Should we forget and try to assign text as a value for our variable or another numeric data type like a float data type, say 23.5, the compiler will let us know that this is not allowed while we are writing our program instead of us finding out the hard way, later on after the program has been compiled and being run by our customer. This saves a lot of time and
money.
For more information on the data types available for use in the C# language, read the section titled Data Types.
You can also initialize our variable (assign a value to it) at the same time we declare it by adding the C# assignment operator (=) followed by a value, like this:
Notice how asignment goes from right to left. Whether you are initializing a variable or just modifying its current value, assignments always go from right to left. Once our variable is declared or initialized, we can change the value of our variable at any time by simply writing an assignment statement using the name of the variable, the assignment operator, and a new value, like this:
//variable = expression
age = 45;
variable names must start with a letter or an underscore and can contain only letters, numbers, or underscores. A variable name can only be a maximum of 255 characters and must be unique within scope (more on local and global variables [scope] later).
Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type. The following two declarations of i are functionally equivalent:
var i = 10; //implicitly typed
int i = 10; //explicitly typed
Python is a dynamically typed language like JavaScript in that the interpreter infers the data type at run-time based on the value assigned to the variable. For instance, age = 20
would give the inference that age is an int. However, if we declare age like this age = "20"
then the inference is that age should be a string type. You can test this in Python using the type() function, like this: type(variable_name)
.
In JavaScript the keyword var
is used to dynamically declare a variable's data type, for example: var age = 20;
. When the var
keyword is not used in the declaration of a JavaScript variable, the variable is considered global in scope even if the declaration appears inside of a structure like a for
loop.
Creating Variables
⇑ Table of Contents
Data Types
Bool
Boolean data types stores one of two possible values, false or true (0 or 1 in binary). However, bools can be used to represent any diametrically opposed values like up or down, left or right, in or out, on or off, etc. The default value of a bool variable is false
public class BoolTest
{
static void Main()
{
bool b = true;
// WriteLine automatically converts the value of b to text.
Console.WriteLine(b);
int days = DateTime.Now.DayOfYear;
// Assign the result of a boolean expression to b.
b = (days % 2 == 0);
// Branch depending on whether b is true or false.
if (b)
{
Console.WriteLine("days is an even number");
}
else
{
Console.WriteLine("days is an odd number");
}
}
}
/* Output:
True
days is an (even/odd) number
*/
In this example, you enter a character from the keyboard and the program checks if the input character is a letter. If it is a letter, it checks if it is lowercase or uppercase. These checks are performed with the IsLetter, and IsLower, both of which return the bool type:
public class BoolKeyTest
{
static void Main()
{
Console.Write("Enter a character: ");
char c = (char)Console.Read();
if (Char.IsLetter(c))
{
if (Char.IsLower(c))
{
Console.WriteLine("The character is lowercase.");
}
else
{
Console.WriteLine("The character is uppercase.");
}
}
else
{
Console.WriteLine("Not an alphabetic character.");
}
}
}
/* Sample Output:
Enter a character: X
The character is uppercase.
Enter a character: x
The character is lowercase.
Enter a character: 2
The character is not an alphabetic character.
*/
⇑ Table of Contents
Byte
The Byte data type is used to represent an 8-bit unsigned integer. Byte is an immutable value type that represents unsigned integers with values that range from 0 (which is represented by the Byte.MinValue constant) to 255 (which is represented by the Byte.MaxValue constant). The .NET Framework also includes a signed 8-bit integer value type, SByte, which represents values that range from -128 to 127.
byte value1 = 64;
byte value2 = 255;
In this example two bytes named value1 and value2 are initialized with the integer values of 64 and 255 respectively.
To format a Byte value as an integral string with no leading zeros, you can call the parameterless ToString()
method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "X" format specifier, you can represent a Byte value as a hexadecimal string. The following example formats the elements in an array of Byte values in these three ways.
byte[] numbers = { 0, 16, 104, 213 };
foreach (byte number in numbers) {
// Display value using default formatting.
Console.Write("{0,-3} --> ", number.ToString());
// Display value with 3 digits and leading zeros.
Console.Write(number.ToString("D3") + " ");
// Display value with hexadecimal.
Console.Write(number.ToString("X2") + " ");
// Display value with four hexadecimal digits.
Console.WriteLine(number.ToString("X4"));
}
// The example displays the following output:
// 0 --> 000 00 0000
// 16 --> 016 10 0010
// 104 --> 104 68 0068
// 213 --> 213 D5 00D5
You can also format a Byte value as a binary, octal, decimal, or hexadecimal string by calling the ToString(Byte, Int32)
method and supplying the base as the method's second parameter. The following example calls this method to display the binary, octal, and hexadecimal representations of an array of byte values.
byte[] numbers ={ 0, 16, 104, 213 };
Console.WriteLine("{0} {1,8} {2,5} {3,5}",
"Value", "Binary", "Octal", "Hex");
foreach (byte number in numbers) {
Console.WriteLine("{0,5} {1,8} {2,5} {3,5}",
number, Convert.ToString(number, 2),
Convert.ToString(number, 8),
Convert.ToString(number, 16));
}
// The example displays the following output:
// Value Binary Octal Hex
// 0 0 0 0
// 16 10000 20 10
// 104 1101000 150 68
// 213 11010101 325 d5
⇑ Table of Contents
Int
Int or Int32 (specific to C#) is an immutable value type that represents signed integers with values that range from negative 2,147,483,648 (which is represented by the Int32.MinValue constant) through positive 2,147,483,647 (which is represented by the Int32.MaxValue constant. The .NET Framework also includes an unsigned 32-bit integer value type, UInt32, which represents values that range from 0 to 4,294,967,295.
You can declare an Int32 variable and assign it a literal integer value that is within the range of the Int32 data type. The following example declares two Int32 variables and assigns them values in this way.
int number1 = 64301;
int number2 = 25548612;
You can assign the value of an integer type whose range is a subset of the Int32 type. This is a widening conversion that does not require a cast operator in C#.
sbyte value1 = 124;
short value2 = 1618;
int number1 = value1;
int number2 = value2;
You can call a method of the Convert class to convert any supported type to an Int32 value. This is possible because Int32 supports the IConvertible interface. The following example illustrates the conversion of an array of Decimal values to Int32 values.
decimal[] values= { Decimal.MinValue, -1034.23m, -12m, 0m, 147m,
199.55m, 9214.16m, Decimal.MaxValue };
int result;
foreach (decimal value in values)
{
try {
result = Convert.ToInt32(value);
Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.",
value.GetType().Name, value,
result.GetType().Name, result);
}
catch (OverflowException) {
Console.WriteLine("{0} is outside the range of the Int32 type.",
value);
}
}
// The example displays the following output:
// -79228162514264337593543950335 is outside the range of the Int32 type.
// Converted the Decimal value '-1034.23' to the Int32 value -1034.
// Converted the Decimal value '-12' to the Int32 value -12.
// Converted the Decimal value '0' to the Int32 value 0.
// Converted the Decimal value '147' to the Int32 value 147.
// Converted the Decimal value '199.55' to the Int32 value 200.
// Converted the Decimal value '9214.16' to the Int32 value 9214.
// 79228162514264337593543950335 is outside the range of the Int32 type.
You can call the Parse or TryParse method to convert the string representation of an Int32 value to an Int32. The string can contain either decimal or hexadecimal digits. The following example illustrates the parse operation by using both a decimal and a hexadecimal string.
string string1 = "244681";
try {
int number1 = Int32.Parse(string1);
Console.WriteLine(number1);
}
catch (OverflowException) {
Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string1);
}
catch (FormatException) {
Console.WriteLine("The format of '{0}' is invalid.", string1);
}
string string2 = "F9A3C";
try {
int number2 = Int32.Parse(string2,
System.Globalization.NumberStyles.HexNumber);
Console.WriteLine(number2);
}
catch (OverflowException) {
Console.WriteLine("'{0}' is out of range of a 32-bit integer.", string2);
}
catch (FormatException) {
Console.WriteLine("The format of '{0}' is invalid.", string2);
}
// The example displays the following output:
// 244681
// 1022524
The Int32 type provides full support for standard and custom numeric format strings. (For more information, see Formatting Types, Standard Numeric Format Strings, and Custom Numeric Format Strings.)
To format an Int32 value as an integral string with no leading zeros, you can call the parameterless ToString() method. By using the "D" format specifier, you can also include a specified number of leading zeros in the string representation. By using the "N" format specifier, you can include group separators and specify the number of decimal digits to appear in the string representation of the number. By using the "X" format specifier, you can represent an Int32 value as a hexadecimal string. The following example formats the elements in an array of Int32 values in these four ways.
int[] numbers = { -1403, 0, 169, 1483104 };
foreach (int number in numbers) {
// Display value using default formatting.
Console.Write("{0,-8} --> ", number.ToString());
// Display value with 3 digits and leading zeros.
Console.Write("{0,11:D3}", number);
// Display value with 1 decimal digit.
Console.Write("{0,13:N1}", number);
// Display value as hexadecimal.
Console.Write("{0,12:X2}", number);
// Display value with eight hexadecimal digits.
Console.WriteLine("{0,14:X8}", number);
}
// The example displays the following output:
// -1403 --> -1403 -1,403.0 FFFFFA85 FFFFFA85
// 0 --> 000 0.0 00 00000000
// 169 --> 169 169.0 A9 000000A9
// 1483104 --> 1483104 1,483,104.0 16A160 0016A160
Float
The floating-point types are a subset of the simple types and can be initialized with literals. All floating-point types are also value types. All floating-point numeric types support arithmetic, comparison, and equality operators.
A floating-point expression can contain the following sets of values:
- Positive and negative zero
- Positive and negative infinity
- Not-a-Number value (NaN)
- The finite set of nonzero values
For more information about these values, see IEEE Standard for Binary Floating-Point Arithmetic, available on the IEEE website.
float data type uses four bytes to store numberic values which contain decimal places.
Real literals
The type of a real literal is determined by its suffix as follows:
- The literal without suffix or with the d or D suffix is of type double
- The literal with the f or F suffix is of type float
- The literal with the m or M suffix is of type decimal
The following code demonstrates an example of each:
double d = 3D;
d = 4d;
d = 3.934_001;
float f = 3_000.5F;
f = 5.4f;
decimal myMoney = 3_000.5m;
myMoney = 400.75M;
The preceding example also shows the use of _ as a digit separator, which is supported starting with C# 7.0. You can use the digit separator with all kinds of numeric literals.
You also can use scientific notation, that is, specify an exponent part of a real literal, as the following example shows:
double d = 0.42e2;
Console.WriteLine(d); // output 42;
float f = 134.45E-2f;
Console.WriteLine(f); // output: 1.3445
decimal m = 1.5E6m;
Console.WriteLine(m); // output: 1500000
⇑ Table of Contents
Doubles
The Double value type represents a double-precision 64-bit number with values ranging from negative 1.79769313486232e308 to positive 1.79769313486232e308, as well as positive or negative zero, PositiveInfinity, NegativeInfinity, and not a number (NaN). It is intended to represent values that are extremely large (such as distances between planets or galaxies) or extremely small (the molecular mass of a substance in kilograms) and that often are imprecise (such as the distance from earth to another solar system), The Double type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.
⇑ Table of Contents
Char
The char data type
var chars = new char[4];
chars[0] = 'X'; // Character literal
chars[1] = '\x0058'; // Hexadecimal
chars[2] = (char)88; // Cast from integral type
chars[3] = '\u0058'; // Unicode
Console.Write(string.Join(" ", chars));
// Output: X X X X
Escaping and Casting Values
As you can see above the literal values being assigned to chars[1] and chars[3] use a special programming technique known as an escape sequence. Escape sequences can be used in many ways with chars and strings. In order to escape a character you type to type a backslash character before the character you want escaped. In the case of chars[1] the value being escaped is a hexadecimal value - hex is indicated using a lower-case 'x'. In the chars[3] example the value is a unicode value as designated by prefixing the value with a 'u'.
The literal value being assigned to chars[2] uses a programming technique known as casting. Casting, placing a data type name in parenthesis before the literal value to be assigned, converts the value to the data type identified in the parenthesis.
Here are a few more char examples:
// An ordinary character
char character = 'a';
Console.WriteLine(character);
// Unicode character code in a hexadecimal format
character = '\u003A';
Console.WriteLine(character);
// Assigning the single quotation character (escaped as \')
character = '\'';
Console.WriteLine(character);
// Assigning the backslash character (escaped as \\)
character = '\\';
Console.WriteLine(character);
// Console output: // a // : // ' // \
⇑ Table of Contents
Strings
In computer programming, a string data type is a data type which contains an array of char (character) data types.
Using Strings In JavaScript
Watch this video to learn about strings and string manipulation.
String Properties
The string type in C# has two properties:
- Chars[index]
- Gets the Char object at a specified position in the current String object.
- Length
- The number of characters in the current string.
String Methods
The string type in C# has numerous methods: Clone, Compare, CompareOrdinal, CompareTo, Concat, Contains, Copy, CopyTo, Create, EndsWith, EnumerateRunes, Equals, Format, GetEnumerator, GetHashCode, GetTypeCode, IndexOf, IdexOfAny, Insert, Intern, IsInterned, IsNormalized, IsNull Or Empty, IsNullOrWhiteSpace, Join, LastIndexOf, LastIndexOfAny, Normalize, PadLeft, PadRight, Remove, Replace, Split, StartsWith, Substring, ThCharArray, ToLower, ToLowerInvariant, ToString, ToUpper, ToUpperInvariant, Trim, TrimEnd, and TrimStart (as of .NET Framework 4.8).
Code Examples Using Strings
⇑ Table of Contents
Operators
Operators
You have already seen a couple of C# operators in action (=
and new
). In this section we will discuss C# operators in more depth.
Operators are symbols that specify which operations (math, indexing, function call, etc.) to perform on the operands in an expression. Operands can be variables, constants, literals, etc. Operators can be organized by function or by number of operands it operates on. If we organize operators by function, each operator would fall into one of three categories, 1) arithmetic, 2) boolean, or 3) relational. Examples of arithmetic operators include: +, -, *, /, and %. If we organize operators by the number of operands they operate on then the groupings would be: 1) unary operators, 2) binary operators, and 3) ternary operators.
Operators can be organized depending on the number of operands involved, like this:
Unary operators: The unary operators work with only one operand. Examples include ++x (prefix increment), x++ (postfix increment), or new.
Binary operators: Binary operators take two operands. Examples include x + y or x > y
Ternary operators: Ternary operators take three operands. There is just one ternary operator in C# ?:. Pseudo code example:
condition ? expression_if_true : expression_if_false;
Operators can also be organized by how they are used, like this:
Arithmetic operators can be used to create expressions like:
x = 1 + 1;
Conditional operators can be used to create expressions like:
if (x < 2)
Logical operators can be used to create expressions like:
if (x<2 && y == 3)
Often expressions involve more than one operator. In this case the compiler needs to determine which operator takes precedence over the other(s). Figure 3 lists the C# operators in order of precedence (pretty much the same in all computer programming languages). The higher an operator is located in the table, the higher the precedence. Operators with higher precedence are evaluated before operators with lower precedence. Operators that appear in the same row have equal precedence.
Figure 3: C# Operators
Category |
Operators |
Primary |
x.y f(x) a[x] x++ x-- new
typeof checked unchecked |
Unary |
+ - ! ~ ++x --x (T)x |
Multiplicative |
* / % |
Additive |
+ - |
Shift |
<< >> |
Relational and type testing |
<> <= >= is as |
Equality |
== != === !== |
Logical AND |
& |
Logical XOR |
^ |
Logical OR |
| |
Conditional AND |
&& |
Conditional OR |
|| |
Conditional ternary |
?: |
Assignment |
= *= /= %= += -= <<= >>= ^= |= |
The unary increment operator (++) adds 1 to the value of the an identifier (variable). Similarly, the decrement (--) operator subtracts 1 from the value of the identifier. The unary increment and decrement operator can be used as prefixes or suffixes. For example:
int x = 10;
x++; //value of x is now 11
++x; //value of x is now 12
However, when used as part of an assignment the results can be unexpected. When the unary increment and decrement operators are used as prefixes (++x), the current value of the identifier is returned after (post) the increment or decrement operation. When used as a suffix (x++), the value of the identifier is returned before (pre) the increment decrement operation is complete. To better understand how this works let's look at another example:
int x = 10;
int y = x++ //value of y is 10 (assigned pre-increment)
int z = ++x //value of z is 12 (assigned post-increment)
In this example, because y is assigned the value of x pre-increment y's value is 10. However x is increment after the assignment to y so x's value is now 11. Then, z is assigned the value of x post-increment so both x and y now have the value of 12. Fun stuff, eh?
If this example boggles you brain, I encourage you to copy this console application code into Visual Studio and try it out for yourself:
using System;
namespace IncrementDecrementOperators
{
class Program
{
static void Main(string[] args)
{
int x = 10;
int y = x++; //value of x is now 11
Console.WriteLine("x = " + x + ", y = " + y);
int z = ++x; //value of x is now 12
Console.WriteLine("x = " + x + ", z = " + z);
}
}
}
Assignment, Comparison, and Logical Operators
Addition Vs. Concatenation
⇑ Table of Contents