Name :
Juhani Septiadi Tambun
NIM :
1701369632
Class :
01 PWT
Subject :
Concepts of Programming Languages
Summary about Data Types
The data type of a programming element refers to
what kind of data it can hold and how it stores that data. Data types apply to
all values that can be stored in computer memory or participate in the
evaluation of an expression. Every variable, literal, constant, enumeration,
property, procedure parameter, procedure argument, and procedure return value
has a data type.
Primitive Data Types
Almost all programming languages provide a set of primitive
data types. A primitive type is predefined by
the language and is named by a reserved keyword. Primitive values do not share
state with other primitive values. The eight primitive data types supported by
the Java programming language are:
byte:
The
byte
data type is an 8-bit signed
two's complement integer. It has a minimum value of -128 and a maximum value of
127 (inclusive). The byte
data type can be useful for saving
memory in large arrays, where the
memory savings actually matters. They can also be used in place of int
where their limits help to
clarify your code; the fact that a variable's range is limited can serve as a
form of documentation.
short:
The
short
data type is a 16-bit signed
two's complement integer. It has a minimum value of -32,768 and a maximum value
of 32,767 (inclusive). As with byte
,
the same guidelines apply: you can use a short
to save memory in large arrays,
in situations where the memory savings actually matters.
int:
By default, the
int
data type is a 32-bit signed
two's complement integer, which has a minimum value of -231 and a maximum value of 231-1.
In Java SE 8 and later, you can use the int
data type to represent an
unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of
232-1. Use the Integer class to use int
data
type as an unsigned integer. See the section The Number Classes for more
information. Static methods like compareUnsigned
, divideUnsigned
etc have been added to the integer class to support the
arithmetic operations for unsigned integers.
long:
The
long
data type is a 64-bit two's
complement integer. The signed long has a minimum value of -263 and a maximum value of 263-1.
In Java SE 8 and later, you can use the long
data type to represent an
unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1.
The unsigned long has a minimum value of 0 and maximum value of 264-1.
Use this data type when you need a range of values wider than those provided by int
.
The long class also contains
methods likecompareUnsigned
, divideUnsigned
etc to support arithmetic
operations for unsigned long.
float:
The
float
data type is a single-precision
32-bit IEEE 754 floating point. Its range of values is beyond the scope of this
discussion, but is specified in the floating-point
types, formats, and values section of the Java Language Specification. As
with the recommendations for byte
and short
,
use a float
(instead of double
)
if you need to save memory in large arrays of floating point numbers. This data
type should never be used for precise values, such as currency. For that, you
will need to use thejava.math.BigDecimal class
instead. Number and Strings covers BigDecimal
and other useful classes provided
by the Java platform.
double:
The
double
data type is a double-precision
64-bit IEEE 754 floating point. Its range of values is beyond the scope of this
discussion, but is specified in the Floating-Point Types, Formats, and Values section of the Java Language
Specification. For decimal values, this data type is generally the default
choice. As mentioned above, this data type should never be used for precise
values, such as currency.
boolean:
The
boolean
data type has only two possible
values: true
and false
.
Use this data type for simple flags that track true/false conditions. This data
type represents one bit of information, but its "size" isn't
something that's precisely defined.
char:
The
char
data type is a single 16-bit
Unicode character. It has a minimum value of '\u0000'
(or 0) and a maximum value of '\uffff'
(or 65,535 inclusive).
Array
An array is an aggregate of homogeneous data
elements in which an individual element is identified by its position in the
aggregate, relative to the first element. An array is a series of elements of the same type placed in
contiguous memory locations that can be individually referenced by adding an
index to a unique identifier.
That means that, for example, we can store 5 values of type int in an array without having to declare 5 different variables, each one with a different identifier. Instead of that, using an array we can store 5 different values of the same type, int for example, with a unique identifier.
That means that, for example, we can store 5 values of type int in an array without having to declare 5 different variables, each one with a different identifier. Instead of that, using an array we can store 5 different values of the same type, int for example, with a unique identifier.
Initializing Arrays
When declaring a regular array of local scope
(within a function, for example), if we do not specify otherwise, its elements
will not be initialized to any value by default, so their content will be
undetermined until we store some value in them. The elements of global and
static arrays, on the other hand, are automatically initialized with their
default values, which for all fundamental types this means they are filled with
zeros.
In both cases, local and global, when we declare an array, we have the possibility to assign initial values to each one of its elements by enclosing the values in braces { }.
In both cases, local and global, when we declare an array, we have the possibility to assign initial values to each one of its elements by enclosing the values in braces { }.
Arrays
Operations
•
APL
provides the most powerful array processing operations for vectors and matrixes
as well as unary operators (for example, to reverse column elements)
•
Ada
allows array assignment but also catenation
•
Python’s
array assignments, but they are only reference changes. Python also supports
array catenation and element membership operations
•
Ruby
also provides array catenation
•
Fortran
provides elemental operations because they are between pairs of array
elements
–
For
example, + operator between two arrays results in an array of the sums of the
element pairs of the two arrays
Slices
A slice is some substructure of an array;
nothing more than a referencing mechanism. Slices are only useful in languages that have
array operations
Implementation of Arrays :
Access function maps subscript expressions to
an address in the array
Access function for single-dimensioned arrays:
address(list[k])
= address (list[lower_bound])
+
((k-lower_bound) * element_size)
Record Types
In computer
science, records (also
called tuples, structs,
or compound data) are among the
simplest data structures. A
record is a value that contains other values, typically in fixed number and
sequence and typically indexed by names. The elements of records are usually
called fields or members.
A record type is a data
type that describes such values and variables. Most modern
computer languages allow the programmer to define new record types. The
definition includes specifying the data type of each field and an identifier (name or label) by which it can be
accessed. In type theory, product types (with
no field names) are generally preferred due to their simplicity, but proper
record types are studied in languages such as System F-sub. Since
type-theoretical records may contain first-class
function-typed fields in addition to data, they can express many
features of object-oriented programming.
Records can exist in any
storage medium, including main memory and mass storage devices such as magnetic tapes or hard disks. Records are a fundamental
component of most data structures, especially linked
data structures. Many computer files
are organized as arrays of logical
records, often grouped into larger physical records or blocks for efficiency.
The parameters of a function or procedure can often be viewed as the fields of a
record variable; and the arguments passed to that function can be viewed as a
record value that gets assigned to that variable at the time of the call. Also,
in the call stack that is often used to implement
procedure calls, each entry is an activation
record or call frame, containing the
procedure parameters and local variables, the return address, and other
internal fields.
An object in object-oriented language is essentially a record that
contains procedures specialized to handle that record; and object data types
(often called object classes) are an elaboration of record types. Indeed, in
most object-oriented languages, records are just special cases of objects.
A record can be viewed as
the computer analog of a mathematical tuple. In the same vein, a record type
can be viewed as the computer language analog of the Cartesian product of two or moremathematical sets, or
the implementation of an abstract product
type in a specific language.
Operations
A programming language that supports record types usually provides
some or all of the following operations:
·
Declaration of a new record type, including the position, type,
and (possibly) name of each field;
·
Declaration of variables and values as having a given record type;
·
Construction of a record value from given field values and
(sometimes) with given field names;
·
Selection of a field of a record with an explicit name;
·
Assignment of a record value to a record variable;
·
Comparison of two records for equality;
·
Computation of a standard hash
value for the record.
Some languages may provide facilities that enumerate all fields of
a record, or at least the fields that are references. This facility is needed
to implement certain services such as debuggers,garbage collectors,
and serialization. It requires some degree of type polymorphism.
The selection of a field from a record value yields a value.
Assignment and comparison
Most languages allow assignment between records that have exactly
the same record type (including same field types and names, in the same order).
Depending on the language, however, two record data types defined separately
may be regarded as distinct types even if they have exactly the same fields.
Some languages may also allow assignment between records whose
fields have different names, matching each field value with the corresponding
field variable by their positions within the record; so that, for example, a complex number with fields called
real
and imag
can be assigned to a 2D point record variable with fields X
and Y
. In this
alternative, the two operands are still required to have the same sequence of
field types. Some languages may also require that corresponding types have the
same size and encoding as well, so that the whole record can be assigned as an
uninterpreted bit string. Other
languages may be more flexible in this regard, and require only that each value
field can be legally assigned to the corresponding variable field; so that, for
example, a short integer field can be assigned to a long integer field, or vice-versa.
Other languages (such as COBOL)
may match fields and values by their names, rather than positions.
These same possibilities apply to the comparison of two record
values for equality. Some languages may also allow order comparisons ('<'and
'>'), using the lexicographic
order based on the comparison of individual fields.
Union
Types
In computer
science, a union is a value that may have any of several
representations or formats; or it is a data
structure that consists of a variable which may hold such a value.
Someprogramming languages support
special data types, called union types, to describe such
values and variables. In other words, a union type definition will specify
which of a number of permitted primitive types may be stored in its instances,
e.g., "float or long integer". Contrast with a record (or structure), which could be defined
to contain a float and an integer; in a union, there is only
one value at any given time.
A union can be pictured as a chunk of memory that is used to
store variables of different data types. Once a new value is assigned to a
field, the existing data is overwritten with the new data. The memory area
storing the value has no intrinsic type (other than just bytes or words of memory), but the value can be
treated as one of several abstract data types, having the type of the value
that was last written to the memory area.
In type
theory, a union has a sum type.
Depending on the language and type, a union value may be
used in some operations, such as assignment and comparison for equality, without
knowing its specific type. Other operations may require that knowledge, either
by some external information, or by the use of a tagged union.
Untagged unions
Because of the limitations of their use, untagged unions are
generally only provided in untyped languages or in a type-unsafe way (as in C). They have the advantage over simple tagged unions of not
requiring space to store a data type tag.
The name "union" stems from the type's formal
definition. If a type is considered as the set of all values that that type can take
on, a union type is simply the mathematical union of its constituting types, since it
can take on any value any of its fields can. Also, because a mathematical union
discards duplicates, if more than one field of the union can take on a single
common value, it is impossible to tell from the value alone which field was
last written.
However, one useful programming function of unions is to map
smaller data elements to larger ones for easier manipulation. A data structure
consisting, for example, of 4 bytes and a 32-bit integer, can form a union with
an unsigned 64-bit integer, and thus be more readily accessed for purposes of
comparison etc.
Like a structure, all of the members of a union are by
default public. The keywords
private
, public
, and protected
may be used inside a
structure or a union in exactly the same way they are used inside a class for
defining private, public, and protected member access.
Unions in various programming languages
C/C++
In C and C++,
untagged unions are expressed nearly exactly like structures (structs),
except that each data member begins at the same location in memory. The data
members, as in structures, need not be primitive values, and in fact may be
structures or even other unions. However, C++ does not allow for a data member
to be any type that has a full fledged constructor/destructor and/or copy
constructor, or a non-trivial copy assignment operator. For example, it is
impossible to have the standard C++ string as a member of a union. (C++11 lifts some of these restrictions.)
The primary usefulness of a union is to conserve space,
since it provides a way of letting many different types be stored in the same
space. Unions also provide crude polymorphism.
However, there is no checking of types, so it is up to the programmer to be
sure that the proper fields are accessed in different contexts. The relevant
field of a union variable is typically determined by the state of other variables,
possibly in an enclosing struct.
One common C programming idiom uses unions to perform what
C++ calls a reinterpret_cast,
by assigning to one field of a union and reading from another, as is done in
code which depends on the raw representation of the values. A practical example
is the method of computing square
roots using the IEEE representation. This is not, however, a safe use of unions
in general.
Structure and union specifiers have the same form. [ . . . ]
The size of a union is sufficient to contain the largest of its members. The
value of at most one of the members can be stored in a union object at any time. A pointer to a union
object, suitably converted, points to each of its members (or if a member is a
bit-field, then to the unit in which it resides), and vice versa.
—ANSI/ISO 9899:1990 (the ANSI C standard) Section 6.5.2.1
Anonymous union
Unions can also be anonymous; that is, they do not have a
name. Their data members are accessed directly. In addition to this, they have
certain other restrictions like:
·
They must also be declared as static if declared in file scope. If
declared in local scope, they must be static or automatic.
·
They can have only public members; private and protected members
in anonymous unions generate errors.
·
They cannot have function members.
Pointer
and Reference Types
- Pointer type values consists of memory
addresses
- Pointers have been designed for the following
uses:
Allocate memory for variable and return a
pointer to that memory.
Dereference a pointer to obtain the value of
variable it points to.
Deallocate the memory of variable pointed to by a pointer.
Pointer arithmetic.
- Pointers improve writability
Doing dynamic data structures (linked lists,
trees) in a language with no pointers (FORTRAN 77) must be emulated with
arrays, which is very cumbersome.
The variable that stores the reference to another variable
is what we call a pointer.
& is the reference operator
and can be read as "address of"
* is the dereference operator and can be read
as "value pointed by"
void pointers
A special type of pointer. In C++, void pointers are
pointers that point to a value that has no
type.
This allows void pointers to
point to any data type, from an integer value or a float to a string
of characters.
Limitation: the data pointed by them cannot be directly
dereferenced, and for that reason we
will always have to change the type of the void pointer to
some other pointer type that points to
a concrete data type before dereferencing it.
This is done by performing type-castings.
Problems with Pointers
- PL/I was the first programming language to
provide a pointer type.
- Pointers come with several problems (PL/I, C,
C++, etc.)
(1) Dangling pointers (dangerous)
–A pointer points to a heap-dynamic
variable that has been de-allocated
In C++. arrayPtr1
ArrayPtr2 int[100]
int * arrayPtr1;
int * arrayPtr2 = int[100];
arrayPtr1 = arrayPtr2;
delete [] arrayPtr2;
// Now
arrayPtr1 is dangling.
Reference Types of C++
A C++ reference type variable is a constant, it must be
initialized with the address of
some variable in its definition, and after
initialization a reference type variable can
never be set to reference any other variable.
int num1 = 10;
int num2 = 20;
int &RefOne = num1; // valid
int &RefOne = num2; // error, two
definitions of RefOne
int &RefTwo = num2; // valid
In C++, the real usefulness of references is when they
are used to pass values into functions
Tidak ada komentar:
Posting Komentar