Ich habe mehrere Diskussionen über die Übergabe von char * in C gelesen.
stackoverflow: Übergabe-einer-Reihe-von-Zeichenfolgen-als-Parameter-an-eine-Funktion-in-c
stackoverflow: Wie funktioniert ein Array von Zeigern zu Zeigern?
stackoverflow: was-ist-dein-liebstes-programmierer-ignoranz-tier-peeveve
drexel.edu: Zeichen-Arrays
In vielen von ihnen wird auch über Arrays gesprochen, aber davon möchte ich mich fernhalten.
Ich schreibe ein Beispielprogramm, um mir selbst etwas über die Weitergabe von char *
y char **
in C. Dies ist eine Übung zur Übergabe von char *, ohne Verwendung von (Zeigern auf) Arrays. Auch keine Bedenken hinsichtlich der Ausführungseffizienz :-)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void get_args_works(int, char **, char **);
void get_args_broken(int, char **, char *);
char *get_string(int, char **);
int main(int argc, char **argv)
{
char *string_works;
char *string_broken;
get_args_works(argc, argv, &string_works);
get_args_broken(argc, argv, string_broken);
printf("in main string_works (%p) = %s\n",string_works,string_works);
free(string_works);
printf("in main string_broken (%p) = %s\n",string_broken,string_broken);
free(string_broken);
}
void get_args_works(int argc, char **argv, char **string)
{
*string = get_string(argc, argv);
printf("in get_args_works %p string %s\n",*string,*string);
}
void get_args_broken(int argc, char **argv, char *string)
{
string = get_string(argc, argv);
printf("in get_args_broken %p string %s\n",string,string);
}
char * get_string(int argc, char **argv)
{
int i;
char *string;
string = malloc(40);
// placeholder in case -s switch not found below
strcpy(string,"-s switch not found below");
for(i = 0; i < argc; i++)
{
if(argv[i][0] == '-')
{
switch(argv[i][1])
{
case 's':
// release above malloc(40) for "-s switch not found below"
free(string);
// make room for storing variable
string = malloc(strlen(argv[++i]) + 1);
// the argv just after -s
strcpy (string,argv[i]);
break;
}
}
}
return string;
}
Sie können auch die gleicher Code auf github
Der obige Code ist einigermaßen selbsterklärend. main()
deklariert zwei char *-Variablen und übergibt sie als Parameter an ihre jeweiligen get_args()
Funktionen.
Jede get_args()
Funktionsaufrufe char * get_string(int, char **)
mit genau demselben Aufruf (aber mit einer anderen Methode zur Erfassung des Rückgabewerts).
get_string()
funktioniert gut; es macht eine malloc()
und gibt den Zeiger an die aufrufende Funktion zurück. Dieser Code funktioniert, und jede get_args()
Funktion den Rückgabewert wie erwartet erhält.
Aber dann, wenn die get_args()-Funktionen zurückkehren zu main()
warum wird der dereferenzierte Zeigerwert an main zurückgegeben (von get_args_works()
aber nicht den Wert des Zeigers (aus get_args_broken()
)?
(d.h. ich kann sehen, dass, wenn ich den Zeiger dereferenziere ( &string_works
), wenn sie als Parameter gesendet wird, funktioniert es. Aber warum? Ist nicht char * string_broken
bereits ein Zeiger? Warum braucht es die "zusätzliche" Dereferenzierung, wenn es als Parameter gesendet wird?)
Ich hoffe auf eine überzeugende Antwort, die erklärt, wie Sie (ja, Sie) Senden char * als Parameter vs Empfangen es als Rückgabewert der Funktion konzeptualisieren.