1

I am trying to write a program in Fortran (using Plato) to calculate the median of an array without sorting them. However, I receive this error and it seems that the program doesn't enter the function at all. Can anyone please let me know what is wrong about my program? My program is this:

    !=================program median========================
    program MedianVal
    real,dimension(:),allocatable::arr
    real::median
    integer::n
    print*,'please enter the number of the arrays'
    read*,i
    allocate(arr(i))
    print*,'please enter your array:'
    read*,arr
    !med=median(n,arr)
    !print*,'The median is:'
    !print*,median(n,arr)
    write(6,*)'The median is:',median(n,arr)
    end program
    !=================Function Median=======================
    real function median(n,arr)
    real,dimension(:),allocatable::arr
    integer::n
    !allocate(arr(i))
    print*,'entered function'
    n=size(arr,1)
    print*,n
    median=0
    if(mod(n,2)==0)then 
      median=(arr((n-1)/2)+arr(n/2))/2
    else
      median=arr(n/2)
    end if
    end function median

Here is the error log :

Attempt to call a routine with an incorrect or missing INTERFACE related to argument number two, which needs to be declared as assumed-shape in both the caller and callee at address 1c008629

Within file Exercise2.exe in MEDIAN at address fc in MEDIANVAL in line 14, at address 371

francescalus
  • 30,576
  • 16
  • 61
  • 96
ro.jam
  • 11
  • 2
  • See also the more general [question about assumed-shape arguments](https://stackoverflow.com/q/42766530/3157076). – francescalus Dec 05 '19 at 16:43
  • It's also not obvious why you want the dummy argument `arr` to be allocatable rather than assumed-shape. It doesn't need to be allocatable just because the actual argument is and you don't need to change the allocation status of it. However, your main problem appears to relate to the explicit interface being required and not provided. – francescalus Dec 05 '19 at 16:48
  • @francescalus Thanks. I checked the link you mentioned. My program contains a function (not subroutine and I have no problem when I write it using subroutine). The reason I use allocatable is I want the user to specify the number of the arrays he wants to enter and then enter them. The problem doesn't solve by putting the function in the module since I am defining executable statements that can't appear before/inside module. I have checked many files containing the programs with functions, but all of them are just very similar to my program. So any help will still be appreciated. – ro.jam Dec 06 '19 at 14:00
  • Using an allocatable array in the main program is entirely appropriate for that use. However, you're just passing the array to the function and that function doesn't need to change the array at all - so it doesn't need to be allocatable there. (As I said before, you can associate the allocatable array in the main program with a non-allocatable array in the function.) – francescalus Dec 06 '19 at 14:07
  • "putting the function in the module since I am defining executable statements that can't appear before/inside module" I'm afraid I don't follow. You just have `module mymod; contains; function median(arr); ... ; end function; end module` (semi-colons used just for formatting in this comment). You don't need to put any executable statements in the module itself. – francescalus Dec 06 '19 at 14:08
  • @francescalus If you mean the allocate command in the function, it is not included in the program (it has a ! beside it). for your second question, when I use the executable statements, they should be written in the main program since they cant be included in the module. On the other hand, since the module contains the function and the function uses the parameters that are read externally, it should be 'use module' after the executable statements which is also an error since the 'use module' command must come before executable statements. This causes a problem. – ro.jam Dec 06 '19 at 16:03
  • I don't mean the `allocate` statement, I mean the `allocatable` attribute: `real,dimension(:),allocatable::arr` could just be `real,dimension(:) ::arr` to make this argument assumed-shape. – francescalus Dec 06 '19 at 16:06
  • The function you have now is an external function: it has no access at all to anything in the main program except through the arguments. Moving it to a module cannot create a problem there that's not present in the external version. – francescalus Dec 06 '19 at 16:08
  • @francescalus Even that one cant be omitted since I want to ask the user to enter the dimension of the array and if I define shape then I need to write it like 'real,dimension(:) ::arr(i)' which I receive an error due to unknown 'i' value unless I don't want the user to define it and I define it myself like: 'real,dimension(:) ::arr(5)'. Anyways, that is not the problem with my program. the program is compiling, when it runs, the only line that gives error is 'write(6,*)'The median is:',median(n,arr)' which means either the function doesn't work or the way I write the write command is wrong. – ro.jam Dec 06 '19 at 16:15
  • @francescalus If I move it into a module, then I should write 'use module' in the main program, which I can't write that in the program after I ask the user to enter the array and its dimension. – ro.jam Dec 06 '19 at 16:26
  • "then I should write 'use module' in the main program, which I can't write that in the program after I ask the user to enter the array and its dimensio", no: you put `use module` at the start of the program before any executable statements. – francescalus Dec 06 '19 at 16:32
  • @francescalus OMG! It worked...Thank you so much! I thought I can't put it in a module since the parameters of the function are yet not defined in the program. But as you said the function is something from out of the program and external, It solved the problem. – ro.jam Dec 06 '19 at 16:41

0 Answers0