Brauche Hilfe bei Pointern



  • Furble Wurble schrieb:

    Joe1903 schrieb:

    In dieser Version bricht es ab,sobald die Eingabe lim-1 erreicht.
    Ich wollte aber,dass es weiterzählt aber nur bis lim-1 ausgibt (lim='\0')
    Es geht ja darum,die längste Eingabe widerzugeben.Ich wollte dabei einfach nicht an lim gebunden sein.

    Aha.
    Aber wie weiss getline() , bis wohin es schreiben darf, ohne lim ?

    void f(void) {
      char s[42];
      getline(s, 42); // maximal 41 Zeichen + '\0'...mehr Platz ist nicht da!
    }
    

    PS: Hast Du BBCode in Deinen Beiträgen deaktiviert? Schalt das mal wieder an.

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.



  • Joe1903 schrieb:

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.

    Also: das ist Dein Code, richtig?

    /* getline: read a line into s, return length
     */
    int getline(char *s,int lim)
    {
      int c,i,j;
      j=0;
    
      for (i=0;(c=getchar() != EOF && c != '\n');i++){
        if (j>lim-1)
          s[j++];
      }
    
      if (c == '\n'){
        if (j>lim-1)
          s[j++];
        i++;
      }
    
      s[j] = '\0';
    
      return i;
    }
    

    Was soll denn in Zeilen 9-10 und 14-16 passieren? Und was hast Du programmiert? Ich sehe überhaupt keine Zuweisungen und die Tests j>lim-1 ("größer als") sind verkehrt?

    Und allgemein verstehe ich nicht, was passieren soll? Einen String der Länge n einlesen und alle weiteren chars in der Eingabe konsumieren und verwerfen?



  • Furble Wurble schrieb:

    Joe1903 schrieb:

    Deshalb benutze ich ja i und j als Variablen (statt nur i im Original)
    Die if-Bedingung innerhalb der for-Schleife stellt sicher,dass nur solange auf s[j] geschrieben wird,solange j>lim-1 gilt.
    i zählt hierbei die eingegeben Zeichen ohne an lim gebunden zu sein.Hoffe ich konnte ich es beschreiben.

    Also: das ist Dein Code, richtig?

    /* getline: read a line into s, return length
     */
    int getline(char *s,int lim)
    {
      int c,i,j;
      j=0;
    
      for (i=0;(c=getchar() != EOF && c != '\n');i++){
        if (j>lim-1)
          s[j++];
      }
    
      if (c == '\n'){
        if (j>lim-1)
          s[j++];
        i++;
      }
    
      s[j] = '\0';
    
      return i;
    }
    

    Was soll denn in Zeilen 9-10 und 14-16 passieren? Und was hast Du programmiert? Ich sehe überhaupt keine Zuweisungen und die Tests j>lim-1 ("größer als") sind verkehrt?

    Und allgemein verstehe ich nicht, was passieren soll? Einen String der Länge n einlesen und alle weiteren chars in der Eingabe konsumieren und verwerfen?

    Sorry ja die < ist verkehrt.Also:Wenn ich im ursprünglichen Programm lim = 100 hatte (wird im Main definiert) und meine längste Eingabe z.B. 240 Zeichen hatte,gab es 2x 99 und 1x 42 aus.Und ich wollte dass es 240 ausgibt,auch wenn es den Teil nach lim verwirft.
    i zählt die Anzahl der Zeichen OHNE bei lim von vorne anzufangen.j füllt den String bis lim-1.


  • Mod

    Im ganzen Thread ist bis jetzt noch kein einziges Array aufgetaucht. Das s hier:

    int getline(char s[],int lim)
    

    Das s ist kein Array. Es ist ein Zeiger. Sieht zwar ein bisschen aus wie ein Array, weil Arrays und Zeiger eine ganz ähnliche Syntax haben, aber es ist ein Zeiger.

    Dies ist eine der wichtigsten Lektionen über C, vielleicht sogar die wichtigste, die man lernen kann. Insofern hat sich der Thread vermutlich gelohnt.



  • SeppJ schrieb:

    Im ganzen Thread ist bis jetzt noch kein einziges Array aufgetaucht. Das s hier:

    int getline(char s[],int lim)
    

    Das s ist kein Array. Es ist ein Zeiger. Sieht zwar ein bisschen aus wie ein Array, weil Arrays und Zeiger eine ganz ähnliche Syntax haben, aber es ist ein Zeiger.

    Dies ist eine der wichtigsten Lektionen über C, vielleicht sogar die wichtigste, die man lernen kann. Insofern hat sich der Thread vermutlich gelohnt.

    Auch wenn im main char s[100]; ist?



  • Wäre es nicht auch sinnvoll, das eingelesene Zeichen (im Array) abzuspeichern?



  • Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?


  • Mod

    Joe1903 schrieb:

    Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?

    Da ist kein Array!

    Joe1903 schrieb:

    Auch wenn im main char s[100]; ist?

    Ja. Dann zeigt der Zeiger eben auf ein Array. Er ist immer noch ein Zeiger. Eine Variable kann (in C) nicht einfach ihren Typ ändern, bloß weil die Funktion, in der sie steht, mit einem anderen Argument aufgerufen wird.



  • Sind im K&R nicht auch Beispiele für strcpy in Array- und Pointerschreibweise?
    ^Ich hab den gerade nicht zur Hand^



  • SeppJ schrieb:

    Joe1903 schrieb:

    Zurück zu meiner ursprünglichen Frage:
    Wie kann ich bei meinem Code Array durch Zeiger ersetzen (ohne es zu ändern)?

    Da ist kein Array!

    Um es nochmal ganz klar zu machen: in der main()-Funktion, bzw. in dem Scope, wo du das Array definierst, hast du ein waschechtes Array. Nur übergeben kannst du es nicht, stattdessen aber dessen Adresse, also einen Pointer auf das erste Element des Arrays. Wenn du nun in der Funktion, in dem du die Adresse des Arrays weiterreichst, auch die Größe brauchst, so gibst du als zweiten Parameter dessen Größe mit an. Arrays sind implizit in Pointer konvertierbar (aber nicht umgekehrt), das heißt aber nicht, dass ein Array ein Pointer ist! Einen Pointer jedoch kannst du genau so, wie einen Array benutzen, du kannst ihn subscripten (also mit [] ), du kannst ihn dereferenzieren (also mit * ).

    Aber bitte, behalte fest, dass ein Array kein Pointer ist. Er ist lediglich konvertierbar.



  • Joe1903 schrieb:

    Hallo.Ich bin neu in C und muss mich schnellstmöglich einarbeiten.

    Achso: einen wichtigen Punkt habe ich dann noch: aktivier Warnungen in Deinem Compiler, bzw. dreh das Warnlevel auf die empfindlichste Stufe hoch.



  • Hallo Joe1903,

    noch etwas detaillierter als MrDoe es beschrieben hat.
    Die beiden folgenden Zeilen sind äquivalent:

    s[i];
    *(s+i);
    

    Ebenso

    i[s];
    *(i+s);
    

    (auch wenn man dies in Produktivcode eher nicht so schreiben würde).

    char *s = "Test";
    // alternativ: char[] s = "Test"
    
    putchar(s[0]);
    putchar(*(s+1));
    putchar(2[s]);
    putchar(*(3+s));
    

    gibt wieder "Test" aus, s.a. http://ideone.com/0lGWEo



  • Th69 schrieb:

    char *s = "Test";
    // alternativ: char[] s = "Test"
    

    Unsinn. Da ist nichts alternativ. Das sind grundsätzlich unterschiedliche Definitionen.



  • Furble Wurble schrieb:

    So steht's bei K&R:

    /* getline: read a line into s, return length
     */
    int getline_kr(char s[],int lim)
    {
      int c, i;
      for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
      if (c == '\n') {
        s[i] = c;
        ++i;
      }
      s[i] = '\0';
      return i;
    }
    

    Du könntest jetzt Z. 3 ersetzen durch

    int getline_kr(char *s,int lim)
    

    und wärst fertig.

    Unsinn.

    int getline_kr(char s[],int lim)
    int getline_kr(char *s,int lim)
    

    sind in jeglicher Hinsicht identisch.



  • Th69 schrieb:

    char *s = "Test";
    // alternativ: char[] s = "Test"
    ...
    

    Einspruch! Das ist nicht das Selbe.

    Ersteres ist ein Pointer auf {'T','e','s','t','\0'}, das üblicherweise in einem schreibgeschützten Bereich gespeichert ist.
    Letzteres ist ein Array aus 5 Zeichen, das mit {'T','e','s','t','\0'} initialisiert wird und dessen Inhalt auch verändert werden kann.

    Probier doch mal:

    char *a = "Test";
    char b[] = "Test";
    
    printf ("%p %p\n", a, &a);  // unterschiedliche werte. dereferenzierung klappt
    printf ("%p %p\n", b, &b);  // 2 mal gleicher wert, dereferenzierung nicht möglich
    


  • Wutz schrieb:

    Furble Wurble schrieb:

    So steht's bei K&R:

    /* getline: read a line into s, return length
     */
    int getline_kr(char s[],int lim)
    {
      int c, i;
      for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
        s[i] = c;
      if (c == '\n') {
        s[i] = c;
        ++i;
      }
      s[i] = '\0';
      return i;
    }
    

    Du könntest jetzt Z. 3 ersetzen durch

    int getline_kr(char *s,int lim)
    

    und wärst fertig.

    Unsinn.

    int getline_kr(char s[],int lim)
    int getline_kr(char *s,int lim)
    

    sind in jeglicher Hinsicht identisch.

    So würde es für den obigen Code aussehen:

    int getline_kr(char *s,int lim)
    {
        int c;
        char *t=s;
    
        while(--lim >0 && (c=getchar())!=EOF && c!='\n')
            *s++ = c;
        if( c == '\n')
            *s++ = c;
    
        *s= '\0';
    
        return s-t;
    }
    

    Aber wie sieht es für meinen modifizierten Code aus?

    int mgetline(char s[], int lim)
    {
       int c, i, j;
       for (i=0;(c=getchar() != EOF && c!='\n'; i++)
       {
          if (j<lim-1)
             s[j++]=c;
       }
    
       if (c == '\n)
       {
          if (j<lim-1)
             s[j++]=c;
             i++;
       }
    
       s[j]='\0';
    
       return i;
    }
    

  • Mod

    Ich verstehe nicht, was du wissen möchtest. Besteht immer noch Unklarheit zu Pointern und Arrays? Wurde schon alles 3x erklärt.

    Willst du wissen, wieso dein modifizierter Code nicht funktioniert? Der compiliert nicht einmal, die Syntaxhervorhebung im Forum zeigt dir warum.



  • Meine Frage ist wie würde mein modifizierter Code mit Pointern aussehen?
    Ich krieg es nicht richtig hin und möchte wissen,wie es aussehen würde,damit ich es verstehe



  • DU NUTZT SCHON POINTER1111



  • Ich weiß aber nicht genau wie ich wie in meinem Fall mit 2 Variablen mache.Bzw. kann jemand ein Bsp geben anhand des mod. Codes?Kann jemand wenn auch nur die for-Schleife den mod. Code so schreiben wie im dem Bsp dass ich gepostet habe??


Anmelden zum Antworten