globale und lokale Variablen



  • Hallo,

    hab da ein paar Fragen zu folgendem Programm. Will ich das Programm compilieren bekomme ich einige warnings, gestartet wird es aber trotzdem. mir gehts nun nicht darum die Fehler zu beheben ich würde nur gerne wissen was an diesem Programm korrekt bis falsch ist und falls etwas falsch ist warum der Compiler so darauf reagiert. z.B. würde ich gerne wissen was passiert wenn die globale Variable i vom Typ long innerhalb der for Schleife erneut als int deklariet wird. Desweiteren würde mich interssieren warum bei a[negativer Wert] bzw a[Wert größer 100] kein Error sondern eine Zahl ausgegeben wird. Ich hab einfach mal die Zeilen die ich nicht verstehe mit ??? gekennzeichnet.

    #include <iostream>
    using namespace std;
    
       long i;
       long j;
       long ar[100];
       long k;
       long l;
       long p;
       long q;
    
    int main()
    
    {
       for (int i = 0; i < 100; i = i + 1)
          ar[i] = i + 1000;
    
       i = 16;
       j = 17;
       k = 21;
       l = 22;
       p = 23;
       q = 24;
    
       cout << "i ist " << i << endl;               // 16 ???       
       cout << "j ist " << j << endl;               // 17       
    
       cout << "ar[-3] ist " << ar[-3] << endl;     // 0  ???  
       cout << "ar[-2] ist " << ar[-2] << endl;     // 0  ???
       cout << "ar[-1] ist " << ar[-1] << endl;     // 0  ???  
       cout << "ar[0] ist " << ar[0] << endl;       // 1000    
       cout << "ar[100] ist " << ar[100] << endl;   // 21 ???   
       cout << "ar[101] ist " << ar[101] << endl;   // 22 ???   
       cout << "ar[102] ist " << ar[102] << endl;   // 23 ???  
       cout << "ar[103] ist " << ar[103] << endl;   // 24 ???   
    
       cout << "k ist " << k << endl;               // 21    
       cout << "l ist " << l << endl;               // 22   
       cout << "p ist " << p << endl;               // 23    
       cout << "q ist " << q << endl;               // 24    
    
       cin.get();
       return 0;
    }
    


  • #include <iostream>
    using namespace std;
    
       long i;
       long j;
       long ar[100];
       long k;
       long l;
       long p;
       long q;
    
    int main()
    
    {
       for (int i = 0; i < 100; i = i + 1)
          ar[i] = i + 1000;
    
       i = 16;
       j = 17;
       k = 21;
       l = 22;
       p = 23;
       q = 24;
    
       cout << "i ist " << i << endl;               // 16 ???   ... du hast i "überdeckt", sprich das lokale i verdeckt das globale
       cout << "j ist " << j << endl;               // 17      
    
       cout << "ar[-3] ist " << ar[-3] << endl;     // 0  ???   ... du greifst auf andere speicherbereiche zu, die außerhalb des arrays liegen. das ist undefiniert
       cout << "ar[-2] ist " << ar[-2] << endl;     // 0  ???   ... dito
       cout << "ar[-1] ist " << ar[-1] << endl;     // 0  ???   ... dito
       cout << "ar[0] ist " << ar[0] << endl;       // 1000    
       cout << "ar[100] ist " << ar[100] << endl;   // 21 ???   ... dito, hier bekommst du aber k, weil es direkt hinter ar liegt.
       cout << "ar[101] ist " << ar[101] << endl;   // 22 ???   ... hier bekommst du l
       cout << "ar[102] ist " << ar[102] << endl;   // 23 ???   ... p
       cout << "ar[103] ist " << ar[103] << endl;   // 24 ???   ... q
    
       cout << "k ist " << k << endl;               // 21    
       cout << "l ist " << l << endl;               // 22  
       cout << "p ist " << p << endl;               // 23    
       cout << "q ist " << q << endl;               // 24    
    
       cin.get();
       return 0;
    }
    
    //Sonst dürfte alles klar sein, oder?
    


  • Der Gültigkeitsbereich einer Variable (oder wenn man will: Ihres Namens) ist nicht vom Typ abhängig. Es macht im Verhalten keinen unterschied ob man eine globale long und eine lokale int variable mit dem selben namen hat, oder ob beide int sind. In jedem fall hat die Lokale Variable vorrang. Das bedeutet wenn du in der Funktion / Schleife was auch immer auf i zugreifst dann benutzt du die lokale Variable. Du kannst aber über den scope operator (::) auch auf die Globale Variable zugreifen wenn eine lokale Variable mir selben Namen existiert (::i).

    Was die arrays angeht: Normal müsste dein Programm mit nem Laufzeitfehler abbrechen... vielleicht korrigiert der compiler da aber auch irgendwas. Versuch mal ne variable mit negativem oder zu hohem Wert in die eckigen Kammmern zu schreiben und schau was passiert ^^

    int x = -5;
    cout << ar[x] << endl;
    


  • Vielen Dank das war genau das was ich wissen wollte

    bis dann



  • Man kann nicht davon ausgehen, daß der Compiler die Variablen in der gleichen Reihenfolge anordnet, wie man sie hinschreibt.



  • Warner schrieb:

    Man kann nicht davon ausgehen, daß der Compiler die Variablen in der gleichen Reihenfolge anordnet, wie man sie hinschreibt.

    AFAIK doch. Die werden genau so auf dem Stack angelegt, es sei denn, sie werden wegoptimiert.



  • Lars Hupel schrieb:

    cout << "i ist " << i << endl;   // 16 ???   ... du hast i "überdeckt", sprich das lokale i verdeckt das globale
    

    Bist du Dir an dieser Stelle sicher, das er auf das lokale i zugreift?
    Eventuell ist es ja Compilerabhängig aber soweit ich weiß ist der Gültigkeitsraum von int i nach der for-Schleife zu Ende, und damit greift er auf das globale long i zu.

    Bsp:

    void a_function()
    {
        for(int i=0; i<10;i++)
            i++;
        ShowMessage(i);   //Fehlermeldung undefiniertes Symbol i
    }
    

    Bei mir mit dem BCB6 kommt diese Fehlermeldung, ich glaube mich aber zu erinnern, daß das Bsp. bei VC++ so funktionieren sollte.

    Gruß Alex



  • schliesse mich Alex an. meines wissens ist das lokale int nur in der forschleife gültig. und dort wird das globale durch das lokale "überdeckt"



  • Alex_H schrieb:

    Lars Hupel schrieb:

    cout << "i ist " << i << endl;               // 16 ???   ... du hast i "überdeckt", sprich das lokale i verdeckt das globale
    

    Bist du Dir an dieser Stelle sicher, das er auf das lokale i zugreift?
    Eventuell ist es ja Compilerabhängig aber soweit ich weiß ist der Gültigkeitsraum von int i nach der for-Schleife zu Ende, und damit greift er auf das globale long i zu.

    Bsp:

    void a_function()
    {
        for(int i=0; i<10;i++)
            i++;
        ShowMessage(i);   //Fehlermeldung undefiniertes Symbol i
    }
    

    Bei mir mit dem BCB6 kommt diese Fehlermeldung, ich glaube mich aber zu erinnern, daß das Bsp. bei VC++ so funktionieren sollte.

    Gruß Alex

    Es funktioniert beim VC++ 6. 'i' ist hier aber, wie schon gesagt, lokal zum
    for-Body. Ausserhalb der for-Schleife kann nicht auf diese Variable zugegriffen
    werden.

    mfg
    v R



  • virtuell Realisticer schrieb:

    [Ausserhalb der for-Schleife kann nicht auf diese Variable zugegriffenwerden.

    😕
    Ist 'i' an dieser Stelle nicht schon außerhalb der for-Schleife? Irgendwie kann ich Dir da nicht folgen. Ich verstehe ja, das VC++ den Lebensbereich auf die ganze Funktion erweitert und damit das lokale 'i' anspricht, aber irgendwie wiederspricht dein Satz dem Rest oder habe ich irgendwas falsch verstanden?

    Gruß Alex



  • Alex_H schrieb:

    virtuell Realisticer schrieb:

    [Ausserhalb der for-Schleife kann nicht auf diese Variable zugegriffenwerden.

    😕
    Ist 'i' an dieser Stelle nicht schon außerhalb der for-Schleife?

    Wenn du dich auf deinen letzten Code beziehst:

    void a_function()
    {
        for(int i=0; i<10;i++)
            i++; //lokal zum for-rumpf
        ShowMessage(i);   //lokal zum funktionsrumpf -> fehler: i nicht deklariert
    }
    

    mfg
    v R



  • Danke,
    schlussendlich habe ichs auch verstanden, also läuft mein Bsp bei VC++ jedoch das hier nicht mehr.

    void a_function (){
    	if(true){
    		for(int i=0;i<10;i++)
    			i++;
    	}
    	cout<<i<<endl;
    }
    

    Wie sieht das eigentlich aus, wer ist da jetzt zum standard konform der BCB6 oder VC++?
    Ich tendiere eher zum BCB aber vielleicht bin ich auch voreingenommen?

    Gruß Alex



  • Tag,

    der VC++ _6_ verhaelt sich hier nicht korrekt. Bei den neuen Versionen ist das,
    afair, nicht mehr so.

    mfg
    v R



  • Variablen sollten, zwar mit kleinst moeglichem Scope deklariert werden aber meiner Meinung nach nicht in Schleifen(-koepfen).



  • PunI$0R schrieb:

    Variablen sollten, zwar mit kleinst moeglichem Scope deklariert werden aber meiner Meinung nach nicht in Schleifen(-koepfen).

    Das ist bloedsinn. Wenn ich 'i' ausserhalb der Schleife nicht benoetige, dann
    brauch ich 'i' auch nicht in dem aeusseren Scope.

    mfg
    v R



  • zu PunI$0R
    Kannst Du das auch begründen, ich sehe keinen Grund das nicht zu tun, wenn ich die Variable nur innerhalb der Schleife benötige, warum dann nicht im Schleifenkopf deklarieren, dazu ist die erste Position in der for-Schleife doch da, zum deklarieren und initialisieren.

    Gruß Alex

    Edit:virtuell Realisticer war da wohl schneller, dafür war meine Antwort diplomatischer.



  • Stimmt wohl, aber wenn ihr doch hier schon ueber unteschiedliches Verhalten von Kompilern und so disskutiert, dann wisst ihr ja schon den Hauptgrund. Man kann nicht immer genau sagen wie diese im Schleifenkopf deklarierten Variablen behandelt werden. Also ich versuche meinen Quellcode sicher, schnell und kompatibel zu schreiben. Das erreicht man nicht durch solch(meiner Meinung nach) seltsame Konstrukte. Dann doch lieber ein paar Zeilen mehr als undefiniertes Verhalten. Denk mal drueber nach..



  • PunI$0R schrieb:

    Stimmt wohl, aber wenn ihr doch hier schon ueber unteschiedliches Verhalten von Kompilern und so disskutiert, dann wisst ihr ja schon den Hauptgrund. Man kann nicht immer genau sagen wie diese im Schleifenkopf deklarierten Variablen behandelt werden. Also ich versuche meinen Quellcode sicher, schnell und kompatibel zu schreiben. Das erreicht man nicht durch solch(meiner Meinung nach) seltsame Konstrukte. Dann doch lieber ein paar Zeilen mehr als undefiniertes Verhalten. Denk mal drueber nach..

    Da braucht man nicht drueber nachzudenken. Es gibt kein UB. Der VC++ 6 laesst
    es nunmal zu, ok. Jeder andere Compiler quitiert dir das mit einer Fehlermeldung,
    so einfach ist das.

    mfg
    v R



  • Das Default-Verhalten vom VC ist in der Tat nicht Standard-Konform, kann aber
    per Kommandozeilen-Parameter konfiguriert werden.



  • Tja wer so programmieren will kann das gern tun, ich werde es auf keinen Fall machen, nicht fuer eine Zeile Code. Code von Leuten die in Schleifenkoepfen Variablen deklarieren, den ich gesehn hab, die haben auch sonst gut Scheisse gemacht und alles fuer due Unportierbarkeit und Inkompatibilitaet ihres programms getan. Ich kann so was nicht nachvollziehen.



  • PunI$0R schrieb:

    Tja wer so programmieren will kann das gern tun, ich werde es auf keinen Fall machen, nicht fuer eine Zeile Code. Code von Leuten die in Schleifenkoepfen Variablen deklarieren, den ich gesehn hab, die haben auch sonst gut Scheisse gemacht und alles fuer due Unportierbarkeit und Inkompatibilitaet ihres programms getan. Ich kann so was nicht nachvollziehen.

    Das eine hat mit dem anderen gar nichts zu tun.

    mfg
    v R


Anmelden zum Antworten