Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

hallo habe ne frage;

also wieso erwartet die funktion scanf Zeiger auf die einzulesenden Daten,

und

wieso nimmt die Funktion printf die auszugebenden daten direkt entgegen.

  • Antworten 54
  • Ansichten 7.4k
  • Erstellt
  • Letzte Antwort

Top-Poster in diesem Thema

Beispiel:


#include <stdio.h>


int main()

{

	int* i;

	scanf("%d",&i);

	printf("%d",i);

	return 0;

}

int* i ist vom Typ Zeiger auf Int. Das heißt, daß was an der Speicherstelle von i steht kann einen Integer Wert aufnehmen. Bei 32 Bit Systemen werden hier 4 Byte für den Pointer reserviert. scanf hat "const char* format" und weitere Argumente. In diesem Fall die Adresse von dem Zeiger, der auf einen Integer Wert zeigt. D.h. der Funktion wird mitgeteilt, an welche Speicherstelle sie die Eingabe speichern soll. In diesem Fall erwartet die Funktion als Eingabe einen Integer Wert. Zwischenbeispiel:

int i = 5;

int* pi = &i;

Hier zeigt pi auf die Adresse von i.

Noch eine Anmerkung zu "const char* format":

In C gibt es keine Strings. Ein Stringliteral wie z.b. "Hallo Welt" wird als array of char bezeichnet. man könnte sagen:

char* s = "Hallo Welt";

hierbei Zeigt der Zeiger auf das erste Element des Stringliterals.

Generell schau mal unter:

Galileo Computing :: C von A bis Z – 5 Formatierte Eingabe mit scanf()

Bleib am Ball.

In C werden Funktionsparameter "by value" übergeben, d.h. die Funktion bekommt eine Kopie des Wertes, der beim Aufruf übergeben wurde (Ausnahme: Arrays). Änderungen an dieser Kopie ändern natürlich nichts an der Originalvariablen. Damit eine Funktion wie scanf also überhaupt etwas tun kann, muss ein Verweis übergeben werden, über den die Originalvariable erreichbar ist. Und die einzige Möglichkeit in C, das zu tun, ist ein Zeiger.

hmm ok danke,

und warum nimmt die funktion printf die auszugebenden daten direkt entgegen???

jetzt im allgemeinen fall

hmm ok danke, habe noch eine frage:

ich habe ein ausschnitt aus einem c-programm:

01 char *str1, *str4 = 0;

02 char str2 [] = "t2";

03 char *str3 [2] = {" Element_0" , "Element_1" };

04 str1 = malloc (5);

05 str3 [0] = str1;

06 strcpy ( str1, "test1");

07 strcpy (str1, str2);

08 strcpy (str3[0], "test3");

09 strcpy (str4, str2);

also ich soll jetzt die programmzeilen nennen, in denen auf ungültige speicher zugegriffen wird, und genau beschreiben, weshalb die zugriffe unzulässig sind.

nur ich weiss jetzt nicht wie ich das merke, gibt es da bestimmte regel oder so würde mich auf eine antwort freuen, da ich erst neu anfange zu programmieren und nicht weiss wie das so funktioniert.

Folgende Operationen sind verboten, weil sie undefiniertes Verhalten erzeugen:

  • Jegliche Zugriffe über uninitialisierte Zeiger
  • Jegliche Zugriffe über Nullzeiger
  • Schreibzugriffe auf Stringliterale
  • Jegliche Zugriffe über den alloziierten Speicherbereich hinaus (Buffer Overflow)

hmm,

und wie könnte ich das auf den obrigen abschnitt anwenden.

Schreib auf, wohin die einzelnen Zeiger zeigen, also unintialisiert, NULL, Literal (mit Größe) oder gültiger Speicher (mit Größe), und prüfe Zeile für Zeile, was die Anweisungen tun.

Beispiel :

Zeile 1: str1 ist uninitialisiert, str4 ist NULL

Zeile 2: str2 ist ein Array auf dem Stack, Größe 3

usw.

also ich habe da mal was versucht, aber weiss net ob es richtig ist:

also ab zeile 3:

03 str3 ist ein Array und ist gleichzeitig Element von 0 und 1

04 str1 reserviert einen Speicherplatz

05 str3 ist ein Array und gleichzeitig str1

06 str1 kopiert eine Zeichenkette zu test1

07 str1 und str2 kopieren zeichenketten

08 str3 ist ein Nullelement

09 str4 kopiert eine zeichenkezze zu str 2

Du musst da schon ein wenig genauer arbeiten:

03 str3 ist ein Array und ist gleichzeitig Element von 0 und 1
str3 ist ein Array von 2 Zeigern, str3[0] und str3[1]. str3[0] zeigt auf ein Literal der Länge 11, str3[1] auf ein Literal der Länge 10.

04 str1 reserviert einen Speicherplatz
str1 zeigt auf gültigen Speicher der Länge 5.

05 str3 ist ein Array und gleichzeitig str1

str3[0] zeigt nicht mehr auf Literal, sondern auf denselben gültigen Speicherbereich wie str1.

usw.

okii,

aber bei strcpy war ich mir gar nicht sicher und weiss irgendwie auch nicht wie ich das audführlich bearbeiten soll :-(

ne ich weiss jetzt irgendwie noch nicht welche zeilen auf ungültige speicher zugreifen

ne ich weiss jetzt irgendwie noch nicht welche zeilen auf ungültige speicher zugreifen

Kannst du bitte auf das Wort "irgendwie" verzichten?

Du kannst nicht "wissen", welche Zeilen ungültig sind, ohne genau herauszuarbeiten, welcher Zeiger wohin zeigt, und was wohin kopiert wird.

Wenn du das "irgendwie" nicht kannst, können wir dir hier auch nicht helfen. Du musst schon konkret erklären, womit du Probleme hast.

ja also ich muss ja zunächst schreiben wo die zeiger hin zeigen.

bei strcpy

weiss ich jetzt noch nicht genau wo die zeiger hin zeigen, ich weiss das

die funktion strcpy eine zeichenkette kopiert.

jetzt in den zeilen von 06-09

06 es wird eine Zeichenkette von str1 in test1 kopiert

07 str1 kopiert ihre zeichenkette in str2

08 str3 kopiert ihr Nullelement in test3

09 str4 kopiert ihre zeichenkette in str 2

ich weiss jetzt nicht wie ich das anders beschreiben soll

bei strcpy

weiss ich jetzt noch nicht genau wo die zeiger hin zeigen,

strcpy ändert nichts daran, wo die Zeiger hinzeigen.

06 es wird eine Zeichenkette von str1 in test1 kopiert
Nein, der erste Parameter von strcpy ist das Ziel, der zweite ist die Quelle.

Bei strcpy musst du prüfen:

  • ob der Quellzeiger auf Speicher zeigt, aus dem gelesen werden darf,
  • ob dieser Speicher einen terminierten String enhält,
  • ob das Ziel auf Speicher zeigt, in den geschrieben werden darf, und
  • ob dieser Speicher groß genug für den String (mit Terminierung) ist.

Mach das mal für Zeile 6.

also

06 str1 zeigt auf speicher test 1, indem geschrieben werden darf

06 str1 zeigt auf speicher test 1, indem geschrieben werden darf

Ich sagte doch, dass strcpy nichts daran ändert, wohin die Zeiger zeigen. Quelle und Ziel zeigen dahin, wo sie vorher auch hingezeigt haben.

Du sollst die vier Dinge prüfen, die ich da hingeschrieben habe. Das kannst du nicht in einem Satz abhandeln.

06:

dieser speicher enthält einen terminierten string

der ziel zeigt auch auf den speicher, in den geschrieben werden darf

und speicher ist groß genug

dieser speicher enthält einen terminierten string

der ziel zeigt auch auf den speicher, in den geschrieben werden darf

und speicher ist groß genug

Nicht ganz.

Die Quelle ist "test1", das ist ein Literal der Länge 6, denn die Terminierung muss man mitzählen. Die wird von strcpy auch mit kopiert.

Die Quelle ist also soweit in Ordnung. In das Ziel darf auch geschrieben werden, aber nur 5 Bytes. Dies ist also die erste Zeile mit ungültigem Zugriff.

ok,

jetzt mit 07:

also ich denke das hier die 4 bedingungen erfüllt sind, und der zugriff gültig ist

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.