Ergebnis 1 bis 10 von 10

Fortran

  1. #1 Zitieren
    Sergej Petrow
    Gast
    Kennt sich hier jemand in Fortran aus und kann mir die Übersetzung einer kleinen Java-Arbeit in Fortran erledigen?
    Das Programm rechnet die Determinante einer fünfer Matrix aus nach dem Laplace-Verfahren.


    Code:
    	double [][] array=new double[6][6];
    	
    	array[1][1]=8; //nur ein Beispielarray einer 5 Matrix zum Berechnen der Determinante
    	array[1][2]=2;
    	array[1][3]=3;
    	array[1][4]=4;
    	array[1][5]=5;		
    	
    	array[2][1]=6;
    	array[2][2]=5;
    	array[2][3]=4;
    	array[2][4]=3;
    	array[2][5]=9;	
    	
    	array[3][1]=7;
    	array[3][2]=8;
    	array[3][3]=0;
    	array[3][4]=10;
    	array[3][5]=9;		
    	
    	array[4][1]=9;
    	array[4][2]=8;
    	array[4][3]=7;
    	array[4][4]=6;	
    	array[4][5]=5;		
    
    	array[5][1]=12;
    	array[5][2]=13;
    	array[5][3]=14;
    	array[5][4]=15;	
    	array[5][5]=16;		
    	
    	
    	double [][] array_;
    	double [][] array1;
    	double [][] array2;	
    	int matrix_groesse=5;
    	int vorzeichen=1,hilf1=1,hilf2=1;
    	double faktor1,faktor2;
    	double determinante=0;
    	double zwischenergebnis=0,zwischenergebnis1=0;
    	
    	for(int k=1;k<matrix_groesse+1;k++)
    		{
    		array2=Formelsammlung.laplace(array, matrix_groesse+1, k);
    		faktor2=array[1][k]*vorzeichen;
    		hilf2=vorzeichen;
    		vorzeichen=1;
    		matrix_groesse-=1;
    		
    		for (int j=1;j<matrix_groesse+1;j++)
    			{
    			array1=Formelsammlung.laplace(array2, matrix_groesse+1, j);
    			faktor1=array2[1][j]*vorzeichen;
    			hilf1=vorzeichen;
    			vorzeichen=1;
    			matrix_groesse-=1;
    			
    			for (int i=1;i<matrix_groesse+1;i++)
    				{
    				array_=Formelsammlung.laplace(array1,matrix_groesse+1,i);
    				zwischenergebnis+=array1[1][i]*Formelsammlung.determinante(array_)*vorzeichen;
    				vorzeichen*=-1;
    				}
    			
    			vorzeichen=hilf1*(-1);
    			zwischenergebnis*=faktor1;
    			zwischenergebnis1+=zwischenergebnis;
    			zwischenergebnis=0;
    			matrix_groesse+=1;
    			}
    		vorzeichen=hilf2*(-1);
    		zwischenergebnis1*=faktor2;
    		determinante+=zwischenergebnis1;
    		zwischenergebnis1=0;
    		matrix_groesse+=1;
    		}
    	
    	System.out.println("Determinante = "+Double.toString(determinante));
    Hier sind die beiden Methoden aus der Bibliothek Formelsammlungen, die oben benutzt werden. Die müssten auch übersetzt werden.
    Code:
    public static double determinante(double [][] array)
    {
    	return (array[1][1]*array[2][2])-(array[1][2]*array[2][1]);
    }
    
    public static double[][] laplace(double [][] array,int groesse_matrix, int spalte)
    {
    	double [][] array_=new double[groesse_matrix-1][groesse_matrix-1];
    	int k,l;
    	
    	k=1;
    	l=1;
    	for (int i=2;i<groesse_matrix;i++)//beginn mit zeile 2, da zeile 1 immer die ausgewählte Zeile ist
    		{
    			{
    			for(int j=1;j<groesse_matrix;j++)
    				{
    				if(j!=spalte) //aktuelle spalte wird nicht berücksichtigt
    					array_[k][l++]=array[i][j];
    				}
    			}
    		k++;
    		l=1;
    		}
    	
    	return array_;
    }
    Der Code ist von mir. Habe das ganze in Java gelöst, was ich einigermaßen gut beherrsche. Musste aber feststellen, dass Fortran eine komplett eigene Welt ist. Normalerweise kann ich mich in Programmiersprachen recht gut einarbeiten, aber strukturell scheint mir das komplett anders als C, C++ oder Java zu sein.

    Wer Lust hat, mir da zu helfen, nur zu.

  2. #2 Zitieren

    Batmanistrator
    Avatar von Thoronador
    Registriert seit
    Jul 2005
    Ort
    Morrowind, Vvardenfell-Distrikt
    Beiträge
    20.801
    Ist eine Weile her, seit ich das letzte Mal etwas in Fortran gemacht habe, aber von den Grundzügen müsste das in Fortran 95 wie folgt aussehen:
    (Es gibt inzwischen auch neuere Fortran-Standards, aber mit denen habe ich mich nicht befasst.)

    Code:
    program matrix
      ! keine implizite Variablendeklarationen
      implicit none
    
      ! zweidimensionales Array mit 5x5 Elementen
      ! Typ real, doppelte Genauigkeit mittels "(kind=8)"
      real(kind=8), dimension(1:5, 1:5) :: array
    
      array(1,1) = 8
      array(1,2) = 2
      array(1,3) = 3
      array(1,4) = 4
      array(1,5) = 5
    
      array(2,1) = 6
      array(2,2) = 5
      array(2,3) = 4
      array(2,4) = 3
      array(2,5) = 9
    
      ! ... und so weiter
    
    end program matrix
    Die Funktionen werden in Fortran auf diese Art geschrieben:
    Code:
    real(kind=8) function determinante(array)
    real(kind=8), dimension(1:,1:), intent(in) :: array
    
        determinante = array(1,1)*array(2,2)-array(1,2)*array(2,1)
    end function determinante
    Im Prinzip werden Funktionen in der Art
    Rückgabetyp function Funktionsname(kommagetrennte Liste der formalen Parameter)
    deklariert.
    Die Typen der Funktionsparameter werden dann am Anfang des Funktionsrumpfes wie normale Variablen deklariert. Fortran erkennt dann anhand der Benamung, dass es um die Parameter geht. Zuweisung eines Funktionsergebnisses erfolgt durch Zuweisung an den Funktionsnamen.
    Thoronador ist offline

  3. #3 Zitieren
    Sergej Petrow
    Gast
    Das heißt ich kann mit einer Funktion auch arrays zurückgeben?

    Und, was auch genauso wichtig ist:

    Ich habe ja bei der Methode Laplace den Rückgabetyp Array. Dieses Array ist aber mehr oder weniger unbestimmt.
    Mit Java kann ich dann einfach in der Main schreiben:

    Double [][] array; als Deklaration und dann nachher:

    array=laplace(array_, matrix_groesse, spalte);

    Hier übergebe ich also an laplace ein array mit der Größe, die in matrix_groesse festgelegt wird. Bekomme eine reduzierte Matrix zurück, die in der noch von der Größe her undefiniertes Array gespeichert wird und ab dann erst von der Größe deklariert ist.

    Fortran lässt sich ganz schön schlecht lesen, muss ich sagen. So anders als Java, Pascal, C oder C++.

  4. #4 Zitieren
    Sergej Petrow
    Gast
    So, hab das ganze in Fortran 95 umgewandelt. Am Ende ist es doch wieder ganz einfach. Nur manches sieht im ersten Moment sehr merkwürdig in Fortran aus, so dass man meint, es wäre vieles anders.
    Code:
    program determinante
    
        real, dimension(:,:),allocatable::array1	!array1 bis array4 arrays von der Größe 5 bis 2
        real, dimension(:,:),allocatable::array2
        real, dimension(:,:),allocatable::array3
        real, dimension(:,:),allocatable::array4
        integer, dimension(100)::vorzeichen			!Vorzeichen für die einzelnen Arrays
        real, dimension(100)::faktor				!Faktor für die einzelnen Arrays nach Zeilen
        real, dimension(100)::zwischenergebnis		!Zwischenergebnis der einzelnen Ebenen
        real ::det									!Zwischenergebnis der zweier Matrix
        integer :: spalte, matrix_groesse			!Größe der Matrix, spalte der zweier Matrix
    	integer :: i,j,zaehler						!Durchlaufvariablen
        character(len=10)::hilf						!Wird nur für die sichtbare Lösung aus Start der Exe-Datei benötigt
    
        zaehler=1
    	
    	! Öffnen der Eingabedatei, Einlesen und Zuweisen der Matrixgröße
    	!**************************************************************************!
    	open(10,file='Matrix.txt')
    	read(10,*) matrix_groesse
    	allocate(array1(matrix_groesse,matrix_groesse))
    
    	! Einlesen der Matrix und Schließen der Eingabedatei
    	!**************************************************************************!
    	do i=1,matrix_groesse
    		read(10,*) (array1(i,j),j=1,matrix_groesse)
    	end do
    	close(10)      
    
    !Initialisieren der arrays vorzeichen, zwischenergebnis und faktor
    	do i=1,matrix_groesse
        	vorzeichen(i)=1
            zwischenergebnis(i)=0
            faktor(i)=0
        end do
    
    !Darstellung der zu berechnenden 5er Matrix
    	print*,'Matrix ='
        do i=1,matrix_groesse
          do j=1,matrix_groesse
       		write(*,'(F12.5)',advance="no") array1(i,j)
          end do
          print*
        end do
       	print*
    
    	spalte=1
        matrix_groesse=matrix_groesse-1									!Matrixgröße wird vorbereitet auf nächsttiefere Ebene 
    
    !Benötigter Speicher der Arrays wird bereitgestellt
    	allocate(array2(matrix_groesse,matrix_groesse))						
    	allocate(array3(matrix_groesse-1,matrix_groesse-1))
    	allocate(array4(matrix_groesse-2,matrix_groesse-2))
    
    !zaehler wird um 1 erhöht (Index für die Arrays vorzeichen, Faktor und zwischensumme
    	zaehler=zaehler+1
        	do i=1, matrix_groesse+1
    			array2=laplace(array1,matrix_groesse+1,i)				!4er Matrix wird in Abhängigkeit der zu berechnenden Matrix und der aktuellen Spalte gebildet.
    			faktor(zaehler)=array1(1,i)*vorzeichen(zaehler)			!Der Faktor wird in Abhängigkeit des aktuellen Vorzeichens gebildet.
    
    !Vorbereitung für nächsttiefere Ebene 3er Matrix
       			matrix_groesse=matrix_groesse-1
                zaehler=zaehler+1
                vorzeichen(zaehler)=1	
    
        		do j=1,matrix_groesse+1
    				array3=laplace(array2,matrix_groesse+1,j)			!3er Matrix wird in Abhängigkeit der zu berechnenden Matrix und der aktuellen Spalte gebildet.
    				faktor(zaehler)=array2(1,j)*vorzeichen(zaehler)		!Der Faktor wird in Abhängigkeit des aktuellen Vorzeichens gebildet.
    
    !Vorbereitung für tiefste Ebene 2er Matrix
    	   			matrix_groesse=matrix_groesse-1
                    zaehler=zaehler+1
                    vorzeichen(zaehler)=1	
    				do spalte=1,matrix_groesse+1
        				array4=laplace(array3,matrix_groesse+1,spalte) !2er Matrix wird in Abhängigkeit der zu berechnenden Matrix und der aktuellen Spalte gebildet.
                        det=determinante_matrix_2(array4)			 	!Die Determinante der zweier Matrix wird berechnet
        				zwischenergebnis(zaehler)=zwischenergebnis(zaehler)+array3(1,spalte)*det*vorzeichen(zaehler) !zwischenergebnis aus Ergebnis der 2er Matrix mit dem aktuellen Faktor der aktuellen 3er Matrix
           				vorzeichen(zaehler)=vorzeichen(zaehler)*(-1)	!Vorzeichen anpassen 1,-1,1,-1,...
    				end do
    !Rückkehr zur nächsthöhere Ebene 3er Matrix
                    matrix_groesse=matrix_groesse+1
                    zaehler=zaehler-1
    !Berechnung des Zwischenergebnisses und auf 0 Stellung der Zwischensumme der nächsttieferen Ebene
    		    	vorzeichen(zaehler)=vorzeichen(zaehler)*(-1)
    		    	zwischenergebnis(zaehler+1)=zwischenergebnis(zaehler+1)*faktor(zaehler)
    		    	zwischenergebnis(zaehler)=zwischenergebnis(zaehler)+zwischenergebnis(zaehler+1)
    		    	zwischenergebnis(zaehler+1)=0
    			end do
    !Rückkehr zur nächsthöhere Ebene 4er Matrix
                matrix_groesse=matrix_groesse+1
                zaehler=zaehler-1
    !Berechnung des Zwischenergebnisses und auf 0 Stellung der Zwischensumme der nächsttieferen Ebene
    	    	vorzeichen(zaehler)=vorzeichen(zaehler)*(-1)
    	    	zwischenergebnis(zaehler+1)=zwischenergebnis(zaehler+1)*faktor(zaehler)
    	    	zwischenergebnis(zaehler)=zwischenergebnis(zaehler)+zwischenergebnis(zaehler+1)
    	    	zwischenergebnis(zaehler+1)=0
           end do
    
    !Freigeben des Speichers der Arrays
    	deallocate(array4)
        deallocate(array3)
    	deallocate(array2)    
    	deallocate(array1)
    
    !Ergebnisausgabe
        print*
        print*,'Determinante = ', zwischenergebnis(zaehler)
    
    !Unterbrechung damit das Programm mit sichtbaren Ergebnis auch bei Start der Exe-Datei angezeigt bleibt. Weiter mit beliebiger Eingabe und Return	
    read *, hilf
    
    contains
    !Liefert die Determinante einer 2er Matrix zurück
    function determinante_matrix_2(array)result(d)
    	real, dimension(2,2) :: array
        real ::d
    	d= (array(1,1)*array(2,2))-(array(1,2)*array(2,1))
    end function determinante_matrix_2
    
    !Reduziert eine quadratische Matrix nach dem laplaceschem Verfahren um 1 (5er Matrix zu einer 4er Matrix, 4er zu einer 3er Matrix, usw.
    function laplace(array, groesse_matrix, spalte)result(array_)
    	integer :: groesse_matrix,spalte
    	real, dimension(groesse_matrix,groesse_matrix), intent(in) :: array
       
    	real, dimension(groesse_matrix-1,groesse_matrix-1) :: array_
    
    	integer:: k,l
        integer:: i,j
    	
    	k=1
    	l=1
        
    	do i=2,groesse_matrix!beginn mit zeile 2, da zeile 1 immer die ausgewählte Zeile ist (Kann man optimieren, in dem man die  Zeile oder Spalte raussucht mit den meisten Nullen)
    		do j=1,groesse_matrix
    				if(j/=spalte) then!aktuelle spalte wird nicht berücksichtigt
    					array_(k,l)=array(i,j)
                        l=l+1
    				end if
    		end do
    		k=k+1
    		l=1
    	end do
    
    end function laplace
    
    end program determinante
    Geändert von Sergej Petrow (14.06.2015 um 21:15 Uhr)

  5. #5 Zitieren
    Sergej Petrow
    Gast
    Ich habe das ganze jetzt für eine n * n Matrix geschrieben.

    Erst habe ich das ganze in Jave geschrieben:

    Main:
    Code:
    System.out.println("Determinante = "+Double.toString(Formelsammlung.determinante(array,matrix_groesse)));
    Methoden:
    Code:
    public static double determinante(double [][] array)
    {
    	return (array[0][0]*array[1][1])-(array[0][1]*array[1][0]);
    }
    
    public static double[][] laplace(double [][] array,int groesse_matrix, int spalte)
    {
    	double [][] array_=new double[groesse_matrix-1][groesse_matrix-1];
    	int k,l;
    	
    	k=0;
    	l=0;
    	for (int i=1;i<groesse_matrix;i++)//beginn mit zeile 1, da zeile 0 immer die ausgewählte Zeile ist
    		{
    			{
    			for(int j=0;j<groesse_matrix;j++)
    				{
    				if(j!=spalte) //aktuelle spalte wird nicht berücksichtigt
    					array_[k][l++]=array[i][j];
    				}
    			}
    		k++;
    		l=0;
    		}
    	
    	return array_;
    }
    
    public static double determinante(double [][] array, int matrix_groesse)
    {
    	int vorzeichen=1;
    	double [][] array2;
    	double faktor;
    	double zwischensumme=0;
    	double endsumme=0;
    	
    	if (matrix_groesse==2) 
    		{
    		return Formelsammlung.determinante(array);
    		}
    	else
    		{
    		for (int i=0;i<matrix_groesse;i++)
    			{
    			zwischensumme=0;
    			array2=laplace(array, matrix_groesse,i);
    			faktor=array[0][i]*vorzeichen;
    			vorzeichen*=-1;
    
    			if(faktor!=0)
    				{
    				zwischensumme=faktor*determinante(array2,matrix_groesse-1);
    				}
    			
    			endsumme+=zwischensumme;
    			}
    		return endsumme;
    		}
    }
    Das funktioniert astrein.

    Dann hab ich das übersetzt in Fortran
    Code:
    program determinante
    
        double precision, dimension(:,:),allocatable::array		!Startmatrix mit groesse matrix_groesse
        integer::groesse_matrix						!Groesse der Startmatrix 
    	integer ::i,j								!schleifenvariablen
    	double precision ::ergebnis=0								!Ergebnis der Determinante für die Startmatrix
        character(len=10)::hilf						!Wird nur für die sichtbare Lösung aus Start der Exe-Datei benötigt
    
    	! Öffnen der Eingabedatei, Einlesen
    	!**************************************************************************!
    	open(10,file='vierer.txt')
    	read(10,*) groesse_matrix
    
    	! Zuweisung der Matrixgrößen, Einlesen der Matrix und Schließen der Eingabedatei
    	allocate(array(groesse_matrix,groesse_matrix))
                
    	do i=1,groesse_matrix
    		read(10,*) (array(i,j),j=1,groesse_matrix)
    	end do
    	close(10)      
    
    !Darstellung der zu berechnenden Matrix
    	print*, 'Berechnung der Determinanten von zweier bis siebener Matrix'
        print*, '==========================================================='
        print*
        print*, 'gewaehlte Matrixgroesse = ', groesse_matrix
    	print*
    	print*,'Matrix ='
        do i=1,groesse_matrix
          do j=1,groesse_matrix
    		write(*,'(F7.1)',advance="no") array(i,j)
          end do
          print*
        end do
       	print*
    
        ergebnis=determinante_laplace(array,groesse_matrix)
        
    !Freigeben des Speichers array
        deallocate(array)
    
    !Ergebnisausgabe
        print*
        print*,'Determinante = ', ergebnis
    
    !Unterbrechung damit das Programm mit sichtbaren Ergebnis auch bei Start der Exe-Datei angezeigt bleibt. Weiter mit beliebiger Eingabe und Return	
    read *, hilf
    
    contains
    !Liefert die Determinante einer 2er Matrix zurück
    function determinante_matrix_2(array)result(d)
    	double precision, dimension(2,2) :: array
        double precision ::d
    	d= (array(1,1)*array(2,2))-(array(1,2)*array(2,1))
    end function determinante_matrix_2
    
    !Reduziert eine quadratische Matrix nach dem laplaceschem Verfahren um 1 (5er Matrix zu einer 4er Matrix, 4er zu einer 3er Matrix, usw.
    function laplace(array, groesse_matrix, spalte)result(array_)
    	integer :: groesse_matrix,spalte
    	double precision, dimension(groesse_matrix,groesse_matrix), intent(in) :: array
       
    	double precision, dimension(groesse_matrix-1,groesse_matrix-1) :: array_
    
    	integer:: k,l
        integer:: i,j
    	
    	k=1
    	l=1
        
    	do i=2,groesse_matrix!beginn mit zeile 2, da zeile 1 immer die ausgewählte Zeile ist (Kann man optimieren, in dem man die  Zeile oder Spalte raussucht mit den meisten Nullen)
    		do j=1,groesse_matrix
    				if(j/=spalte) then!aktuelle spalte wird nicht berücksichtigt
    					array_(k,l)=array(i,j)
                        l=l+1
    				end if
    		end do
    		k=k+1
    		l=1
    	end do
    
    end function laplace
    
    recursive function determinante_laplace(array, groesse_matrix)result(det)
    	integer, intent(in) :: groesse_matrix	
    	double precision, dimension (groesse_matrix,groesse_matrix), intent(in) :: array
    	double precision, dimension (groesse_matrix-1,groesse_matrix-1) :: array2
        double precision :: det
    	integer,save :: vorzeichen=1
    	double precision,save :: faktor
    	double precision,save :: zwischensumme
    	double precision,save :: ergebnis=0
        double precision,save :: hilf=0
        integer::i !schleifenvariable
    
    	if (groesse_matrix==2) then
        	hilf=determinante_matrix_2(array)
        	det=hilf
    	else
    		do i=1,groesse_matrix
    			zwischensumme=0
    			array2=laplace(array, groesse_matrix,i)
    			faktor=array(1,i)*vorzeichen
    			vorzeichen=vorzeichen*(-1)
    			if(array(1,i)/=0) then
    				zwischensumme=faktor*determinante_laplace(array2,groesse_matrix-1)
    			end if	
    			ergebnis=ergebnis+zwischensumme
                print*, 'Zwischensumme = ',ergebnis
                print*
    		end do
            print*, 'Endsumme = ',ergebnis
            det=ergebnis
    	end if
    
    end function determinante_laplace
    
    end program determinante
    ... und es funktioniert gar nichts mehr. Das heißt, ich bekomme zwar ein Ergebnis raus, aber ein falsches. Für zweier und dreier matrix passt es, ab vierer passt es nicht mehr.
    Ich werde noch wahnsinnig. Das Augenmerk muss natürlich auf die rekursive Funktion gerichtet werden. Ich sehe da kein Unterschied zur rekursiven Methode in Java. Aber es passt nicht. Vielleicht mag ja jemand mit drauf schauen.

  6. #6 Zitieren
    Sergej Petrow
    Gast
    Hab das Problem gelöst.

    In der rekursiven Funktion steckt der Fehler im Detail. Ich habe Ergebnis und Vorzeichen direkt bei der Deklaration mit Werten initialisiert.
    Das darf ich wohl offensichtlich nicht. Initialisiere ich erst nach der Deklaration, klappt es.

  7. #7 Zitieren
    Mythos
    Registriert seit
    Jul 2011
    Beiträge
    8.292
    Zitat Zitat von Sergej Petrow Beitrag anzeigen
    Hab das Problem gelöst.

    In der rekursiven Funktion steckt der Fehler im Detail. Ich habe Ergebnis und Vorzeichen direkt bei der Deklaration mit Werten initialisiert.
    Das darf ich wohl offensichtlich nicht. Initialisiere ich erst nach der Deklaration, klappt es.
    Hast du auch schon raus, warum sich das so verhält?
    (Nur vorsichtshalber gefragt: Bist du nun sicher, dass die Ergebnisse immer stimmen und nicht nur zufällig?)

    Ich habe mir den Code nicht reingezogen, daher nur etwas Grundsätzliches. Was du beschreibst, könnte darauf hinweisen, dass das Problem mit den jeweiligen Speicherklassen der Variablen zu tun hat (bzw. bin ich mir ziemlich sicher):

    Die in den Methoden des Java-Beispiels deklarierten Variablen sind implizit lokal. Ich weiß nicht, wie das bei Fortran aussieht, aber es scheint zumindest so, dass sie explizit statisch deklariert wurden, was das "save" besagen könnte:
    Code:
    integer,save :: vorzeichen=1
    Unabhängig von Fortran, allgemein gesprochen:

    "Statisch" bedeutet, dass die Lebensdauer der Variablen unabhängig vom Durchlauf der Funktion ist. Sie wird genau einmal, gleich bei der Deklaration (bei den mir geläufigen Sprachen), initialisiert und kann dann immer wieder modifiziert werden, wobei sie bei jedem Funktionsaufruf stets dieselbe Variable bleibt, wie bei einer globalen Variablen.

    Deshalb wird sie nicht mit jedem Funktionausfruf auf den Initialisierungswert gesetzt, sondern genau einmal, wenn die Funktion zum ersten Mal aufgerufen wird (oder bei Programmstart, je nach Sprache, Sprachversion, Compiler).

    Sie behält ihren Wert bis zum nächsten Funktionsaufruf bei. Daran ändert sich auch nichts, wenn du sie zunächst undefiniert lässt und ihr später einen Wert zuweist. Der zuletzt zugewiesene Wert schlägt sozusagen in den nächsten Funktionsaufruf durch.

    Fingerzeig: Zuweisung ist nicht Initialisierung, aber eine Initialisierung ist auch eine Zuweisung.
    (Du hattest zunächst eine statische Variable initialisiert, nun weist du einer uninitialisierten Variablen einen Wert zu, was nicht dasselbe ist. Letzteres geschieht bei jedem einzelnen Durchlauf, ersteres genau einmal.)

    Das dürfte jedoch kein Problem sein, wenn die Variable stets mit einem neuen Wert belegt wird (was du nun gemacht hast, indem du sie zunächst undefiniert lässt und ihr später einen Wert zuweist) und bei der Abarbeitung und Abwicklung des Stacks immer nur der jeweils aktuelle Wert benötigt wird. Andernfalls hättest du jedoch einen Fehler, indem in der Umgebung des Aufrufers der Wert der Variablen durch die aufgerufene Funktion manipuliert wäre oder andersherum.

    Weil ein solcher Stil zu verborgenen Fehlern führen kann, gilt auch hier: "So lokal wie möglich, so global wie nötig". Das kannst du auch auf statische Variablen übertragen, weil sie sich etwa wie globale verhalten, mit dem Hauptunterschied, dass sie durch die Funktion gekapselt sind.
    Best practice: Globale oder statische Variablen verwendet man nur, wenn es einen guten Grund dafür gibt.

    Nebenbei: Lokale Variablen sind, wo es sich um echte Stack-Variablen handelt (bei Maschinencode bzw. kompilierten Sprachen üblich), in der Regel performanter als globale bzw. statische.

    Das Äquvialent zum Java-Code erhältst du also erst, indem du auch die jeweiligen Speicherklassen berücksichtigst, wobei das nicht immer nötig ist, aber dann müsstest du das im Einzelfall klären. Die Speicherklassen erst zu ändern, um sie dann zu korrigieren, wäre das Pferd falsch herum aufgezäumt.

    Ich hoffe, hiermit schon mal geholfen zu haben. Ich bitte um Nachsicht, dass nicht jede Formulierung sitzt, da ich jetzt schnell weg muss.
    jabu ist offline

  8. #8 Zitieren
    Sergej Petrow
    Gast
    Zitat Zitat von jabu Beitrag anzeigen
    Hast du auch schon raus, warum sich das so verhält?
    (Nur vorsichtshalber gefragt: Bist du nun sicher, dass die Ergebnisse immer stimmen und nicht nur zufällig?)
    Yep, der Fortrancompiler betrachtet es genauso, wie Du beschrieben hast. Nur beim ersten mal initialisiert, danach hat er den Wert, den er gerade hat.
    Ist bei einer Rekursion natürlich tödlich.
    http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#4

    Das Attribut Save muss oben natürlich auch überall raus. Das war nach diversen Versuchen ein weiterer verzweifelter Versuch, zu korrekten Ergebnissen zu kommen. Save macht dabei quasi das gleiche, als wenn ich in der Deklaration der Variablen auch gleichzeitig die Initialisierung vornehme.

  9. #9 Zitieren
    Mythos
    Registriert seit
    Jul 2011
    Beiträge
    8.292
    Zitat Zitat von Sergej Petrow Beitrag anzeigen
    Yep, der Fortrancompiler betrachtet es genauso, wie Du beschrieben hast. Nur beim ersten mal initialisiert, danach hat er den Wert, den er gerade hat.
    Ist bei einer Rekursion natürlich tödlich.
    http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#4
    Zitat Zitat von Siehe vorstehend zitierten Link
    A local variable that is initialized when declared has an implicit save attribute.
    Ich wusste auch nicht, dass in Fortran Initialisierung bei der Deklaration "implizit statisch" bedeutet. Das kann in der Tat überraschend sein, wenn man von einer Sprache her kommt, welche ihre Wurzeln in C hat.

    Schön, dass du uns dazu bewegst, ein wenig Fortran zu lernen.
    Von selbst wäre ich nicht darauf gekommen.

    Zitat Zitat von Sergej Petrow Beitrag anzeigen
    Das Attribut Save muss oben natürlich auch überall raus. Das war nach diversen Versuchen ein weiterer verzweifelter Versuch, zu korrekten Ergebnissen zu kommen.
    Verstehe.

    Save macht dabei quasi das gleiche, als wenn ich in der Deklaration der Variablen auch gleichzeitig die Initialisierung vornehme.
    Nur so eine Idee: Könnte vielleicht eine Stilfrage sicheren Programmierens sein, dass man sich auferlegt, das "save"-Attribut stets explizit anzugeben, sodass alle impliziten Fälle, wo es unbeabsichtigt ist, besser ins Auge fallen. Aber ob das sinnvoll ist (oder eher stört), kann man vermutlich besser beantworten, wenn man schon länger mit der Sprache vertraut ist.


    Vielleicht erlaubst du mir eine Frage, weil ich das interessant finde, zumal Fortran vergleichsweise anstrengend zu lesen ist und ein Nischendasein fristet:

    Was bewegt dich ausgerechnet zu Fortran? Nur so aus Spaß? Aus Neugier? Wegen neuer Perspektiven? Wegen irgendwelcher Vorteile? Irgendwann mal gelernt?
    jabu ist offline

  10. #10 Zitieren
    Sergej Petrow
    Gast
    Zitat Zitat von jabu Beitrag anzeigen
    Vielleicht erlaubst du mir eine Frage, weil ich das interessant finde, zumal Fortran vergleichsweise anstrengend zu lesen ist und ein Nischendasein fristet:

    Was bewegt dich ausgerechnet zu Fortran? Nur so aus Spaß? Aus Neugier? Wegen neuer Perspektiven? Wegen irgendwelcher Vorteile? Irgendwann mal gelernt?
    Vor ewig langer Zeit habe ich mal im Studium damit zu tun gehabt. Dann später musste ich in einer Firma uralten F77-Code auf Windows 98 übertragen. War auch Hardcore. Mir macht diese Sprache nicht sonderlich viel Spaß. Mittlerweile programmiere ich am liebsten in Java.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •