2016-04-28 8 views
1

以前は、機能する配列を取得する関数f(double *a)がありました。正しい位置を取得するためには、配列上で動作する必要があります。f(a+offset)と呼び、offsetという整数です。今私は、コードを再加工し、私は、カスタム構造体定義された:構造体のポインタを関数呼び出しで使用するときにポインタを追加する

typedef struct{ 
double *a; 
} struName; 

をし、機能がf(struName *a)に変更しました。今私は、新しい一時的なstructを作成することなく、またはf(struName *a)からf(struName *a, int offset)に機能を変更することなく、機能にオフセットをどのように得ることができるのだろうかと思っていました。それも可能ですか?

+5

なぜ関数プロトタイプを 'f(struName * a)'に変更したのですか?それはまだ 'f(variabelname.a + offset) 'で動作するはずです。 –

+3

関数を変更することは、これまでにない最もクリーンな解決策のようです。これを行うことができない場合は、オフセットメンバをstructにオプションとして追加しますか? – Lundin

答えて

2

構造体の内容を変更したり、未定義のビヘイビアを呼び出すことはできません。

あなたはISO C99へのアクセス権を持っている場合は、値によってstructを受け入れ、複合リテラルを渡すために署名を変更することができます。

f((struct struName){ .a = myStruct.a + offset }); 

それ以外の場合は個別のパラメータを使用して提案したソリューションは、うまく動作するはずです:

f(myStruct, offset); 
+0

未定義の振る舞いを恐れず、厳密なエイリアシングルールを解除したい場合は、 'f((double *)myStruct)+ offset);'を実行します。 ** NASAのデーモンが好きな場合を除いて、この作業を行わないでください** – Leandros

+0

UBは構造体をユニオンに変更することで簡単に取り消されます。この場合、動作は明確に定義されます。とにかくメンバーは1人だけです。 – Lundin

+0

@ Lundinまだ別の種類のエイリアシングではありませんか? – Leandros

2

最適な解決策は、オフセットパラメータを取るように関数を変更することです。

これはオプションではない場合、2番目に良い解決策は、構造体の定義をオフセットメンバーを含むように変更することです(これは意味があります)。

これもオプションでない場合、3番目に良い解決策は、Leandrosの答えに似ています。ポインタを一時構造体に渡す前に一時的な構造体を作成し、ポインタメンバーを変更します。つまり、構造体をとして扱います。 - 可能であれば、ポインタメンバをconstにしてください。これはプログラムのデザインをきれいに保ちますが、構造体の余分なコピーを作成する必要があります。

関連する問題