1

関数があり、 int の配列を返したいのですが、このように、それを行うためだけに変数を作成したくありません

 int* foo()
 {
       static int bar[]={1,2,3}; // edit thanks to comments
       return bar;
 }

それを回避するために、私はこれを試しました:

       return (Uint8Type*)   gAppCanContext.BluetoothMacAddr[0] + MacAddr[1] + '-'\
               + gAppCanContext.BluetoothMacAddr[2] + MacAddr[3] + '-' ;

しかし、うまくいきません。私もこれを試しました:

return (Uint8Type*[]){ MacAddr[0] , MacAddr[1] + '-' MacAddr[3] ... };

警告付きでコンパイルされ、プログラムを実行するとフリーズします。アスタリスクとアンパサンドでも少し遊んでみましたが、適切に機能させることができませんでした。

それは可能ですか?もしそうなら、どのように?

追加: malloc は使用できません - 動的割り当てのない組み込みシステムです。

4

5 に答える 5

3

警告付きでコンパイルされ、プログラムを実行するとフリーズします。

この警告は、死にかけているオブジェクトのアドレスを返していることを示しているため、関数呼び出しの終了後にアクセスすることは違法です。

それは可能ですか?もしそうなら、どのように?

  • あなたはmallocいくらかのメモリとそれへのポインタを返すことができます
  • staticElectro で述べたように、オブジェクトを使用できます。
于 2012-07-04T14:41:14.580 に答える
0

foo のデータが動的でない場合は、これを試すことができます。

const char *foo(void)
{
    static const char *bar[] = {"aa", "bb", "cc"};
    return bar;
}

「静的」の助けを借りて、データがスコープ外に出ても消えません。

于 2012-07-04T14:44:15.500 に答える
0

標準が変更されていない限り、C はレジスタに返すことができる値を返します。したがって、あなたの場合、関数は文字列へのポインターを返します。

その文字列をどのように作成するかは、ベスト プラクティスを考慮して決定します。

関数で静的配列を宣言し、それへのポインターを返すことができます。

char * cp1()
{
    static char szForeverBuf[100] = {0};

    return (char * ) &szForeverBuf;
}

起動時に cp1 が 1 回呼び出された場合、これは問題を処理する方法である可能性がありますが、関数はコンパイル時に作成されたバッファーのアドレスのみを返すため、2 回以上呼び出されるとエラーになる可能性があります。

つまり、関数 cp1 は、cp1 が呼び出されるたびに値が変化しない文字ポインターを返します。したがって、これが関数が起動時に役立つ理由です。

次のように動的メモリを作成することもできます。

#include <stdio.h>
#include <stdlib.h>

char * cp2(int nSizeP)
{
    char *pszForeverBuf = NULL;
    int nSize = 0;

    if (0 >= nSizeP)
    {
        nSize = 100;
    }
    else
    {
        nSize = nSizeP + 1;
    }

    pszForeverBuf = (char *) malloc((nSize + 1) * sizeof(char));

    return pszForeverBuf; 
}

pszForeverBuf の値をどこかに保存する必要があるため、メモリを使用する必要がなくなった場合は、 pszForeverBuf -- を使用して解放できますfree(pszForeverBuf)

最後に、より高度な方法として、ストレージの巨大な静的ブロックを作成し、メモリ ハウスキーピングを実行する関数を使用してそれを操作できます。ただし、これは、malloc を何度も呼び出したくない高度なケースで使用されます。

于 2012-07-04T15:47:51.023 に答える
0

まず、C の関数は配列値を返すことができず、ポインターのみを返します。次に、関数から戻るとそのようなオブジェクトが存在しなくなるため、他の人がすでに述べたように、動的に「スタック」に割り当てられたオブジェクトを返すことはできません。

そのようなことに対処する最も簡単な方法は、配列を引数として関数に渡すことです (へのポインター)。

int* foo(int bar[3]) {
  // fill the array here

  return bar;
}

これにより、2 つの異なる割り当て戦略で関数を呼び出すことができます

int* aMalloc = foo(malloc(sizeof(int[3])));
int* aLocal = foo((int[3]){ 0 });

そして、コーディングを容易にするために、これら 2 つのフォームをマクロにラップすることもできます。

#define fooMalloc() foo(malloc(sizeof(int[3])))
#define fooLocal() foo((int[3]){ 0 })

したがって、上記のコードは次のようになります

int* aMalloc = fooMalloc();
int* aLocal = fooLocal();
于 2012-07-04T18:58:15.870 に答える
0
int* foo()
{
   int bar[]={"aa","bb","cc"};
   return bar;
}

いいえ、できません。C には実際には「配列」がありません。bar を返すと、実際には bar の最初の要素へのポインターが返されるだけで、呼び出し元に戻るまでにポインターは失われます。

それに加えて、配列に「文字列」または整数のどちらが必要かを決定したい場合があります:-)

配列を構造体に貼り付けることができます

struct Weird
{
    int bar[3];
}

そしてそれを返します:

struct Weird foo(void)
{
    struct Weird bar;
    bar.bar[0]=1;
    bar.bar[1]=5;
    bar.bar[2]=10;
    return bar;
}

それでも、それがあなたの望みかどうかはわかりません。私の推測では、あなたは本当に C に慣れたいと思っているのでしょう :-)

そうすれば、最初の例を機能させることもできます

int* foo()
{
   static int bar[]={1,2,3};
   return bar;
}

しかし、もちろん、それは配列のインスタンスを 1 つしか作成しません。したがって、それを変更すると、それらのすべての戻り値が変更されます。

于 2012-07-04T14:48:31.940 に答える