Ergänzung Anweisung mit PTR

Java The Hutt

Mitglied
Hallo,

Ich habe folgende Aufgabe in C, leider habe ich keinen Lösungsansatz. Eventuell kann mir jemand sagen, wie die Lösung lautet und dazu bitte eine Erklärung hinzufügen :)


Ergänzen Sie die for – Anweisung im folgenden Programm so, dass alle 3 Parameter durch den Zeiger ptr definiert werden! Ergänzen Sie auch die anderen unvollständigen Anweisungen.

C:
#include <stdio.h>
#include <conio.h>

short abc(char *txt){ char *ptr;
for (.....................; ........................ ;......................... );
return ..................................;
}

int main() {
char txt[25] = "Hallo Welt";
int i = 0;
printf("\nIhr Text: "); 
gets(txt); 
fflush(stdin); 
printf("\n Der Text enthält %d Zeichen.", abc(txt)); 
getch()
return 0;
}
 

mihe7

Top Contributor
Ich habe folgende Aufgabe in C, leider habe ich keinen Lösungsansatz.

Code:
Zu Beginn: 

txt
|
v
Text im Speicher$
^
|
ptr

Es gilt: ptr - txt == 0

Am Ende:

txt
|
v
Text im Speicher$
                ^
                |
               ptr

Es gilt: ptr - txt == 16
Das '$' wird hier aus Gründen der Darstellung verwendet. Bei Dir wird das Ende der Zeichenkette durch eine 0 markiert.
 

Java The Hutt

Mitglied
Hmm... hier mein Lösungsansatz. Der leider nicht funktioniert...

C:
#include <stdio.h>
#include <conio.h>

char abc(char *txt)
{
    char *ptr;
    //Lösungsansatz, überlegung:
        // Pointer soll die Adresse annehmen von Txt.
        // Pointer soll maximal erhöht werden, bis er die letzte Stelle von Txt erreicht hat
    for (*ptr == *txt ; *ptr<*txt ; *ptr++  );
    printf("Ausgabe erscheint nur, wenn ein Printf hier steht")
    // Pointer - Text = Anzahl der Stellen.
    return ((*ptr) - (*txt));
}

int main()
{
    char txt[25];
    int i = 0;
    printf("\nIhr Text: ");
    gets(txt);
    fflush(stdin);
    printf("\n Der Text enthaelt %d Zeichen.", abc(txt));
    getch();
    return 0;
}
 

Java The Hutt

Mitglied
Was funktioniert nicht?

warum vergleichst du *ptr mit *txt?

Was erwartest du von der Anweisung im for?

Ich wollte die Stelle meines (Ptr) an die erste Stelle des Textes (txt) setzen.
Das ganze soll solange gehen, bis Ptr an der letzten Stelle von Txt ist.

und zurückgeben möchte ich dann den Zahlenutnerschied von Txt und meinem Pointer, sprich, die Buchstabenanzahl
 

thecain

Top Contributor
Dann musst du eine Zuweisung machen und keinen vergleich.
Dann musst du dir überlegen, wie du erkennst, wann der Text zuende ist, da du ja die Länge nicht kennst, nur den Startpointer. @mihe7 hat da ja einen guten Hinweis gegeben.
 

Java The Hutt

Mitglied
Dann musst du eine Zuweisung machen und keinen vergleich.
Dann musst du dir überlegen, wie du erkennst, wann der Text zuende ist, da du ja die Länge nicht kennst, nur den Startpointer. @mihe7 hat da ja einen guten Hinweis gegeben.

Das hatte ich eig probiert :D
Also,
C:
char *ptr = txt;
damit habe ich meinem Pointer die Speicheradresse von dem Text (txt)

C:
for (*ptr = 0; *ptr < *txt; *ptr++);
Damit versuche ich, dem Pointer den Startwert 0 zugeben. Die Schleife soll solange durchlaufen, bis Ptr die größe von txt hat. und solange Ptr um 1 erhöhen.
Damit versuche ich gedanklich, dass Txt an seiner Stelle bleibt, aber mit jedem Durchlauf bis Txt Pointer erhöht wird um die Anzahl der Buchstaben in dem Char.
C:
return ((*ptr) - (*txt));
Danach möchte ich, dass Text vom Ptr abgezogen wird, sodass ein Zahlenwert erscheint...
Aber es klappt leider nicht :(
 

Java The Hutt

Mitglied
Ich habe jetzt das ganze nochmal einfach aufgebaut.
C:
int main()
{

    int Zahl[] = {5,1,2,3,4,4,432,4,34,4,4,4,324,43,34,43,432};
    int *PtrZahl;
    PtrZahl = Zahl;
    printf("\nAnzahl Zahlen: \t\t\t\t %d",sizeof(Zahl) / sizeof(*PtrZahl));

    char buchstabe [] = {'H', 'a', 'l', 'l', '\0'};
    char * PtrBuchstabe;
    PtrBuchstabe = buchstabe;
    printf("\nAnzahl Buchstaben:\t\t\t %d",(sizeof(buchstabe)/sizeof(*PtrBuchstabe))-1);


    char zeichenkette [] = "Hallo Welt ich bin die Zeichenkette";
    char * PtrZeichenkette;
    PtrZeichenkette = zeichenkette;
    printf("\nAnzahl Zeichen der Zeichenkette: \t %d", (sizeof(zeichenkette)/sizeof(*PtrZeichenkette))-1);


}

Das klappt so soweit.

Wenn ich nun aber die Funktion übergebe und sämtliche Zählungen gleich lasse, erhalte ich nicht mehr den richtigen Wert.

C:
#include <stdio.h>
#include <stdlib.h>

char funktionzaelen(char *zeichenkette){


    char * PtrZeichenkette;
    PtrZeichenkette = zeichenkette;
    printf("\nAnzahl Zeichen der Zeichenkette: \t %d", (sizeof(zeichenkette)/sizeof(*PtrZeichenkette))-1);

}

int main()
{


    char zeichenkette [] = "Hallo Welt ich bin die Zeichenkette";
    funktionzaelen(zeichenkette);
}

Ich schließe darauf, dass es ein Problem bei der Übergabe an die Funktion gibt. Kann mir da jemand helfen?
 

mihe7

Top Contributor
@Java The Hutt in meinem "Bild" kannst Du annehmen, dass ptr der Fuß des Pfeils ist, *ptr die Pfeilspitze.

Anders formuliert: ptr speichert eine Adresse, *ptr kennzeichnet den Wert, der an dieser Adresse steht.
 

Java The Hutt

Mitglied
Bzw oder gemeinsam:D

Ich würde als erstes, den Wert festlegen den der Ptr annehmen soll:
C:
short abc(char *txt)
{
    char *ptr;
    ptr = &txt[0];

    for (; ; );
    return ;
}
 

mihe7

Top Contributor
Das sieht schon mal nicht schlecht aus.

Nachtrag: Du hast als Parameter einen Pointer, den kannst Du direkt einem anderen Pointer zuweisen.
 

Java The Hutt

Mitglied
Bevor ich die Lösung gesehen hatte, war ich soweit:
C:
short abc(char *txt)
{
    char *ptr;
    for (ptr = txt; *ptr < 25 ; (*ptr)++);
    return ptr-txt;

Daher eine Frage;
Warum != 0?

Edit:
Weil \0 das Beenden des Strings ist?
 

mihe7

Top Contributor
Daher eine Frage Fragen;
Das ist gut, dass Du Dich nicht mit der fertigen Lösung zufrieden gibst.

Stell Dir mal den Speicher als ein großes Array vor, ein Byte folgt dem nächsten. Sagen wir mal, ab Adresse 1000 stünde der Text, den Deine Funktion verarbeiten soll.

Du bekommst einen Zeiger auf diesen Text. Ein Zeiger speichert einfach eine Adresse, ganz analog zum Array-Index. Dein txt-Parameter hätte in diesem Beispiel einfach den Wert 1000.

Deine Funktion bekommt also nur die Startadresse, woher soll sie nun wissen, wo der Text endet? In C lautet die Regel für Zeichenketten, dass diese mit einer 0 terminiert werden. D. h. die Zeichenkette belegt ein Byte mehr als sie Text enthält.

Beispielhaft könnte der Speicher so belegt sein (die Spalte Zeichen dient nur der Darstellung):

Code:
Addr Wert Zeichen
1000 0x54 'T'
1001 0x65 'e'
1002 0x73 's'
1003 0x74 't'
1004 0x00
 

Java The Hutt

Mitglied
Eine weitere Frage zu einem anderen Programm:

C:
#include <stdio.h>
#include <stdlib.h>

struct dop_short
{

    short x,y;
};
struct dop_short d1;

short d2[2];

void set_struct(struct dop_short *d){
d->x = d->y = 1;
}

void set_vek(short *d2)
{
    d2[0] = d2[1] = 1;
}



int main()
{
    d1.x = d1.y = 2;
    set_struct (&d1);
    printf("\n%d \t %d", d1.x, d1.y);
    short d2[2];
    d2[0] = d2[1] = 2;
    set_vek (d2);
    printf("\n%d \t %d", d2[0], d2[1]);

}

Meine Frage, warum ruft man
C:
printf("\n%d \t %d", d1.x, d1.y);
mit dem Punkt-Zugriffsoperator auf und nicht mit dem -> Zugriffsoperator? Wenn ich den -> Zugriffsoperator nehme, bekomme ich einen Fehler. "Invalid Type Argument of "->" (have struct dop_short)
Ich habe bisher die Erfahrung gemacht, dass man Strukturen, die mit einem -> belegt werden auch so aufruft.
 

httpdigest

Top Contributor
Weil `d1` ein struct ist und kein Zeiger auf ein struct. Der Klassen/Struct-Member-Zugriffsoperator `->` kann z.B. bei `a->b` als Shortcut für den Ausdruck `(*a).b` verwendet werden.
Siehe: https://stackoverflow.com/questions/4263796/pointer-dereference-operator-vs

In der von dir gezeigten `set_struct` Funktion z.B. wird ein Pointer auf den struct übergeben, um das struct für den Aufrufer sichtbar zu verändern. Und dort wird dann entsprechend auch `->` verwendet. Genauso gut hätte aber auch: `(*d).x = (*d).y = 1` geschrieben werden können.
 

Neue Themen


Oben