Die Gründe dafür sind rein historischer Natur. Beachten Sie, dass in den alten Tagen der C-Sprache (K & R C) gab es keine Funktion Prototyp. Eine strchr
Funktion in jenen Zeiten werden würde als
erklärt
char *strchr();
und in K & R Stil als
char *strchr(s, c)
char *s;
char c;
{
/* whatever */
}
jedoch in der Sprache C (in K & RC und in dem modernen als auch) definiert Wenn die Funktion ohne einen Prototyp deklariert wird (wie oben gezeigt), werden die Parameter, die in jedem Funktionsaufruf übergeben werden, sogenannten Standardargument-Promotions unterworfen. Unter Default-Argument-Promotions wird jeder Integraltyp kleiner als int
(oder unsigned int
) immer in int
(oder unsigned int
) konvertiert. I.e. Wenn die Parameter nicht deklariert sind und Sie einen Wert von char
als Argument übergeben, wird dieser Wert implizit in konvertiert und tatsächlich physisch als int
übergeben. Das gleiche gilt für short
. (BTW, float
wird standardmäßig in Argument-Promotions in double
konvertiert). Wenn innerhalb der Funktion der Parameter tatsächlich als char
deklariert ist (wie in der obigen R-Stildefinition K &), wird implizit in char
konvertiert und als char
innerhalb der Funktion verwendet. So funktionierte es in K & R-Zeiten, und so funktioniert es bis heute in modernem C, wenn die Funktion keinen Prototyp hat oder wenn variadische Parameter verwendet werden.
Nun, Stichwort in der modernen C, die Funktionsprototypen hat und verwendet moderne Funktionsdefinition Syntax. Um die "traditionelle" Funktionalität von strchr
, wie oben beschrieben, zu bewahren und zu reproduzieren, haben wir keine andere Wahl, als den Parameter als int
zu deklarieren und innerhalb der Funktion explizit in char
umzuwandeln. Dies ist genau das, was Sie in dem von Ihnen zitierten Code beobachten. Dies ist genau so, wie die Funktionalität von strchr
in der Norm beschrieben ist.
Außerdem, wenn Sie haben eine bereits kompilierte Legacy-Bibliothek, wo strchr
in K & R Stil definiert ist, wie oben gezeigt, und Sie sich entschieden moderne Prototypen für die Bibliothek zur Verfügung zu stellen, die richtige Erklärung für strchr
wäre
char *strchr(const char *s, int c);
weil int
ist, was die obige Legacy-Implementierung physisch als c
erhalten erwartet. Die Angabe mit einem char
Parameter wäre falsch.
Aus diesem Grund werden Sie nie "traditionelle" Standardbibliotheksfunktionen sehen, die Parameter des Typs char
, short
oder float
erwarten. Alle diese Funktionen werden stattdessen mit Parametern des Typs int
oder double
deklariert.
Ein sehr ähnliches Grundprinzip ist hinter der Standardgarantie, dass Zeichenzeiger und void *
Zeiger die gleichen Darstellungs- und Ausrichtungsanforderungen teilen. Mit dieser Garantie können Sie malloc
als void *
-Returning-Funktion deklarieren und diese Deklaration dann mit einer vorkompilierten Legacy-Version der Standardbibliothek verwenden, wobei malloc
tatsächlich char *
zurückgegeben wird.
Referenz: die C99 Gründe, Version 5,10
7.1.4 Verwendung von Bibliotheksfunktionen
/-/
Alle Bibliothek Prototypen werden in Bezug auf die „erweitert“ Typen angegeben: Ein Argument, das früher als char deklariert wurde, wird jetzt als int geschrieben. Diese stellt sicher, dass die meisten Bibliotheksfunktionen können mit oder ohne Prototyp in Umfang genannt werden, so dass die Kompatibilität mit Code pre-C89
Aufrechterhaltung rückwärts
gleichen Grund dafür, warum [Memset einen int nehmen statt von einem char] (https://stackoverflow.com/q/5919735/995714) –