Pointer auf Stack



  • Guten morgen,
    ich hab hier einen Stack programmiert, der 10 Werte aufnhmen soll.

    An dieser Stelle habe ich eine Frage:
    lauf = array; //Wert auf dem Stack ablegen
    lauf hat jetzt Anfangsadresse von dem array

    Aber warum muss ich in der func push
    zuerst erhöhen:lauf++;
    und dann Wert schreiben:*lauf=zahl;
    Ich bin doch schon in der ersten freien Adresse.
    Also warum zuerst erhöhen und dann Wert schreiben.

    Wenn ich das umgekeht mach dann passen 11 Werte rein.
    Vielen Dank.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define SIZE 10
    
    int array[SIZE];
    int *grenzen, *lauf;
    
    void push(int );
    
    int main (void)
    {
    	grenzen = array;		//Grenzüberschreitungen prüfen
    	lauf = array;			//Wert auf dem Stack ablegen
    	printf("\nADRESSEN: \n");
    	printf("\nAdresse array__	%p", &array[0]);
    	printf("\nAdresse grenzen	%p", grenzen);
    	printf("\nAdresse lauf___	%p", lauf);
    	printf("\nWerte: \n");
    	printf("\nWerte array__	%d", array[0]);
    	printf("\nWerte grenzen	%d", *grenzen);
    	printf("\nWerte lauf___	%d", *lauf);
    	int eingabe;
    	printf("\nDIE GROSSE DES STACKS -> %d", SIZE);
    	do
    	{
    		printf("\nBITTE EINE ZAHL EINGEBEN: ");
    		scanf("%d", &eingabe);
    	if(eingabe!=777)
    	{
    		push(eingabe);
    	}
    	}while (eingabe!=-1);
    	return 0;
    }
    
    void push(int zahl)
    {
    	lauf++;
    	printf("\nAdresse lauf___		%p", lauf);
    	printf("\nAdresse lauf___		%d", sizeof(lauf));
    	printf("\nAdresse lgrenzen+SIZE	%p", grenzen+SIZE);
    	if(lauf==(grenzen+SIZE))
    	{
    		printf("\nStack Overflow.");
    		printf("\nAdresse lauf___		%p", lauf);
    		printf("\nAdresse lgrenzen+SIZE	%p", grenzen+SIZE);
    		exit(1);
    	}
    	*lauf=zahl;
    
    }
    


  • SeriK00 schrieb:

    Also warum zuerst erhöhen und dann Wert schreiben.

    musst du doch garnicht. probier mal so:

    void push(int zahl)
    {
      if (lauf==(array+SIZE))  // am ende angekommen?
      {
        puts ("******** overflow! **********");
        return;
      }
      printf ("[%p...%p] %p\n", array, array+SIZE, lauf);  // vorher
      *lauf++ = zahl;
      printf ("[%p...%p] %p\n", array, array+SIZE, lauf);  // nachher
    }
    

    🙂



  • Hallo fricky,

    Vielen Dank für deine Lösung.
    Jetzt würde ich gerne eine Ausgabe-Funktion schreiben die bei Eingabe von 0 den letzten Wert vom stack nimmt und diesen Wert ausgibt

    Ich glaube bei deiner Lösung muss die func push den lauf zurückliefern.
    Damit dieser der func pop übergeben werden kann um die grenzen zu prüfen und den letzten Wert auszugeben.
    Das krieg ich leider nicht hin. Bitte um Hilfe:)

    #include <stdio.h>
    #include <stdlib.h>
    
    #define SIZE 10
    
    int array[SIZE];
    int *lauf, *grenzen;
    
    void push( int );
    int pop (void);
    
    int main (void)
    {
    	lauf 	= array;
    	grenzen = array;
    	int zahl;
    	do
    	{
    		if (zahl!=0)
    		{
    		printf("\nBitte die Zahl eigeben: ");
    		scanf("\n%d", &zahl);
    		}
    		else
    		{
    			printf("\nLetzter Wert im Stack %d", pop());
    		}
    	}while (zahl!=-1);
    
    	return 0;
    }
    
    void push ( int wert )
    {
    	if(lauf==(array+SIZE))  //am Ende angekommen?
    	{
    		puts("\nOverflow!");
    		return;
    	}
    	printf("[%p.........%p] %p\n", array, array+SIZE, lauf);  		//vorher
    	(*lauf++=wert);
    	printf("[%p.........%p] %p\n", array, array+SIZE, lauf);		//nachher
    }
    
    int pop ( void )
    {
    	if (lauf==array)
    	{
    		puts("\nUnderflow");
    		return 1;
    	}
    	lauf--;
    	return *(lauf+1);
    
    }
    


  • SeriK00 schrieb:

    lauf--;
    return *(lauf+1);

    probiers mal so: *return --lauf;
    (also ohne deine zeile mit dem lauf--)
    🙂



  • Also es werden alle Werte ausgegeben und wenn die Bedingung lauf==grenzen stimmt, dann wird Underflow ausgegeben und das Prog beendet.
    Aber warum werden alle Werte ausgegeben?
    Mit return *(--lauf+1); wird doch ein Wert an main zurückgeliefert und lauf um eine Adresse verringert.
    Es muss nur das letzte Wert ausgegeben werden!
    Nur ein einziger.

    int pop ( void )
    {
    	if (lauf==grenzen)
    	{
    		puts("\nUnderflow");
    		exit(1);
    	}
    		return *(--lauf+1);
    }
    


  • ^^da wird auch nur einer ausgegeben, ist ja keine schleife oder sowas in sicht.
    warum machst du denn: **(--lauf+1)*? wozu das +1 ?



  • Hier ist nochmal das ganze Programm.
    Wenn ein Wert > 0 ist, wird dieser auf dem stack abgelegt.
    Kommt jetzt eine 0 wird der letzte Wert auf dem Stack zurückgegeben und das stack um eins verrigert.
    Deswegen
    --lauf: eins zurückgehen, da ein Wert von dem Stack durch Eingabe von 0 genommen wurde
    *(lauf+1): Aber den letzen Wert zurück geben
    Beides return *(--lauf+1);

    Eingabe:77 ->stack 1
    Eingabe: 5 ->stack 2
    Eingabe: 8 ->stack 3
    Eingabe: 0
    8 zurückliefern
    und auf stack ->2 gehen, da 8 vom stack genommen wurde und auf stack->2 sich nächster gültiger Wert befindet.
    Eingabe: 0
    5 zurückliefern und auf stack->1 zeigen usw. bis Underflow.,

    Ich hoffe ich habe mich verständlich ausgedrückt.

    #include <stdio.h>
    #include <stdlib.h>
    
    #define SIZE 10
    
    int array[SIZE];
    int *lauf, *grenzen;
    
    void push( int );
    int pop (void);
    
    int main (void)
    {
    	lauf 	= array;
    	grenzen = array;
    	int zahl;
    	do
    	{
    		if (zahl!=0)
    		{
    		printf("\nBitte die Zahl eigeben: ");
    		scanf("\n%d", &zahl);
    		push (zahl);
    		}
    		else
    		{
    			printf("\nLetzter Wert im Stack %d", pop());
    		}
    	}while (zahl!=-1);
    
    	return 0;
    }
    
    void push ( int wert )
    {
    	if(lauf==(grenzen+SIZE))  //am Ende angekommen?
    	{
    		puts("******** overflow! **********");
    		exit(1);
    	}
    	printf("[%p.........%p] %p\n", grenzen, grenzen+SIZE, lauf);  		//vorher
    	*lauf++=wert;
    	printf("[%p.........%p] %p\n", grenzen, grenzen+SIZE, lauf);		//nachher
    }
    
    int pop ( void )
    {
    	if (lauf==grenzen)
    	{
    		puts("\nUnderflow");
    		exit(1);
    	}
    		return *(--lauf+1);
    }
    


  • SeriK00 schrieb:

    Ich hoffe ich habe mich verständlich ausgedrückt.

    nö, aber probier mal das hier:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define SIZE 10
    
    int stack[SIZE];   // speicher
    int sp = 0;        // stack pointer
    
    int push (int v)
    {
      if (sp == SIZE)  // stack voll?
        return -1;     // ja
      stack[sp++] = v; // sonst speichern und weiterzaehlen
      return 0;        // hat geklappt
    }
    
    int pop (int *v)
    {
      if (sp == 0)       // stack leer?
        return -1;       // ja
      *v = stack[--sp];  // runterzaehlen und wert holen
      return 0;          // hat geklappt
    }
    
    int main (void)
    {
      // 0...SIZE werte auf den stack pushen
      int s;
      for (s=0; ; s++)
      {
        if (push(s) == -1)
          break;
        printf ("%d ", s);
      }
    
      puts("");  // new line
    
      // stack auslesen (werte erscheinen rueckwaerts)
      while (pop(&s) != -1)
        printf ("%d ", s);
    }
    

    ^^ braucht keine verrenkungen à la *(--lauf+1) und so.
    🙂



  • Vielen Dank fricky,

    was bedeutet diese Zeile den genau?

    for (s=0; ; s++)

    for ( ; ; ) ist eine Endlosschleife und mit einem ; ?



  • SeriK00 schrieb:

    Vielen Dank fricky,
    was bedeutet diese Zeile den genau?
    for (s=0; ; s++)

    das ist 'ne for-schleife ohne abbruchbedingung. da wird 's' einfach immer weitergezählt.
    🙂


Anmelden zum Antworten