C: fifo lesen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Meillo
Moderator
Beiträge: 5053
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: C: fifo lesen

Beitrag von Meillo » 22.08.2018 15:21:38

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
22.08.2018 13:44:13
Dann habe ich auf Deine Anregung noch gefunden: http://marmaro.de/docs/studium/unix-phil/unix-phil.pdf
Das meintest Du doch, oder?
... und das: http://marmaro.de/docs/chaosseminar/

Und textuell noch das: http://marmaro.de/docs/master/schnalke-mmh.pdf ... falls du dir das geben willst. ;-)
Use ed(1) once in a while!

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 22.08.2018 15:46:39

Oh, da hast Du ja ganz schön viel zu dem Thema verfasst. :THX:

Übrigens, die Videos in dem Link http://ulm.ccc.de/ChaosSeminar/2010/03_UnixPhil gibt's nicht mehr...

BTW - nochmal zu meinen shell-builtins: Damit kein falscher Eindruck entsteht, wollte ich nochmal erwähnen, dass die nur in bestimmten Fällen Performance-Vorteile bringen. Die Datei /proc/net/wireless z.B. ist drei Zeilen lang. Wenn ich jetzt aber z.B. die Namen aller Dateien in /usr/share/applications/ möchte, die "NoDisplay=true" beinhalten, lande ich mit builtins von der Performance her auf der Nase und nehme grep. Insofern sind die Unix-Tools im Allgemeinen schon auch von der Performance her zu bevorzugen, denn wenn sie auch bei kleinen Datenmengen ein klein wenig langsamer sein mögen, so sieht es bei größeren Datenmengen um Gößenordnungen anders aus.

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 22.08.2018 21:26:39

Uff, signal handling geschafft... :D

Erst wollte ich einfach zusätzlich noch auf stdin lauschen - mit select geht das ja. Doch nachdem ich das implementiert hatte, habe ich gemerkt und ist mir wieder eingefallen, dass man nicht nach stdin eines im Terminal laufenden Processes mittels "echo /proc/pid/fd/0" pipen kann, weil diese fds immer zu denen des jeweiligen /dev/pts umgeleitet sind... :evil:
Aber eigentlich scheint es mir so jetzt auch eleganter. Ich nutze sigaction und etabliere vor dem loop eine Aktion, die beim Empfangen von SIGTERM (also "kill -15 pid") ausgeführt wird. Diese Aktion ist einfach das Umschalten einer toggle-Variable (ich mag toggle-Variablen :D ), auf deren Ursprungszustand der while-loop basiert. Wird sie also umgeschaltet, beendet sich der loop und dann werden die unter dem Loop stehenden Aufräumarbeiten ausgeführt. Man kann den Vorgang mit eingeschobenen printfs verifizieren.
(Das einzig Doofe ist, dass man die Variable signum benutzen muss, weil sich sonst gcc beklagt...)

Das kommt dann also bei "kill -15" heraus:

Code: Alles auswählen

/opt/scripts/dev$ ./test2xd
Hello, I am the signal handler.
Hello, I am the end of the main function.
Der Code mit den Test-printfs:

Code: Alles auswählen

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

static const char program_name[] = "test2xd";
static Display *dpy;
static int screen;
static Window root;
static XEvent ev;
static int finish;

static void
term_hdl (int signum)
{
	/* we have to use signum */
	switch (signum) {
		case SIGTERM:
			printf("Hello, I am the signal handler.\n");
			finish = 1;
	}
}

int
main(void) 
{
	char *display_name = NULL;
	char name[BUFSIZ];
	int fd;
	struct sigaction term_act;
	
	memset(&term_act, 0, sizeof(term_act));

	dpy = XOpenDisplay(display_name);
	if (dpy == '\0') {
		fprintf(stderr, "%s:  unable to open display '%s'\n",
				program_name, XDisplayName (display_name));
		exit(2);
	}
	root = RootWindow(dpy, screen);

	/* fd = open("/tmp/dwmblocks_fifo_intern", O_RDWR | O_NONBLOCK); */
	fd = open("/home/user/fifo", O_RDWR | O_NONBLOCK);
	if (fd < 0) {
		perror("open");
		exit(1);
	}

	term_act.sa_handler = term_hdl;
	if (sigaction(SIGTERM, &term_act, NULL) < 0) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	fd_set rfds;
	int rc;

	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);

	while (finish == 0) {
		rc = select(fd + 1, &rfds, NULL, NULL, NULL);
		if (rc > 0) {
			memset(name, 0, sizeof(name)-1);
			ssize_t got = read(fd, name, sizeof(name)-1);
			if (got < 0) {
				perror("read");
				break;
			} else if (got == 0) {
				printf("EOF\\n");
				break;
			}
			else {
				/* remove trailing newline */
				if (name[strlen(name)-1] == '\n')
					name[strlen(name)-1] = '\0';
				XStoreName(dpy, root, name);
				while (XPending(dpy))
					XNextEvent(dpy, &ev);
			}
		}
	}
	/* will never get here */
	close(fd);
	XCloseDisplay(dpy);
	printf("Hello, I am the end of the main function.\n");

	exit(EXIT_SUCCESS);
}
Wie findet ihr das? Jetzt könnte ich doch das Programm mittels "kill -15 pid" aus dem Parent-Wrapper-Script heraus auf jeden Fall sauber beenden.

Benutzeravatar
bluestar
Beiträge: 626
Registriert: 26.10.2004 11:16:34
Wohnort: Rhein-Main-Gebiet

Re: C: fifo lesen

Beitrag von bluestar » 22.08.2018 21:34:26

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
22.08.2018 21:26:39

Code: Alles auswählen

...
			memset(name, 0, sizeof(name)-1);
			ssize_t got = read(fd, name, sizeof(name)-1);
...
Ich muss wohl doch noch mal schimpfen :mrgreen:

1) Wenn du read(...) nutzt dann

Code: Alles auswählen

memset(name, 0, sizeof(name));                       // KEIN -1 bei der Länge
ssize_t got = read(fd, name, sizeof(name)-1);    // EIN -1 bei der Länge wobei besser im Sinne von UTF-8 wäre:  sizeof(name) - sizeof(char)
2) Wenn du fgets(...) nutzt dann

Code: Alles auswählen

memset(name, 0, sizeof(name));                     // KEIN -1 bei der Länge
ssize_t got = fgets(name, sizeof(name),fp);    // KEIN -1 bei der Länge
fgets weiß ja, das du einen String in dem Puffer haben willst, also liest es MAX (num -1) Bytes aus dem Fifo uns hängt ein \0 hinten dran....

*WINKS*

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 22.08.2018 22:15:32

Ohje! :facepalm: :oops:
Vielen Dank für Deine Geduld, @bluestar! Manchmal muss ich einfach noch konzentrierter sein...

Ich habe es korrigiert (und dabei noch das sigaction an die richtige Stelle in main() gesetzt und den letzten comment entfernt, der nicht mehr gültig ist).

Code: Alles auswählen

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

static const char program_name[] = "test2xd";
static Display *dpy;
static int screen;
static Window root;
static XEvent ev;
static int finish;

static void
term_hdl (int signum)
{
	/* we have to use signum */
	switch (signum) {
		case SIGTERM:
			printf("Hello, I am the signal handler.\n");
			finish = 1;
	}
}

int
main(void) 
{
	char *display_name = NULL;
	char name[BUFSIZ];
	int fd;
	struct sigaction term_act;
	
	memset(&term_act, 0, sizeof(term_act));
	term_act.sa_handler = term_hdl;
	if (sigaction(SIGTERM, &term_act, NULL) < 0) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	dpy = XOpenDisplay(display_name);
	if (dpy == '\0') {
		fprintf(stderr, "%s:  unable to open display '%s'\n",
				program_name, XDisplayName (display_name));
		exit(2);
	}
	root = RootWindow(dpy, screen);

	/* fd = open("/tmp/dwmblocks_fifo_intern", O_RDWR | O_NONBLOCK); */
	fd = open("/home/user/fifo", O_RDWR | O_NONBLOCK);
	if (fd < 0) {
		perror("open");
		exit(1);
	}

	fd_set rfds;
	int rc;

	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);

	while (finish == 0) {
		rc = select(fd + 1, &rfds, NULL, NULL, NULL);
		if (rc > 0) {
			memset(name, 0, sizeof(name));
			ssize_t got = read(fd, name, sizeof(name)-sizeof(char));
			if (got < 0) {
				perror("read");
				break;
			} else if (got == 0) {
				printf("EOF\\n");
				break;
			}
			else {
				/* remove trailing newline */
				if (name[strlen(name)-1] == '\n')
					name[strlen(name)-1] = '\0';
				XStoreName(dpy, root, name);
				while (XPending(dpy))
					XNextEvent(dpy, &ev);
			}
		}
	}
	close(fd);
	XCloseDisplay(dpy);
	printf("Hello, I am the end of the main function.\n");

	exit(EXIT_SUCCESS);
}
Was meint ihr übrigens zu dem neuen dpy-Test?
Also statt "if (!dpy)" "if (dpy == '\0')"? Ich habe noch auf der Suckless-Seite zusätzliche Links zu Coding-Style gesehen und in einem steht:
Don't use ‘!’ for tests unless it's a boolean [...]
Quelle: https://man.openbsd.org/style
Schien mir irgendwie Sinn zu ergeben.

Benutzeravatar
Meillo
Moderator
Beiträge: 5053
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: C: fifo lesen

Beitrag von Meillo » 22.08.2018 23:34:31

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
22.08.2018 22:15:32
Was meint ihr übrigens zu dem neuen dpy-Test?
Also statt "if (!dpy)" "if (dpy == '\0')"?
Das ist leider falscher. ;-)

XOpenDisplay(3) liefert einen Pointer zurueck und ...
Manpage XOpenDisplay(3) hat geschrieben: If XOpenDisplay does not succeed, it returns NULL.
Logisch korrekt ist also ``if (dpy == NULL)''. (Ich persoenlich finde ``if (!dpy)'' aber besser, weil mehr Signal und weniger Noise und damit direkter, treffender und lesbarer ... aber ich weiss, dass in dem Punkt viele da ``== NULL'' bevorzugen.)

In der Praxis laeuft's auf's gleiche hinaus, trotzdem sollte man NULL, 0 und '\0' voneinander unterscheiden und stets das Passende verwenden.

Ich habe noch auf der Suckless-Seite zusätzliche Links zu Coding-Style gesehen und in einem steht:
Don't use ‘!’ for tests unless it's a boolean [...]
Quelle: https://man.openbsd.org/style
Schien mir irgendwie Sinn zu ergeben.
Das hat durchaus seine Logik und einen Sinn. Ich selber verwende trotzdem `!' auch in anderen Situationen, immer wenn es mir so lesbarer erscheint. Bloss bei strcmp(3) verwende ich `!' nie und das aus starker Ueberzeugung: Es fuehrt einfach zu zu vielen Verstaendnisproblemen! Auch bei fork(2) halte ich `!' fuer nie sinnvoll. Insofern kann man schon sagen, dass man es nur fuer booleanartige Ausdruecke verwenden sollte. Es muss nicht nur 1 und 0 sein, es koennen schon auch viele verschiedene Werte zurueckgegeben werden (z.B. bei fopen(3)), aber wenn ich dort pruefe, ob der Aufruf fehlerhaft war, dann pruefe ich mit `!', weil ich etwas booleanartiges wissen will. Ich wuerde also sagen, dass man `!' nur verwenden sollte, wenn man eine booleanartige Pruefung macht (egal welcher Art die Daten sind).

Bei strcmp(3) macht das `!' IMO keinen Sinn, weil was soll ``if not string-compare'' bitte bedeuten? (``if not fopen'' macht dagegen viel Sinn.)

Bei fork(2) macht die Pruefung mit `!' auch keinen Sinn, weil ``!fork()'' bedeutet, dass man das Kind ist.

Entscheidend ist die Sinnhaftigkeit und das Verstaendnis beim Codeleser. Solange du dir nicht sicher bist, dass du gute Gruende hast, es auf eine bestimmte Art zu machen -- als Anfaenger hast du die fast nie --, dann mach es so wie die (guten) Styleguides es empfehlen.
Use ed(1) once in a while!

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 23.08.2018 12:55:20

Oh, alles klar, vielen Dank, @meillo! Mit dem Unterschied zwischen Null, 0 und '\0' sollte ich mich wohl mal beschäftigen...

Eigentlich sollte man ja alle Variablen in der entsprechenden Funktion deklarieren, wenn sie nicht funktionsübergreifend genutzt werden, richtig?
Und nach den breaks des loops bzw. nach einem gescheiterten open() wäre ja auch Aufräumen angesagt...

Habe das mal versucht:

Code: Alles auswählen

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <X11/Xlib.h>

/* BEGIN: user configuration */
static const char program_name[] = "test2xd";
/* static const char fifo[] = "/tmp/dwmblocks_fifo_intern"; */
static const char fifo[] = "/home/user/fifo";
/* END: user configuration */

static int finish;

static void
term_hdl (int signum)
{
	/* if we do not use signum, gcc complains */
	if (signum == SIGTERM)
		finish = 1;
}

int
main(void)
{
	char *display_name = NULL;
	char name[BUFSIZ];

	int fd;
	int rc;
	static int screen;
	int state = EXIT_SUCCESS;
	static Window root;

	static Display *dpy;
	struct sigaction term_act;
	static XEvent ev;

	fd_set rfds; /* fixed size buffer */
	
	memset(&term_act, 0, sizeof(term_act));
	term_act.sa_handler = term_hdl;
	if (sigaction(SIGTERM, &term_act, NULL) < 0) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	dpy = XOpenDisplay(display_name);
	if (dpy == NULL) {
		fprintf(stderr, "%s:  unable to open display '%s'\n",
				program_name, XDisplayName(display_name));
		exit(EXIT_FAILURE);
	}
	root = RootWindow(dpy, screen);

	fd = open(fifo, O_RDWR | O_NONBLOCK);
	if (fd < 0) {
		perror("open");
		XCloseDisplay(dpy);
		exit(EXIT_FAILURE);
	}
	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);

	while (finish == 0) {
		rc = select(fd + 1, &rfds, NULL, NULL, NULL);
		if (rc > 0) {
			memset(name, 0, sizeof(name));
			ssize_t got = read(fd, name, sizeof(name)-sizeof(char));
			if (got < 0) {
				perror("read");
				state = EXIT_FAILURE;
				break;
			} else if (got == 0) {
				printf("EOF\\n");
				break;
			}
			else {
				/* remove trailing newline */
				if (name[strlen(name)-1] == '\n')
					name[strlen(name)-1] = '\0';
				XStoreName(dpy, root, name);
				while (XPending(dpy))
					XNextEvent(dpy, &ev);
			}
		}
	}
	close(fd);
	XCloseDisplay(dpy);
	exit(state);
}

Benutzeravatar
Meillo
Moderator
Beiträge: 5053
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: C: fifo lesen

Beitrag von Meillo » 23.08.2018 13:43:38

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 12:55:20
Mit dem Unterschied zwischen Null, 0 und '\0' sollte ich mich wohl mal beschäftigen...
Die Binaerdarstellung all dieser Werte sind nur Nullen. (Auch wenn der Standard das nicht erfordert, so ist es in der Realitaet in allen Implementierungen so und es macht auch Sinn.)

Die Unterschiede liegen nur in den Datentypen. Finde heraus, welche Datentypen die drei Ausdruecke haben! 0 und '\0' sind einfach, NULL ist schwieriger.



Und ja, globale Variablen sollte man moeglichst vermeiden.
Use ed(1) once in a while!

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 23.08.2018 13:52:27

Alles klar, mache ich.
Was mir übrigens noch eingefallen ist (habe ich oben vergessen): Ich kann mir beim schließen des Prozesses das "-15" als Argument für kill sparen, denn das default-Signal von kill ist eh SIGTERM:

man 1 kill
The default signal for kill is TERM.

Benutzeravatar
bluestar
Beiträge: 626
Registriert: 26.10.2004 11:16:34
Wohnort: Rhein-Main-Gebiet

Re: C: fifo lesen

Beitrag von bluestar » 23.08.2018 16:38:27

Ich bin mir nicht sicher allerdings will ich es dennoch mal loswerden:

Code: Alles auswählen

while (XPending(dpy))
	XNextEvent(dpy, &ev);
Der Code wird bei dir ja nur nach dem Empfang von Daten ausgeführt, mein Gefühl sagt mir das du hier auf kurz oder lang ein Problem bekommen wirst, wenn der EventPuffer von X voll läuft, während du "unendlich lange" auf Daten aus deinem Fifo wartest.

Ich würde die While Schleife (stark vereinfacht so gestalten):

Code: Alles auswählen

while (finished==0) {
	while (XPending(dpy)) {
		XNextEvent(dpy, &ev);
	}
	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);
	rc = select (.....) // mit timeout von 1 sek oder 5 sek ... 
	if (rc > 0) {
		...
	}
}

Benutzeravatar
bluestar
Beiträge: 626
Registriert: 26.10.2004 11:16:34
Wohnort: Rhein-Main-Gebiet

Re: C: fifo lesen

Beitrag von bluestar » 23.08.2018 16:50:25

Und noch ne Anmerkung möchte ich gern loswerden:

Code: Alles auswählen

if (name[strlen(name)-1] == '\n')
	name[strlen(name)-1] = '\0';
Wenn strlen(name) gleich 0 ist, dann schreibst du an name[-1] = '\0' in den Speicher....

Wäre also wohl besser so:

Code: Alles auswählen

if ( (strlen(name) > 0) && (name[strlen(name)-1] == '\n') )
	name[strlen(name)-1] = '\0';

Benutzeravatar
Meillo
Moderator
Beiträge: 5053
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: C: fifo lesen

Beitrag von Meillo » 23.08.2018 17:44:00

bluestar hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 16:50:25
Und noch ne Anmerkung möchte ich gern loswerden:

Code: Alles auswählen

if (name[strlen(name)-1] == '\n')
	name[strlen(name)-1] = '\0';
Wenn strlen(name) gleich 0 ist, dann schreibst du an name[-1] = '\0' in den Speicher....
Gut gesehen! ... aber kann das im konkreten Fall denn passieren? Schliesslich sind wir im Else-Teil, wo immer Inhalt da sein sollte.

Ist es nicht so: Wenn wir nichts lesen ist's EOF, und wenn wir etwas lesen, dann haben wir mindestens ein Newline?

Wäre also wohl besser so:

Code: Alles auswählen

if ( (strlen(name) > 0) && (name[strlen(name)-1] == '\n') )
	name[strlen(name)-1] = '\0';
Oder:

Code: Alles auswählen

if (strlen(name) == 0) {
        continue;
}
if (name[strlen(name)-1] == '\n') {
	name[strlen(name)-1] = '\0';
}
... wobei manch ein C-Programmierer natuerlich ``if (!*name) {'' schreiben wuerde. ;-)


Fehlerfaelle nacheinander auszusortieren und am Ende die eigentliche Verarbeitung zu machen, fuehrt meist zu einfacher verstaendlicherem Code mit weniger Fehlern.

Btw: Wenn dein C-Code mal nicht mehr sinnvoll mit 8-Zeichen-Tabs eingerueckt auf 80-Zeichen-lange Zeilen passt, dann ist das ein Zeichen dafuer, dass er stilistisch verbessert werden kann. (Bei anderen Programmiersprachen sieht das teilweise anders aus, aber bei C trifft die Regel gut zu.)
Use ed(1) once in a while!

Benutzeravatar
bluestar
Beiträge: 626
Registriert: 26.10.2004 11:16:34
Wohnort: Rhein-Main-Gebiet

Re: C: fifo lesen

Beitrag von bluestar » 23.08.2018 18:45:50

Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 17:44:00
Ist es nicht so: Wenn wir nichts lesen ist's EOF, und wenn wir etwas lesen, dann haben wir mindestens ein Newline?
Wenn wir exakt ein '\0' lesen, dann ist got = 1 und strlen(name) = 0.

Benutzeravatar
Meillo
Moderator
Beiträge: 5053
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: C: fifo lesen

Beitrag von Meillo » 23.08.2018 18:49:18

bluestar hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 18:45:50
Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 17:44:00
Ist es nicht so: Wenn wir nichts lesen ist's EOF, und wenn wir etwas lesen, dann haben wir mindestens ein Newline?
Wenn wir exakt ein '\0' lesen, dann ist got = 1 und strlen(name) = 0.
Okay, wenn jemand Binaerdaten reinschreibt. Akzeptiert!
Use ed(1) once in a while!

RobertDebiannutzer
Beiträge: 235
Registriert: 16.06.2017 09:52:36

Re: C: fifo lesen

Beitrag von RobertDebiannutzer » 23.08.2018 21:15:54

Vielen Dank für eure weiteren Anregungen! :THX:

Wegen dem X-Code werde ich nochmal recherchieren. Man muss da bei Manuals und so aufpassen, denn im Gegensatz zu einem Window-Manager wartet mein Programm ja nicht auf einen Xevent (also z.B. einen Klick vom User), sondern der Xserver wartet auf mein Programm. Da scheint mir das Abarbeiten des Event-Buffers am Ende des loops irgendwie logischer?

Den Test auf newline werde ich anpassen, danke!
Meillo hat geschrieben: ↑ zum Beitrag ↑
23.08.2018 17:44:00
... wobei manch ein C-Programmierer natuerlich ``if (!*name) {'' schreiben wuerde. ;-)
Ja, das würde ich auch versuchen, denn dann hätte man einen function-Aufruf weniger. Aber man hat mir gesagt, ich solle doch im Zweifelsfall lieber die Lesbarkeit als die Performance-Optimierung wählen... :mrgreen:


Den Unterschied zwischen 0, NULL und ’\0’ habe ich jetzt übrigens glaube ich schon besser verstanden:
- 0 ist ein integer
- NULL ist ein pointer, d.h., dass NULL auf eine Speicher-Adresse zeigt, deren Wert 0 ist. Zugleich ist NULL als Makro des Compilers definiert.
- ’\0’ ist ein Zeichen, das nichts enthält. Also ein byte, dessen bits alle 0 sind.
Richtig so?
So wie ich es verstehe, kann man 0 immer für ifs nutzen, denn NULL und ’\0‘ laufen auch auf den int 0 hinaus.

Antworten