2010-12-18 13 views
1

パラメータとして整数をとり、C++で配列を返す関数を作成します。これは私が考えていた擬似コードです:整数をパラメータとして受け取り、配列を返す

function returnarray(integer i) 
{ 
    integer intarr[i]; 

    for (integer j = 0; j < i; j++) { intarr[j] = j; } 

    return intarr; 
} 

私はポインタを返す*関数としてreturnarray宣言の一般的な方法を試してみましたが、その後、私は私のパラメータとしての整数を取ることができません。私はintarr [j]にjを代入することもできません。私は本当にintへのポインタを作ることを避けたいので、パラメータを使うことができます。

これを実行し、ポインタを作成せずにjをintarr [j]に割り当てる方法はありますか?

編集:

私はベクトルを避けたいと書くことを忘れました。私は本当にする必要がある場合にのみ、私はそれらを使用します! (私の理由は私のものです)。

ありがとう:コードコンパイラの手によって触れられていない:私はあなたが総初心者

使用std::vector

#include <vector> 

std::vector<int> yourFunction(int n) 
{ 
    std::vector<int> result; 
    for(int i = 0; i < n; ++i) 
    { 
     result.push_back(i); 
    } 
    return result; 
} 

免責事項だと仮定し、C++ D

+0

これは、関数ポインタとは何の関係もありませんので、私は、タグを削除しました。 – sepp2k

+3

ベクターを避けたい理由を述べる必要があります。ベクターは明らかな解決策を提供します。回答者は、あなたが直面している潜在的な解決策の制限を知る必要があります。 –

+0

@MisterSir:ベクターを使いたくないのなら、自分のベッドでうそをつく。 – Puppy

答えて

0

ダイナミックメモリを使用する必要があります。

1)あなたはベクトルを避けたいことはありません:優れた@DeadMGのソリューションを使用する前にこの

int* returnArray(int size) { 
    int* array = new int[size]; 
    for(int i = 0; i < size; ++i) 
     array[i] = i; 
    return array; 
} 
+2

配列内の値を初期化することを忘れないでください(投稿された擬似コードに従って):) – pstrjds

+0

@pstrjds修正済み: – EnabrenTane

+4

-1これは初心者に未加工のポインタと 'new'と' delete'生涯を手作業で扱っています。初心者がほとんど無関係な問題に対処しなければならないので、ちょうど長い間傾いていません。後で、その人はすべてのものを放棄する必要があります。 –

5

あなたのコードでも有効の近くではありません。

乾杯& HTH。、

+1

これは単に私がしようとしていることを示すための擬似コードです。私はベクトルを使うこともできますが、ベクトルを避けたいと書くことも忘れてしまいました。それらを使用することは可能ですが、配列に直接アプローチする必要があるため、コードが複雑になります。とにかくおかげで。 – Lockhead

+5

@MisterSir: 'std :: vector'を使用すると、コードはより複雑にならず簡単になります。最初は、_something_ elseを実行する必要があるので、配列を返す関数を持つことはできません。 'std :: vector'を返すことは、ほとんどの点で最も単純な方法です。 –

+0

result.reserve(n)を検討してください。それ以外の場合、push_backは大きなnの値に対してパフォーマンスが低下します。実装に応じて、通常、ベクトルは約1.5〜2倍になります。あなたは繰り返し割り当てとmemcpyをしなければならないという意味です。 – EnabrenTane

10

スコープの外に行くことになるだろうし、メモリが割り当て解除array-あなたは、スタック割り当てを返すことができません。さらに、C++では、スタックに割り当てられた可変長配列は許可されていません。 std :: vectorを使うべきです。

std::vector<int> returnarray(int i) { 
    std::vector<int> ret(i); 
    for(int j = 0; j < i; j++) ret[j] = j; 
    return ret; 
} 
+0

STLベクターに慣れている方は素晴らしいです。あなたがCコードにもっと慣れているなら、私の答えはより古くなっています。 味の問題、それぞれの方法は賛否両論あります – EnabrenTane

+0

+1簡潔な回答です。 'const std :: vector 'を返すことができますか? – ig2r

+1

@EnabrenTane:いいえ、それは実際にはまったく真実ではありません。あなたの方法には、プログラムを破壊する短所の巨大なリストがあります。同様に、境界チェックも例外安全性もなく、自動リリースもセマンティック・エンフォースメントもありません。唯一の利点は、クロスコンパイラ/クロスランゲージリンク機能です。そして、すべてのC++プログラマはSTLベクタに慣れていなければなりません。その答えの信じられないほどの失敗は、これらのC++の概念が存在するすべての理由です。 @ ig2r:いいえ、持っていることはありません。 – Puppy

1

二つの発言のようなもの。 vがベクトルで、実際にポインタが必要な場合は、&v[0]と書くことで、常に最初の要素へのポインタを持つことができます。

2)配列を返すことはできません。新しいメモリゾーンへのポインタが返されます。新しいゾーンは、一度終了すると削除する必要があります。ベクトルは自動削除機能を持つ配列だけなので、メモリがリークすることはありません。

0

このアプローチは一般的にはお勧めできませんが、テンプレートを使用してダイナミックメモリ割り当てに頼ることなくこれを行うことができます。残念ながら関数から配列を返すことはできないので、配列を内部に持つ構造体を返す必要があります。

template <int N> 
struct int_array_type { 
    int ints[N]; 
}; 

template <int N> 
int_array_type<N> returnarray() { 
    int_array_type<N> a; 
    for (int i = 0; i < N; ++i) 
     a.ints[i] = i; 
    return a; 
} 

...

int_array_type<10> u = returnarray<10>(); 
std::copy(u.ints, u.ints+sizeof(u.ints)/sizeof(u.ints[0]), 
    std::ostream_iterator<int>(std::cout, "\n")); 
関連する問題