1

すべての値を変更せずに構造体型を返すようにいくつかの関数を変更しようとしています。具体的には、さまざまな方法で画像のサイズを変更し、新しい画像のサイズを返すようにしています。netpbm画像ファイルのヘッダー情報(幅、高さ、最大色値、および形式を示す1〜6の数字)を含む「picspec」という構造体があります。

一部の画像編集では、これら4つすべて(要素?構造体の一部)を変更する必要がある場合がありますが、多くはそれらの一部にのみ影響するため、そのような場合は元の値をそのままにしておくことをお勧めします。私の最初の本能は、関数を次のように終了することでした。

picspec newinfo = {newx, newy, void, void};
return newinfo;

...そして、コンパイラエラーが発生しても特に驚きませんでした。

注:古い「picspec」を引数として渡すことでこの特定の問題を簡単に解決できることを理解していますが、「現在の値を保持」コマンドは他の状況で非常に役立つ可能性があります。私の(現在は非常に限られた)ポインターの知識は、それが可能であると私に思わせますが、私はそれを探すことにあまり成功していません。(「独学へのポインタ」はリンクリストについてすべて教えてくれましたが、それは私が考えていたものではありませんでした。)

「現在の価値を維持する」ためのメカニズム、または同じ目標を達成するための同様に簡潔な方法はありますか?そうでない場合、最も実用的な代替手段は何ですか?

4

2 に答える 2

6

関数を使用してC構造体を操作するには、次の2つの方法があります。

値を返す場合は、構造体全体を返す必要があります。それでも、実際に新しいコピーを作成する必要はありません。

MyStruct myStructModified(MyStruct s, int delta) {
  // s is already a copy of the original value
  s.member += delta;
  return s;
}

..。

{ // somewhere else, with MyStruct s
     // replace value of s with new one
     s = myStructModified(s, 10);
}

比較的小さな構造体を返すことは、Cポインターの問題ではなく、実際の問題に集中するための良い方法ですが、既存の構造体を変更したい場合は、(OOPのないCのようなC ++ではなく)Cに制限されます。ポインタを使用する必要があります。

void modifyMyStruct(MyStruct *sp, int delta) {
  sp->member += delta;
}

..。

{ // somewhere else, with MyStruct s
     // pass pointer to s to function, which will modify it in-place
     modifyMyStruct(&s, 10);
}

C ++コンパイラを使用できる場合は、3番目の選択肢があります。C++参照を使用することです。これは、砂糖でコーティングされたポインタです。

void modifyMyStruct(MyStruct &s, int delta) {
  s.member += delta;
}

..。

{ // somewhere else, with MyStruct s
     // pass reference to s to function, which will modify it in-place
     modifyMyStruct(s, 10);
}

値の使用はよりクリーンで安全ですが、遅くなります(構造体のすべてのデータをコピーします)。ポインタの使用は効率的です(アドレスのみが渡され、通常はCPUレジスタで、非常に高速です)が、間違って実行すると、クラッシュするバグが非常に簡単に発生する可能性があります。C ++参照は、ポインターよりも少しクリーンで安全な代替手段であり、C ++コンパイラーを使用できる場合は、通常は推奨されます。

于 2012-11-13T18:56:22.450 に答える
0

部分構造体を返すことが非常に重要で、操作する既存の構造体を渡さないことが重要な場合は、「部分構造体」を構造体を操作する関数として定義し、それを返すことができます。

残念ながら、C はクロージャをサポートしていません。そのため、少し醜くなります。おそらく、関数ポインターとバインドされた変数を指す void ポインターによってクロージャーを表すでしょう。

于 2012-11-13T19:04:46.940 に答える