Suche…


Bemerkungen

In C ist es üblich, Rückgabewerte zu verwenden, um auf auftretende Fehler hinzuweisen. und um Daten durch die Verwendung von übergebenen Zeigern zurückzugeben. Dies kann aus mehreren Gründen erfolgen. Dazu gehört, dass auf dem Heap kein Speicher zugeordnet werden muss oder dass die statische Zuordnung an dem Punkt verwendet wird, an dem die Funktion aufgerufen wird.

Verwenden von Zeigerparametern, um mehrere Werte zurückzugeben

Ein übliches Muster in C zum einfachen Nachahmen mehrerer Werte aus einer Funktion ist die Verwendung von Zeigern.

#include <stdio.h>

void Get( int* c , double* d )
{
    *c = 72; 
    *d = 175.0;
}

int main(void)
{
    int a = 0;
    double b = 0.0;

    Get( &a , &b );

    printf("a: %d, b: %f\n", a , b ); 

    return 0;
}

Übergabe von Arrays an Funktionen

int getListOfFriends(size_t size, int friend_indexes[]) {
  size_t i = 0;
  for (; i < size; i++) {
    friend_indexes[i] = i;
  }
}
C99 C11
/* Type "void" and VLAs ("int friend_indexes[static size]") require C99 at least. 
   In C11 VLAs are optional. */
void getListOfFriends(size_t size, int friend_indexes[static size]) {    
  size_t i = 0;
  for (; i < size; i++) {
    friend_indexes[i] = 1;
  }
}

Hier fordert die static innerhalb des [] des Funktionsparameters an, dass das Argument-Array mindestens so viele Elemente enthalten muss, wie angegeben (dh size ). Um der Lage sein , diese Funktion verwenden wir , um sicherzustellen haben , dass die size Parameter kommt vor dem Array - Parameter in der Liste.

Verwenden Sie getListOfFriends() wie getListOfFriends() :

#define LIST_SIZE (50)

int main(void) {
  size_t size_of_list = LIST_SIZE;
  int friends_indexes[size_of_list];

  getListOfFriends(size_of_list, friend_indexes); /* friend_indexes decays to a pointer to the
                                                     address of its 1st element: 
                                                                      &friend_indexes[0] */

  /* Here friend_indexes carries: {0, 1, 2, ..., 49}; */

  return 0;
}

Siehe auch

Übergeben von mehrdimensionalen Arrays an eine Funktion

Parameter werden per Wert übergeben

In C werden alle Funktionsparameter als Wert übergeben. Wenn Sie also ändern, was in Aufgerufsfunktionen übergeben wird, hat dies keine Auswirkungen auf die lokalen Variablen der Anruferfunktionen.

#include <stdio.h>

void modify(int v) {
    printf("modify 1: %d\n", v); /* 0 is printed */
    v = 42;
    printf("modify 2: %d\n", v); /* 42 is printed */
}

int main(void) {
    int v = 0;
    printf("main 1: %d\n", v); /* 0 is printed */
    modify(v);
    printf("main 2: %d\n", v); /* 0 is printed, not 42 */
    return 0;
}

Sie können Zeiger verwenden, um die lokalen Variablen der aufrufenden Funktionen durch Aufräumfunktionen zu ändern. Beachten Sie, dass dies nicht als Referenz übergeben wird, sondern die Zeigerwerte , die auf die lokalen Variablen zeigen, übergeben werden.

#include <stdio.h>

void modify(int* v) {
    printf("modify 1: %d\n", *v); /* 0 is printed */
    *v = 42;
    printf("modify 2: %d\n", *v); /* 42 is printed */
}

int main(void) {
    int v = 0;
    printf("main 1: %d\n", v); /* 0 is printed */
    modify(&v);
    printf("main 2: %d\n", v); /* 42 is printed */
    return 0;
}

Das Zurückgeben der Adresse einer lokalen Variablen an den Angerufenen führt jedoch zu undefiniertem Verhalten. Siehe Dereferenzieren eines Zeigers auf eine Variable, deren Lebensdauer überschritten wird .

Reihenfolge der Funktionsparameterausführung

Die Reihenfolge der Ausführung von Parametern ist in der C-Programmierung nicht festgelegt. Hier kann es von links nach rechts oder von rechts nach links ausgeführt werden. Die Reihenfolge hängt von der Implementierung ab.

#include <stdio.h>

void function(int a, int b) 
{
    printf("%d %d\n", a, b);
}

int main(void)
{
    int a = 1;
    function(a++, ++a);
    return 0;
}

Beispiel für eine Funktion, die eine Struktur zurückgibt, die Werte mit Fehlercodes enthält

Bei den meisten Beispielen einer Funktion, die einen Wert zurückgibt, muss ein Zeiger als eines der Argumente angegeben werden, damit die Funktion den Wert, auf den gezeigt wird, ähnlich wie im Folgenden ändern kann. Der tatsächliche Rückgabewert der Funktion ist normalerweise ein Typ wie ein int , um den Status des Ergebnisses anzuzeigen, unabhängig davon, ob es funktioniert hat oder nicht.

int func (int *pIvalue)
{
    int iRetStatus = 0;             /* Default status is no change */

    if (*pIvalue > 10) {
        *pIvalue = *pIvalue * 45;   /* Modify the value pointed to */
        iRetStatus = 1;             /* indicate value was changed */
    }

    return iRetStatus;              /* Return an error code */
}

Sie können jedoch auch eine struct als Rückgabewert verwenden, mit der Sie sowohl einen Fehlerstatus als auch andere Werte zurückgeben können. Zum Beispiel.

typedef struct {
    int    iStat;      /* Return status */
    int    iValue;     /* Return value */
}  RetValue;

RetValue func (int iValue)
{
    RetValue iRetStatus = {0, iValue};

    if (iValue > 10) {
        iRetStatus.iValue = iValue * 45;
        iRetStatus.iStat = 1;
    }

    return iRetStatus;
}

Diese Funktion kann dann wie im folgenden Beispiel verwendet werden.

int usingFunc (int iValue)
{
    RetValue iRet = func (iValue);

    if (iRet.iStat == 1) {
        /* do things with iRet.iValue, the returned value */
    }
    return 0;
}

Oder es könnte wie folgt verwendet werden.

int usingFunc (int iValue)
{
    RetValue iRet;

    if ( (iRet = func (iValue)).iStat == 1 ) {
        /* do things with iRet.iValue, the returned value */
    }
    return 0;
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow