サーチ…


備考

Cでは、発生するエラーを示すために戻り値を使用するのが一般的です。渡されたポインタを使用してデータを返すことができます。これは複数の理由で行うことができます。ヒープ上にメモリを割り当てたり、関数が呼び出された時点で静的割り当てを使用したりする必要はありません。

ポインタパラメータを使用して複数の値を返す

Cの一般的なパターンは、関数から複数の値を返すことを容易に模倣するために、ポインタを使用することです。

#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;
}

関数への配列の受け渡し

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;
  }
}

ここでは、関数のパラメータの[]内のstatic値は、引数配列に少なくとも指定された要素数( size要素)が必要であることを要求します。その機能を使用できるようにするには、 sizeパラメータがリストの配列パラメータの前に来るようにする必要があります。

次のように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;
}

も参照してください

多次元配列を関数に渡す

パラメータは値によって渡されます

Cでは、すべての関数パラメータが値渡されるので、呼び出し先関数で渡されたものを変更しても、呼び出し元関数のローカル変数には影響しません。

#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;
}

ポインターを使用すると、呼び出し先関数が呼び出し元関数のローカル変数を変更できるようになります。これは参照渡しではなく、ローカル変数を指すポインタ渡されることに注意してください。

#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;
}

ただし、ローカル変数のアドレスを呼び出し先に返すと、定義されていない動作になります。 有効期限を超えた変数へのポインタの参照解除参照してください。

関数パラメータの実行順序

パラメータの実行順序は、Cプログラミングでは定義されていません。ここでは、左から右へ、または右から左へ実行することができる。順序は実装によって異なります。

#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;
}

エラーコード付きの値を含むstructを返す関数の例

値を返す関数のほとんどの例は、ポインタが引数の1つとして提供され、関数が次のように指された値を変更できるようにします。関数の実際の戻り値は、通常、結果の状態を示すint型のような型であるかどうかは関係ありません。

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 */
}

しかし、 structを戻り値として使用することもできます。これにより、エラー状態と他の値の両方を返すことができます。例えば。

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;
}

この関数は、次のサンプルのように使用できます。

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

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

または、次のように使用できます。

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
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow