Array Initialization: Difference between revisions

From Rosetta Code
Content added Content deleted
(fortran (code moved from "creating an array"))
Line 204: Line 204:
array ((0,0),(5,5)) [((0,0),0),((0,1),0),((0,2),0),((0,3),0),((0,4),0),((0,5),0),((1,0),0),((1,1),0),((1,2),0),((1,3),0),((1,4),0),((1,5),0),((2,0),0),((2,1),0),((2,2),0),((2,3),0),((2,4),0),((2,5),0),((3,0),0),((3,1),0),((3,2),0),((3,3),0),((3,4),0),((3,5),0),((4,0),0),((4,1),0),((4,2),0),((4,3),0),((4,4),0),((4,5),0),((5,0),0),((5,1),0),((5,2),0),((5,3),0),((5,4),0),((5,5),0)]
array ((0,0),(5,5)) [((0,0),0),((0,1),0),((0,2),0),((0,3),0),((0,4),0),((0,5),0),((1,0),0),((1,1),0),((1,2),0),((1,3),0),((1,4),0),((1,5),0),((2,0),0),((2,1),0),((2,2),0),((2,3),0),((2,4),0),((2,5),0),((3,0),0),((3,1),0),((3,2),0),((3,3),0),((3,4),0),((3,5),0),((4,0),0),((4,1),0),((4,2),0),((4,3),0),((4,4),0),((4,5),0),((5,0),0),((5,1),0),((5,2),0),((5,3),0),((5,4),0),((5,5),0)]
</lang>
</lang>

=={{header|MAXScript}}==
Collect method:
<pre>arr = for i in 1 to 100 collect 0</pre>
Append method:
<pre>arr = #()
for i in 1 to 100 do append arr 0</pre>
Assign and dynamically grow method:
<pre>arr = #()
for i in 1 to 100 do arr[i] = 0</pre>


=={{header|Modula-3}}==
=={{header|Modula-3}}==

Revision as of 23:37, 6 March 2009

Task
Array Initialization
You are encouraged to solve this task according to the task description, using any language you may know.

Demonstrate how to initialize an array variable with data.

See Creating_an_Array for this topic.

Ada

The array value obtained directly from data is called array aggregate. Considering these array declarations: <lang ada> type Vector is array (Integer range <>) of Integer; type Matrix is array (Integer range <>, Integer range <>) of Integer; type String is array (Integer range <>) of Character; type Bits is array (Integer range <>) of Boolean; </lang> Initialization by an aggregate using positional and keyed notations: <lang ada> X : Vector := (1, 4, 5); Y : Vector (1..100) := (2|3 => 1, 5..20 => 2, others => 0); E : Matrix := ((1, 0), (0, 1)); Z : Matrix (1..20, 1..30) := (others => (others => 0)); S : String := "ABCD"; L : String (1..80) := (others => ' '); B : Bits := not (1..2 => False); -- Same as (1..2 => True) </lang> Note that the array bounds, when unconstrained as in these examples can be either determined by the aggregate, like the initialization of X shows. Or else they can be specified as a constraint, like for example in the initialization of Y. In this case others choice can be used to specify all unmentioned elements. But in any case, the compiler verifies that all array elements are initialized by the aggregate. Single dimensional arrays of characters can be initialized by character strings, as the variable S shows. Of course, array aggregates can participate in array expressions and these expressions can be used to initialize arrays. The variable B is initialized by an aggregate inversed by the operation not.

ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
MODE VEC = FLEX[0]INT; # VECTOR is builtin in ALGOL 68R #
MODE MAT = FLEX[0,0]INT;
# MODE STRING = FLEX[0]CHAR; builtin #
MODE BOOLS = FLEX[0]BOOL; # BITS is builtin in the standard #

Initialization by an aggregate using positional and keyed notations:

VEC x := (1, 4, 5);
[100]INT y; FOR i TO UPB y DO y[i]:=0 OD; FOR i FROM 5 TO 20 DO y[i]:= 2 OD; y[2]:=y[3]:= 1;
MAT e := ((1, 0), (0, 1));
[20,30]INT z; FOR i TO UPB z DO FOR j TO 2 UPB z DO z[i,j]:=0 OD OD;
STRING s := "abcd";
STRING l := " "*80;
[2]BOOL b := (TRUE, TRUE);
SKIP

C++

Simple arrays in C++ have no bounds-checking. In order to safely modify the array's contents, you must know in advance both the number of dimensions in the array and the range for each dimension. In C++, all arrays are zero-indexed, meaning the first element in the array is at index 0.

To assign a single value to an array, one uses the [] operator. <lang cpp> // Assign the value 7 to the first element of myArray. myArray[0] = 7; </lang> If myArray has ten elements, one can use a loop to fill it. <lang cpp> // Assign the sequence 1..10 to myArray for(int i = 0; i < 10; ++i)

 myArray[i] = i + 1;

</lang> If myArray has two dimensions, you can use nested loops. <lang cpp> // Create a multiplication table for(int y = 0; y < 10; ++y)

 for(int x = 0; x < 10; ++x)
   myArray[x][y] = (x+1) * (y+1);

</lang>

D

<lang d> int[] y; // y is null until initialized </lang>

<lang d> int[3] y; // y[0] == y[1] == y[2] == int.init == 0 </lang>

<lang d> int[] y = [1,2,3,4]; </lang>

<lang d> int[string] y; // y is an associative array. Initially null until elements are added y["hello"] = 3; y["world"] = 7; </lang>

Fortran

Works with: Fortran version 95 and later

Arrays can be initialized using a robust set of array constructors and array intrinsic functions. <lang fortran> program arrays

    real :: a(100) = 0                      ! entire array initialized to ZERO
    real :: b(9) = (/ 1,2,3,4,5,6,7,8,9 /)  ! array constructor
    real :: c(10) = (/ (2**i, i=1, 10) /)   ! array constructor with "implied do loop"
      ! An array constructor is a literal definition of a ONE-DIMENSIONAL array only.
      ! In order to initialize multidimensional arrays, you need to use the RESHAPE instrinsic
      ! function:
    real :: d(2, 5) = reshape( (/ (2**i,i=1,10) /),            (/ 2, 5 /) )
      !                        ^^^^^^^^^^^^^^^^^^^source array ^^^^^^^^^^ dimension shape
      ! Fills the array in COLUMN MAJOR order. That is, traverse the first dimension first,
      ! second dimension second, etc.
    
      ! In order to fill a matrix in ROW MAJOR order, merely specify as before,
      ! but TRANSPOSE the result
    real :: e(4, 4) = transpose( reshape( &
                      (/  1,  2,  3,  4, &
                          5,  6,  7,  8, &
                          9, 10, 11, 12, &
                         13, 14, 15, 16  /), (/ 4, 4 /) ) )
    
    print *, b
    print *
    print *, c
    print *
    print '(5F7.0)', d(1,:)       ! print row 1
    print '(5F7.0)', d(2,:)       ! print row 2
    print *
    do i = 1, 4
        print '(4F7.0)', e(i,:)   ! print row I
    end do
end program arrays</lang>

Output:

1. 2. 3. 4. 5. 6. 7. 8. 9.

2. 4. 8. 16. 32. 64. 128. 256. 512. 1024.

    2.     8.    32.   128.   512.
    4.    16.    64.   256.  1024.

    1.     2.     3.     4.
    5.     6.     7.     8.
    9.    10.    11.    12.
   13.    14.    15.    16.

Here is a more interesting example showing a function that creates and returns a square identity matrix of order N: <lang fortran> module matrixUtil

contains
    function identity(n)
        integer, intent(in) :: n
        integer             :: i, j
        real, pointer       :: identity(:,:)
        
        allocate(identity(n,n))
          ! the MERGE intrinsic is like a C ternary (if-then-else) operator, except that the logical condition
          ! comes at the end, it is a logical ARRAY, and the function result is an array of the same size and shape
        identity = merge (1.0,               0.0,                reshape( (/ ( (i==j, i=1,n), j=1,n) /), (/ n, n /) ) )
          !               ^^^ if-TRUE-value  ^^^ if-FALSE-value  ^^<-NxN logical array, true only on the diagonal->^^
          ! The TVALUE and FVALUE must be "conformable" to the logical array, meaning that each is either:
          ! -- an array of the same size and shape as the logical array
          ! -- a scalar
    end function identity
end module matrixUtil</lang>

<lang fortran> program muTest

    use matrixUtil
    integer        :: n
    real, pointer  :: i(:,:)
    
    read (*,*) n
    i => identity(n)
    do j=1, size(i,1)
        print *, i(j,:)
    end do
    deallocate(i)
end program muTest</lang>

Example run:

$ g95 -o mu matrixUtil.f95 muTest.f95
$ ./mu
15
1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.
$


Haskell

To create any new Array of the various array types, you can use this to initialise it with all elements filled with x, and indexes ranging from n to m <lang haskell> newArr :: (Ix i) => i -> i -> e -> Array i e newArr n m x = listArray (n,m) (repeat x)


Prelude Data.Array> newArr 0 10 0 array (0,10) [(0,0),(1,0),(2,0),(3,0),(4,0),(5,0),(6,0),(7,0),(8,0),(9,0),(10,0)]

Prelude Data.Array> newArr (0,0) (5,5) 0 array ((0,0),(5,5)) [((0,0),0),((0,1),0),((0,2),0),((0,3),0),((0,4),0),((0,5),0),((1,0),0),((1,1),0),((1,2),0),((1,3),0),((1,4),0),((1,5),0),((2,0),0),((2,1),0),((2,2),0),((2,3),0),((2,4),0),((2,5),0),((3,0),0),((3,1),0),((3,2),0),((3,3),0),((3,4),0),((3,5),0),((4,0),0),((4,1),0),((4,2),0),((4,3),0),((4,4),0),((4,5),0),((5,0),0),((5,1),0),((5,2),0),((5,3),0),((5,4),0),((5,5),0)] </lang>

MAXScript

Collect method:

arr = for i in 1 to 100 collect 0

Append method:

arr = #()
for i in 1 to 100 do append arr 0

Assign and dynamically grow method:

arr = #()
for i in 1 to 100 do arr[i] = 0

Modula-3

The usual module and import code is omitted. <lang modula3>VAR arr := ARRAY [1..10] OF INTEGER {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; VAR arr1 := ARRAY [1..10] OF INTEGER {1, ..} (* Initialize all elements to 1. *)</lang> Array initialization doesn't have to be used in the array declaration. <lang modula3>TYPE Vector: ARRAY OF INTEGER; VAR arr: Vector; arr := Vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};</lang>

Python

Python lists are dynamically resizeable. A simple, single dimensional, array can be initialized thus:

<lang python> myArray = [0] * size </lang>

However this will not work as intended if one tries to generalize from the syntax:

<lang python> myArray = [[0]* width] * height] # DOES NOT WORK AS INTENDED!!! </lang>

This creates a list of "height" number of references to one list object ... which is a list of width instances of the number zero. Due to the differing semantics of mutables (strings, numbers) and immutables (dictionaries, lists), a change to any one of the "rows" will affect the values in all of them. Thus we need to ensure that we initialize each row with a newly generated list.

To initialize a list of lists one could use a pair of nested list comprehensions like so:

<lang python> myArray = [[0 for x in range(width)] for y in range(height)] </lang>

That is equivalent to:

<lang python> myArray = list() for x in range(height):

  myArray.append([0] * width)

</lang>

STL

Library: STL

STL provides std::vector, which behaves as a dynamically-resizable array. When an element is added, its value must be set immediately.

<lang cpp> myVector.push_back(value); </lang> Like simple arrays, std::vector allows the use of the [] operator, and once an element has been added, it can be changed the same way a simple array can. <lang cpp> myVector[0] = value; </lang> Unlike simple arrays, std::vector allows you to determing the size of the array. You can use this set all of the values in the array: <lang cpp> // Create a list of numbers from 1 to the size of the vector. size_t size = myVector.size(); for(int i = 0; i < size; ++i)

 myVector[i] = i + 1;

</lang> std::vector also provides iterators, allowing you to iterate through a vector's elements the same way you might any other STL container class.

 // Create a list of numbers from 1 to the size of the vector.

<lang cpp> std::vector<int> myVector; int val = 0; for(std::vector<int>::iterator it = myVector.begin();

   it != myVector.end();
   ++it)
 *it = ++val;

</lang> A vector can also explicitly be resized: <lang cpp> std::vector<int> myVector; myVector.resize(10); // now the vector contains 10 elements, all of which are 0 myVector.resize(15, 3); // now the vector contains 15 elements, the 5 new got the value 3 myVector.resize(12); // the last three elements got removed </lang> Also note that a vector can already be filled at construction time: <lang cpp> std::vector v1(10); // a vector of 10 ints, all initialized with 0 std::vector v2(5, 7); // a vector containing 5 ints, all inizialized with 7 int a[10] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }; std::vector v3(a, a+10); // a vector containing 10 ints, initialized with the elements of a (i.e. v3[0]==a[0] etc.) std::vector v4 = v3; // v4 is a copy of v3 </lang>