Преобразование функции стека с C в Fortran - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь перевести код на язык фортран.Код представляет собой функцию вставки в стек.Я завершил перевод, и код работает, но я не получаю желаемого результата.Код c:

#include <stdio.h>
#include <string.h>
#define MAX 30

char stack[MAX][MAX];
int top = -1;

void push(char str[]){
 if(top != MAX-1){
  strcpy(stack[++top], str);
  printf("test1 : %s\n",stack[top]);
  }
 else{
  printf("Stack overflow : May be invalid prefix expression\n");
 }
}

int main(){

push("abcd");

return 0;
}

Мой перевод на фортране:

 program testf1
 implicit none
 integer   :: maximum
 integer   :: top
 character(len=:), allocatable :: i 
 character, dimension(:), allocatable :: stack  

 maximum = 30
 top = 0


 allocate (stack(maximum))
 i=trim('abcd')
 print*,"this is the test ",i," is ", push(i)

 contains 

 function push(str) result(out1)
 character(len=:), allocatable, intent(in)   :: str ! input
 !character(len=:), allocatable, intent(out)  :: out1 ! output
 character, dimension(:), allocatable        :: out1 ! output
 integer :: length

 length = len(str)
 allocate (out1(length))
 if (top .NE. maximum - 1 ) then
     top=top+1
     out1(top)=str
     print*, "testf1 : ", out1(top)
  else
  print*, "Stack2 overflow : May be invalid prefix expression"
 end if 
 end function push

end program testf1

Вместо abcd я получаю a.Я подозреваю, что я должен использовать подпрограмму вместо функции, потому что push не должен возвращать значение, как на языке c.Но я все еще борюсь со струнными манипуляциями.Мой подход правильный?Я также думаю, что в c есть ошибка в объявлении переменной, потому что должен быть char stack [max] или массив измерений 1, к которому я уже обратился, что в fortran.

1 Ответ

0 голосов
/ 12 февраля 2019

Ваш код не делает то, что вы хотите, потому что, когда вы говорите

out1(top)=str

в своем коде, вы в основном назначаете содержимое str последнему символу out1, что,учитывая ваш ввод 'abcd' функции, выдает символ a.Есть много лучших способов добиться того, чего вы хотите, и вот один из способов сделать это в современном Fortran:

! /11734130/preobrazovanie-funktsii-steka-s-c-v-fortran
module Stack_mod

    integer, parameter :: MAX_STACK_SIZE = 30

    type :: JaggedArray_type
        character(:), allocatable :: Record
    end type JaggedArray_type

    type :: Stack_type
        integer :: top = 0
        type(JaggedArray_type) :: Array(MAX_STACK_SIZE)
    contains
        procedure, pass :: push
    end type Stack_type

contains

    subroutine push(Stack,record)
        implicit none
        class(Stack_type), intent(inout)    :: Stack
        character(*), intent(in)            :: record
        if (Stack%top>MAX_STACK_SIZE) then
            write(*,"(*(g0,:,' '))") "Stack2 overflow: May be invalid prefix expression"
        else
            Stack%top = Stack%top + 1
            Stack%Array(Stack%top)%record = record
            write(*,"(*(g0,:,' '))") "this is the test",Stack%top,"is",Stack%Array(Stack%top)%record
        end if 
    end subroutine push

end module Stack_mod

program testf1

    use Stack_mod, only: Stack_type
    implicit none
    type(Stack_type) :: Stack
    call Stack%push("abcd")
    write(*,"(*(g0,:,' '))") "This is from the main program: ", Stack%Array(Stack%top)%record

end program testf1

Компиляция и запуск компилятором Fortran 2008 дает:

$gfortran -std=f2008 testf1.f90 -o main
$main
this is the test 1 is abcd
This is from the main program:  abcd

Вы можете проверить это здесь онлайн: https://www.tutorialspoint.com/compile_fortran_online.php

Я надеюсь, что я не просто ответил на вопрос домашней работы здесь и что вы пытаетесь узнать что-то на StackOverflow.

...