How do I create a pointer to an element of an array with a variable index?

In summary, the program prints the largest value in the x-column and the second largest value in the y-column.
  • #1
Eclair_de_XII
1,083
91
TL;DR Summary
In particular, I am having trouble creating a subroutine that takes an array and a pointer as arguments, and has the pointer reference the largest element of the array.
1_point-to-biggest.f90:
program main
    implicit none
    real,dimension(3),target::x=[0,4,5]
    real,pointer::y
    call point_to_biggest(x,y)
    !print *,y ! For testing purposes; to be unmuted only when y points to something
contains
    subroutine point_to_biggest(array,ptr)
        implicit none
        real,dimension(:),intent(in),target::array
        real,pointer,intent(in)::ptr
        !ptr=>array(maxloc(array)) ! Results in gfortran thinking that array(maxloc(array)) is some sort of rank-1 object
    end subroutine point_to_biggest
end program main
 
Last edited:
Technology news on Phys.org
  • #2
Your variable ptr is declared in point_to_biggest as intent(in) but don't you want it to be an output of that subroutine?
 
  • #3
Subroutines do not have outputs, though. They do not return anything. Are they not the Fortran-equivalent of void functions in C?
 
  • #4
You are correct to say that a FORTRAN subroutine can not output a value through its name. It can output value(s) through one or more of its parameters. If you want your subroutine to modify the value of ptr, then you can not declare it intent(in). You can declare it intent(out) or intent(inout). See this.

A FORTRAN function can output a value through its name and that can be very handy for something, like sin(x), that would be used in formulas or equations. You might want to use that here.
 
  • #5
Fortran:
program main
    implicit none
    real,dimension(3)::x=[1,3,77]
    real::y
    y=get_biggest(x)
    print *,y
contains
    real function get_biggest(x)
        implicit none
        real,dimension(:),intent(in)::x
        get_biggest=maxval(x)
    end function get_biggest
end program main

How do I do this with the pointer method, though? For some reason, array(maxloc(array)) is seen as an array and not as a scalar. I have no idea why this is.
 
  • #6
Eclair_de_XII said:
Subroutines do not have outputs, though. They do not return anything. Are they not the Fortran-equivalent of void functions in C?
Fortran subroutines are similar to void functions in C, but the similarity is not exact. Parameters in Fortran subroutines/functions are passed by reference, while parameters in C functions are passed by value. C can simulate passing by reference by the use of pointer variable parameters.

The Fortran maxloc function returns the value of the largest element of an array, not its index. What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index. Working with pointers might be adding more complexity than is needed for what you're trying to do.
 
  • Like
Likes FactChecker
  • #7
Mark44 said:
The Fortran maxloc function returns the value of the largest element of an array, not its index.
I think you mean MAXVAL, which he is calling in post #5, not MAXLOC, which he called in post #1.
Eclair_de_XII said:
How do I do this with the pointer method, though? For some reason, array(maxloc(array)) is seen as an array and not as a scalar. I have no idea why this is.
MAXLOC returns an array so that it will work with multidimensional arrays. If the input array has three dimensions, it will return an array of dimension 3 with the three indices of the largest value. In your case, it will return an array of dimension 1 with one index. It is instructive to study the documentation of MAXINT and look up any terminology or concepts that you are unfamiliar with.
.
Mark44 said:
What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index. Working with pointers might be adding more complexity than is needed for what you're trying to do.
Good advice. Although, in this case, there is a lot to learn about reading the FORTRAN documentation of MAXLOC which has terminology and concepts that may be new to the student. (It was new to an old-timer like me, who has not used modern FORTRAN versions.)
 
  • Like
Likes DrClaude
  • #8
FactChecker said:
I think you mean MAXVAL
Yes, I looked up the docs for MAXVAL but miswrote it as maxloc.
FactChecker said:
(It was new to an old-timer like me, who has not used modern FORTRAN versions.)
Nor have I. Last Fortran compiler I had was an F95 implementation by Fahey, IIRC. It was a lot different from the F77 compiler I used in a class I took back in '80 -- which ran on machines (IBM?) that were programming with punch cards.
 
  • Like
Likes FactChecker
  • #9
Fortran:
program main
    implicit none
    real,dimension(3),target::x=[0,5,5]
    real,pointer::y
    call point_to_biggest(x,y)
    print *,x(2)
contains
    subroutine point_to_biggest(array,ptr)
        implicit none
        real,dimension(:),intent(in),target::array
        real,pointer::ptr
        integer,dimension(1)::array_maxlocs
        array_maxlocs=maxloc(array)
        ptr=>array(array_maxlocs(1))
        ! ptr=>array(maxloc(array)(1)) ! Compiler tells me this is an invalid form of array reference.
        ptr=66 ! To verify that ptr does indeed point to x(2)
    end subroutine point_to_biggest
end program main

Okay, I solved the problem. Thanks, to everyone who replied. I had initially thought that the maxloc function returned an integer scalar; but reading the gnu documentation provided by FactChecker tells me that it returns an integer 1-array that stores the index I had initially thought the maxloc function returned. I had to create an integer 1-array variable to store the result of the maxloc function. What troubles me now, is why I cannot simply have a pointer point to the specific array element directly, as I have done in line 15.
 
  • #10
Eclair_de_XII said:
What troubles me now, is why I cannot simply have a pointer point to the specific array element directly, as I have done in line 15.
Here's your line 15, uncommented:
Fortran:
ptr=>array(maxloc(array)(1)) ! Compiler tells me this is an invalid form of array reference.

My Fortran is pretty rusty, but it seems to me that what you have is an expression, but what I think you need is an assignment statement. In the expression above, ptr is a declared, but uninitialized, pointer.

Edit: My rustiness with relatively recent Fortran syntax led me to think the above was an expression. On review, the problem is more likely the (1) that @DrClaude pointed out.
 
Last edited:
  • #11
The problem is that
Fortran:
maxloc(array)(1)
doesn't make sense syntactically. maxloc is a function, so appending (1) to it makes no sense.
 
  • #12
Mark44 said:
What I would do, rather than rely on a built-in function (which may or may not exist), is to write my own function that cycled through the array, keeping track of both the current largest value and its index.
I must disagree with this. The point of all these built-in functions in modern FORTRAN is to allow for more efficient code. I think they should be used as much as possible.
 
  • #13
DrClaude said:
I must disagree with this. The point of all these built-in functions in modern FORTRAN is to allow for more efficient code. I think they should be used as much as possible.
That's a fair point, but I think the OP just wants to get something done. I don't believe this is any production code that has to be super efficient.
 
  • #14
DrClaude said:
The problem is that
Fortran:
maxloc(array)(1)
doesn't make sense syntactically. maxloc is a function, so appending (1) to it makes no sense.
Oh, I see. So I cannot treat it like the value that it returns, then.

Mark44 said:
OP just wants to get something done
You are mistaken. I created this topic in order to address an exercise I found in an online textbook. It is on page 379 of this book.
 
  • #15
Eclair_de_XII said:
You are mistaken. I created this topic in order to address an exercise I found in an online textbook.
So that is what you wanted to "getting something done," as I put it. My point was that this is not some production code that has to be very efficient.
 
  • #16
Mark44 said:
So that is what you wanted to "getting something done," as I put it. My point was that this is not some production code that has to be very efficient.
That is correct. However, in the context of learning modern FORTRAN, I think it is good to try and master the built-in functions.

(Note: I think that the only point of programming in modern FORTRAN (≥90) is for high-performance computing applications, and therefore using the most efficient approaches.)
 
  • #17
DrClaude said:
That is correct. However, in the context of learning modern FORTRAN, I think it is good to try and master the built-in functions.
I agree. There is the efficiency of execution and also the efficiency of creating reliable code. Using established library functions achieves both.
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
 
  • Like
Likes berkeman and DrClaude
  • #18
FactChecker said:
I agree. There is the efficiency of execution and also the efficiency of creating reliable code. Using established library functions achieves both.
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it? That would provide an even better reason to use them.

For example, the same user program may be used to process 101 elements, or 1010 elements. But huge data sets might make good use of different strategies. They could look for example at the cache size and availability of GPU processors. It would make more sense to me to embed such intelligence in libraries rather than in end user written programs.
 
  • Like
Likes FactChecker
  • #19
anorlunda said:
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it?
Good question.
 
  • #20
FactChecker said:
That said, a simple algorithm like finding the maximum should be well within a programmer's ability before he moves on.
I agree.
 
  • #21
anorlunda said:
My FORTRAN is very obsolete. Is it possible that the modern library functions are prepared to recognize the opportunity to exploit parallelism and if yes to take advantage of it? That would provide an even better reason to use them.
Yes. Modern HPC compilers can do automatic parallelization. In addition to library functions, you have constructs such as DO CONCURRENT, where the compiler can execute the different iterations of the loop in any order.
 
  • Informative
Likes FactChecker

FAQ: How do I create a pointer to an element of an array with a variable index?

1. How do I create a pointer to an element of an array with a variable index?

To create a pointer to an element of an array with a variable index, you can use the syntax "array_name + index". This will return the memory address of the element at the specified index.

2. Can I use a variable as the index when creating a pointer to an element of an array?

Yes, you can use a variable as the index when creating a pointer to an element of an array. This allows you to access different elements of the array without having to change the code for each element.

3. How do I dereference a pointer to an element of an array with a variable index?

To dereference a pointer to an element of an array with a variable index, you can use the "*" operator. This will retrieve the value stored at the memory address pointed to by the pointer.

4. What happens if the index I provide to the pointer is out of bounds of the array?

If the index provided to the pointer is out of bounds of the array, the program may crash or return unexpected results. It is important to ensure that the index is within the bounds of the array before using it to create a pointer.

5. Can I use a pointer to an element of an array with a variable index to modify the value of the element?

Yes, you can use a pointer to an element of an array with a variable index to modify the value of the element. This is because the pointer points to the memory address where the element is stored, so any changes made to that address will also affect the value of the element in the array.

Similar threads

Replies
5
Views
7K
Replies
5
Views
3K
Replies
4
Views
2K
Replies
4
Views
2K
Replies
8
Views
3K
Replies
5
Views
12K
Back
Top