In Fortran, arrays are a fundamental data structure that is used for storing and manipulating collections of values. Sometimes, it’s essential to know the bounds (size or limits) of an array, especially when working with dynamic arrays or when passing arrays between subroutines. Fortran provides two built-in functions, lbound and ubound, that allow you to obtain the lower and upper bounds of an array, respectively.
In this post, we will explain the lbound and ubound functions in Fortran, demonstrate how to use them, and explore their significance in practical applications.
What Are lbound and ubound?
lbound(array): This function returns the lower bound of the array, i.e., the smallest index that can be used to access elements in the array.ubound(array): This function returns the upper bound of the array, i.e., the largest index that can be used to access elements in the array.
Both functions are useful for determining the valid index range for accessing elements in an array. They are especially helpful when working with arrays that have dynamic sizes or when dealing with arrays that are passed as arguments to subroutines and functions.
Syntax
lower_bound = lbound(array, dimension)
upper_bound = ubound(array, dimension)
array: The array for which the bounds are being determined.dimension(optional): The dimension of the array for which you want to find the bounds. If not specified, the function assumes you are asking about the first dimension of the array.
Note that the default lower bound is often 1 for arrays declared with the default indexing, but it can be different if the array has a custom lower bound.
Example 1: Using lbound and ubound with a Static Array
Let’s start with a simple example using a statically declared array, where we explicitly define the lower and upper bounds.
Code Example:
program bounds_example
integer :: arr(1:10)
integer :: lower_bound, upper_bound
lower_bound = lbound(arr)
upper_bound = ubound(arr)
print *, "Lower bound: ", lower_bound
print *, "Upper bound: ", upper_bound
end program bounds_example
Output:
Lower bound: 1
Upper bound: 10
In this example:
- We declared an array
arrwith bounds from 1 to 10. - The
lbound(arr)returns1, and theubound(arr)returns10, indicating the valid indices of the array.
Example 2: Using lbound and ubound with Multi-dimensional Arrays
For multi-dimensional arrays, you can use the lbound and ubound functions to obtain the bounds for each dimension.
Code Example:
program multi_dimensional_bounds
integer :: arr(1:5, 2:6)
integer :: lower_bound1, upper_bound1, lower_bound2, upper_bound2
lower_bound1 = lbound(arr, 1) ! Lower bound for the first dimension
upper_bound1 = ubound(arr, 1) ! Upper bound for the first dimension
lower_bound2 = lbound(arr, 2) ! Lower bound for the second dimension
upper_bound2 = ubound(arr, 2) ! Upper bound for the second dimension
print *, "Lower bound of dimension 1: ", lower_bound1
print *, "Upper bound of dimension 1: ", upper_bound1
print *, "Lower bound of dimension 2: ", lower_bound2
print *, "Upper bound of dimension 2: ", upper_bound2
end program multi_dimensional_bounds
Output:
Lower bound of dimension 1: 1
Upper bound of dimension 1: 5
Lower bound of dimension 2: 2
Upper bound of dimension 2: 6
In this case:
- The first dimension has bounds from
1to5, so the lower bound for dimension 1 is1and the upper bound is5. - The second dimension has bounds from
2to6, so the lower bound for dimension 2 is2and the upper bound is6.
Example 3: Dynamic Arrays with lbound and ubound
When working with dynamic arrays (arrays that are allocated during runtime), you may not know the exact size of the array at compile time. Using lbound and ubound can help you determine the bounds of such arrays at runtime.
Code Example:
program dynamic_bounds
integer, allocatable :: arr(:)
integer :: lower_bound, upper_bound
integer :: n
print *, "Enter the size of the array: "
read *, n
allocate(arr(1:n)) ! Allocating array dynamically
lower_bound = lbound(arr)
upper_bound = ubound(arr)
print *, "Lower bound: ", lower_bound
print *, "Upper bound: ", upper_bound
deallocate(arr) ! Deallocating the array
end program dynamic_bounds
Output:
Enter the size of the array:
10
Lower bound: 1
Upper bound: 10
In this case:
- The user inputs the size of the array (e.g., 10), and the array is dynamically allocated.
- The
lbound(arr)andubound(arr)functions return1and10, respectively, because the default lower bound is1and the array is allocated with size 10.
Example 4: Using lbound and ubound in Subroutines
You can pass arrays with dynamic bounds to subroutines, and inside the subroutine, use lbound and ubound to access the bounds of the array. This is particularly useful when dealing with multi-dimensional arrays or when the bounds of the array may vary based on input.
Code Example:
program bounds_in_subroutine
integer :: arr(1:5), lower_bound, upper_bound
arr = [10, 20, 30, 40, 50]
call print_bounds(arr)
contains
subroutine print_bounds(array)
integer, dimension(:) :: array
integer :: lower_bound, upper_bound
lower_bound = lbound(array)
upper_bound = ubound(array)
print *, "Array bounds in subroutine:"
print *, "Lower bound: ", lower_bound
print *, "Upper bound: ", upper_bound
end subroutine print_bounds
end program bounds_in_subroutine
Output:
Array bounds in subroutine:
Lower bound: 1
Upper bound: 5
Here:
- The
arrarray is passed to theprint_boundssubroutine. - Inside the subroutine,
lbound(array)andubound(array)return the bounds of the array, which are1and5, respectively.
Practical Use Cases for lbound and ubound
- Iterating over arrays dynamically: If you want to iterate over an array but the bounds are not known at compile time (for example, in a dynamically allocated array), you can use
lboundanduboundto determine the correct bounds. - Validating array indices: Before accessing an element in an array, you can check if the index is within the bounds using
lboundandubound. - Subroutine/Function flexibility: When writing generic subroutines or functions that work with arrays,
lboundanduboundmake your code more flexible by allowing it to work with arrays of different sizes or dimensions.
Leave a Reply