Angriffszeiger in C (Teil 1)
Hinweise 101
Ich erinnere mich an das Erlernen der C-Programmierung mit meinen Kommilitonen und an die Freude, die wir empfanden, bis unser Lehrer Hinweise erwähnte. Es war eine Herausforderung, aber es hat mir Spaß gemacht, ein so wichtiges Konzept zu verstehen.
Zeiger sind wohl eines der kniffligsten Konzepte in der C-Sprache, aber sie sind unerlässlich, wenn Sie ein kompetenter C-Programmierer sein möchten. Auch wenn wir es nicht bemerken, sind in fast jedem Code, den wir schreiben, überall Zeiger vorhanden, entweder explizit oder implizit.
In diesem Artikel werden wir die verschiedenen Verwendungsszenarien für Zeiger untersuchen und uns dabei auf die häufigsten konzentrieren. Also tief durchatmen und los geht’s!
Bevor Sie diesen Beitrag lesen, stellen Sie sicher, dass Sie mit den grundlegendsten Konzepten der C-Sprache vertraut sind: Variablen und Typen, Bedingungen, Schleifen und Funktionen. In diesem ersten Teil der Serie werden wir uns mit den folgenden Konzepten befassen: Zeiger und Speicherdarstellung, Zeigerdeklarationen und Anweisungen. Adressen und Arithmetik von Zeigern, Typumwandlung und Dereferenzierungsoperator.
Das Gedächtnis des Computers
Vor langer Zeit waren Zeiger und Programmierer ein und dasselbe. Gemeinsam haben sie alles Mögliche erschaffen. Ohne ihre Partnerschaft wäre nichts entstanden. Also, was sagst du dazu … warum legen wir nicht gleich los?! Sorry, keine Langeweile
Lasst uns jetzt ernst werden!
Um Zeiger und die Operationen, die mit ihnen ausgeführt werden können, zu verstehen, müssen wir ein wenig über den Speicher des Computers lernen und darüber, wie Variablen darin lokalisiert und dargestellt werden. Computer können über viele Gigabyte Speicher verfügen. Jedes Speicherbyte hat eine eindeutige Adresse. Wir können uns den Hauptspeicher oder RAM als ein großes Array von Bytes und die Adressen als die Indizes jedes Array-Elements oder Bytes innerhalb des Arrays vorstellen. Die meisten im Array (dh im Hauptspeicher) gespeicherten Variablen sind größer als ein Byte, daher ist die Adresse jeder Variablen der Index des ersten Bytes dieser Variablen.
Oben sehen Sie die gängigen primitiven Datentypen und ihre Größen, die mit dem sizeofOperator in der C-Sprache abgerufen werden können. Ex:sizeof(int)
Der Hauptspeicher (der RAM) kann als zusammenhängendes Array von Bytes dargestellt werden. Eine Adresse entspricht einem Index im Speicherarray. Die meisten Datentypen erstrecken sich über mehrere Bytes Speicher (z. B. im ersten Bild erstreckt sich float über 4 Bytes und char über 1 Byte). Die Adresse einer Multibyte-Variablen ist die Adresse oder der Array-Index ihres ersten Bytes.
Sie können sich eine Variable als ein Haus und eine Adresse als den Schlüssel vorstellen, um auf den Inhalt des Hauses zuzugreifen. Der Inhalt des Hauses (vielleicht die Bewohner oder irgendetwas darin) kann sich ändern. Und jeder, der den Schlüssel eines Hauses besitzt, kann dessen Inhalt einsehen und ändern.
Die erste Variable ist vom Typ int, umfasst also 4 Bytes und ihre Adresse ist der Index ihres ersten Bytes (0). Das zweite ist vom Typ char (umspannt 1 Byte) und hat dann die Adresse 4, da das erste die ersten vier Bytes von 0 bis n-1 (0, 1, 2, 3) umfasst.
Hinweis: Die Adresse der Variablen im Hauptspeicher wird häufig hexadezimal geschrieben (z. B. 0xFA44dE). Wir verwenden hier ganze Zahlen (0, 1, …), um die Notation zu vereinfachen. Wenn Sie eine Variable x und eine Variable y deklarieren , d . Ihr Programm prüft, ob freie und verfügbare Adressen vorhanden sind, bevor es Ihre Variablen im Speicher speichert. Wenn also eine Adresse nicht verfügbar ist oder die Daten nicht speichern kann, liegt es in der Verantwortung Ihres Programms oder Ihres Betriebssystems (was auch immer), Ihre Variable an einer geeigneten Adresse zu speichern.
Wenn Sie in der Praxis eine Variable deklarieren und ihr einen Wert zuweisen, wird diese Variable an einer Adresse mit dem angegebenen Wert gespeichert. Sehen wir uns dieses Beispiel an:
Wenn Sie den obigen Link aus irgendeinem Grund nicht öffnen können, finden Sie hier den Code in der Sandbox:
/*
* Auth: Arsene Awounou
* File: main.c
*/
#include <stdio.h>
/**
* main - entry point
*
* Return: always 0
*/
int main(void) {
/* declare variables and initialize them*/
int a = 4;
int b = 17;
char c = 'c';
/* print the above variables */
printf("%d %d %c\n", a, b, c);
return 0;
}
Hinweise
Was ist ein Zeiger in C?
In der Programmiersprache C ist ein Zeiger eine Variable, die die Adresse einer anderen Variablen speichert. Really ? Ja, wirklich. Wissen Sie, was das bedeutet? Dies bedeutet, dass ein Zeiger die gleichen Eigenschaften wie eine normale Variable hat, jedoch mit der Besonderheit, dass er Adressen anderer Variablen speichert. Ein Zeiger wird daher durch seinen Namen, seinen Typ (den Typ der Variablen, deren Adresse er enthält) und seine eigene Adresse charakterisiert. Ja, wir haben gesagt, dass ein Zeiger auch eine Variable ist, also alle Eigenschaften einer Variablen erbt.
Wie erhalte ich die Adresse einer Variablen?
Wir haben gerade gesagt, dass Zeiger Variablenadressen speichern sollen. Daher müssen wir wissen, wie wir an diese Adressen kommen, oder? Dazu verwenden wir das kaufmännische Und- Zeichen & . Schauen Sie sich den folgenden Code an:
Wenn Sie den obigen Link aus irgendeinem Grund nicht öffnen können, finden Sie hier den Code in der Sandbox:
/*
* Auth: Arsene Awounou
* File: main.c
*/
#include <stdio.h>
/**
* main - entry point
*
* Return: always 0
*/
int main(void) {
/* declare variables and initialize them*/
int a = 4;
int b = 17;
char c = 'c';
/* print the above variables */
printf("Address of a is : %p\n", &a);
printf("Address of b is : %p\n", &b);
printf("Address of c is : %p\n", &c);
return 0;
}
Hinweis : Wenn Sie denselben Code auf Ihrem Computer ausführen, erhalten Sie möglicherweise eine andere Ausgabe . Denken Sie daran, ich habe Ihnen gesagt, dass die Adressen Ihrer Variablen von Ihrem Betriebssystem entsprechend ihrer Verfügbarkeit ausgewählt werden. Auf meinem Rechner stehen also die Adressen/Speicherorte 0x7ffcc4b574c8 , 0x7ffcc4b574c4 und 0x7ffcc4b574c3 zum Speichern meiner Variablen zur Verfügung.
Um also die Adresse einer gegebenen Variablen var zu erhalten , verwenden wir &var. Hey Alter, ja, du liest! Erinnert Sie das nicht an etwas Vertrautes? Ich bin mir ziemlich sicher, dass Sie so etwas schon einmal geschrieben haben: scanf("%d", &var);Nicht wahr?
Wir senden die Adresse der Variablen an die Funktion scanf , damit diese ihren Wert direkt ändern kann. Behalte dies im Kopf:
Eine Variable kann mit einem Haus verglichen werden und eine Adresse ist wie der Schlüssel , der den Zugriff auf den darin enthaltenen Inhalt ermöglicht. Dieser Inhalt kann sich ändern (z. B. wenn wir die Plätze der Möbel ändern oder einen neuen Anstrich machen), und jeder, der den Schlüssel besitzt, hat Zugriff und Kontrolle darüber.
Wie deklariere ich eine C-Zeigervariable?
Der allgemeine Weg, einen Zeiger zu deklarieren, ist:
datatype* pointer_name;
datatype* pointer_name;
/* or */
datatype * pointer_name;
int* test, test_1; // example 1
int * test, test_1; // example 2
int *test, test_1; // example 3
int *test, *test_1, *test_2; // and so on
Bei der Zeigerinitialisierung wird einem Zeiger die Adresse einer Variablen zugewiesen:
int a = 17;
int *pointer_to_a = &a; /* declaration + initialization */
int a = 17;
int *pointer_to_a; // declaration
pointer_to_a = &a; // initialization
char c = 'A';
int *pointer_to_c = &c; // mismatching types
Dereferenzierungsoperator *
Der Dereferenzierungsoperator , auch Indirektionsoperator genannt , in der C-Sprache mit * bezeichnet, ist ein unärer Operator (dh einer mit einem einzigen Operanden), der eine Zeigervariable enthält. Es arbeitet mit einer Zeigervariablen und gibt einen Wert zurück, der l-valuedem Wert an der Zeigeradresse entspricht. Dies wird als Dereferenzierung des Zeigers bezeichnet . Betrachten Sie zum besseren Verständnis das folgende Beispiel:
Wenn Sie den obigen Link aus irgendeinem Grund nicht öffnen können, finden Sie hier den Code in der Sandbox:
/*
* Auth: Arsene Awounou
* File: main.c
*/
#include <stdio.h>
/**
* main - entry point
*
* Return: always 0
*/
int main(void) {
int var = 17;
int *ptr = &var; // assign ptr the address of var
/* we can print the value of var in three different ways */
printf("Value of var is : %d\n", var);
printf("Value of var is : %d\n", *ptr);
printf("Value of var is : %d\n", *(&var));
/* we can print the address of var in two different ways */
printf("Address of var is : %p\n", &var);
printf("Address of var is : %p\n", ptr);
/* we can print the address of ptr in this way */
printf("Address of ptr is : %p\n", &ptr);
return 0;
}
Erläuterung :
ptrist ein Zeiger, der auf die Variable var zeigt (ptr speichert die Adresse dieser Variablen :int *ptr = &var;);- Die Ausdrücke
*ptrund bedeuten dasselbe: Sie werden verwendet, um den in der Variablen gespeicherten Wertvarabzurufen .*(&var)var
- Beim Deklarieren einer Zeigervariablen gibt * an, dass die Variable ein Zeiger ist;
- Wir können die Adresse einer Variablen mithilfe des kaufmännischen Und-Zeichens & (z. B. &var) ermitteln.
- Die Deklaration
int *ptrbedeutet, dass ptr die Adresse einer Variablen vom Typ Integer speichert (speichert einen Integer-Wert); - Um auf den Wert an einer bestimmten Adresse zuzugreifen, wird * verwendet. Und * kann als „Wert bei“ gelesen werden (*ptr bedeutet Wert bei ptr).
Um eine sichere Umgebung zu gewährleisten, ist es wichtig, Zeigervariablen einen NULL-Wert zuzuweisen, wenn Sie keine genaue Adresse haben. Dies sollte bei der Deklaration der Variablen erfolgen, um einen sogenannten Nullzeiger zu erstellen.
Der NULL-Zeiger ist eine Konstante mit dem Wert Null, die in mehreren Standardbibliotheken definiert ist.
#include <stdio.h>
int main () {
int *pointer = NULL;
printf("Value of pointer: %x\n", pointer); // 0
return 0;
}
Die Überprüfung des Vorhandenseins eines Nullzeigers kann mit einer „if“-Anweisung auf folgende Weise erfolgen:
if(pointer) /* instructions run if pointer is not null */
if(!pointer) /* instructions run if pointer is null */
Vielen Dank fürs Lesen.
Sie können mich jederzeit über Twitter , LinkedIn , WhatsApp oder Telegram erreichen .

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































