0

Visual Studio 2005 で、ある場所から別の場所に構造体をコピーしようとすると、標準の C コンパイラを使用してコンパイラの問題が発生します。

タイプは、次のようにファイルで定義されます。

definition.h

#define MAX 7

typedef struct{
   char    recordtext[18];
   boolean recordvalid;
}recordtype;

typdef recordtype tabletype[MAX];

typedef struct{
   tabletype table;
}global_s;

global_s「オブジェクト」がどこかでインスタンス化および初期化され、この構造体へのポインターが作成されたとします。

#include "definition.h"

global_s global;
global_s* pglobal = &global;
init(&pglobal);

一方、別のファイル(これが私の問題です)で、ローカルテーブルタイプオブジェクトを作成しようとしており、getメソッドを使用してグローバルテーブルメンバーで埋めようとしています(「静的」であるふりをしましょう)

#include "definition.h"

extern global_s* pglobal;

tabletype t;
gettable(&t);

void gettabl (tabletype* pt)
{
   *pt = pglobal->table;
}

コンパイルすると、gettable 関数の行で「エラー C2106: '=': 左オペランドは左辺値でなければなりません。これは通常のコピー操作として動作するように見えますが、実際により基本的な構造体に対して同様の操作を実行しても、エラーは発生しません.たとえば、2 つの整数のみを含む構造体をコピーした場合.

この操作が正しくないと思われる理由について、誰かがしっかりとした説明を持っていますか?

(免責事項:このコードは、例として実際のコードのスクラブバージョンとして開発したため、構文的に100%正しいとは限りません。誰かが問題を指摘したり、明確にする必要がある場合は、質問を編集します。)

4

2 に答える 2

0

(グローバル変数への参照を取得する場合):

これが正しいかどうか(そして問題があるかどうか)はわかりませんが、関数プロトタイプ以外に、配列とポインター(配列1.要素への)はまったく同じではないと思います。また、配列へのポインターと配列の要素へのポインターには違いがあります)。

おそらく配列のアドレスを取得します:

*pt = &(pglobal->table);

とにかく、配列全体のアドレスを取得するのではなく、最初の要素のアドレスを取得する方がよい場合があります。これにより、結果のポインターをレコード配列として直接使用できます (逆参照せずに)。

recordtype* gettable (size_t* puLength)
{     
    *puLength = MAX;     
    return &(pglobal->table[0]);        
}

(テーブルのコピーが必要な場合):

C90 では配列をその場でコピーすることはできません。もちろん、ターゲット メモリを提供する必要があります。次に、関数 get テーブルを次のように定義します。

void gettable (recordtype * const targetArr)
{
    size_t i = 0;
    for (; i < MAX; i++) targetArr[i] = pglobal->table[i];
    return;
}

gettable の完全に同等な関数プロトタイプは次のとおりです。

void gettable(recordtype[] targetArr);

関数パラメーターに関しては、配列は最初の要素へのポインターとして参照によって提供されます。配列全体へのポインターを再度要求し、gettable 内で逆参照することができます。ただし、常に要素ごとにコピーする必要があります。

memcopy を使用して、ワンライナーとしてジョブを実行できます。最新のコンパイラは、私の知る限り、同等に効率的なコードを生成するはずです。

于 2015-01-16T12:48:27.080 に答える
0

構造体の配列です。割り当てることはできません。構造体ごとに operator=() を定義し、配列で memcpy を使用するか、要素ごとにループでコピーする必要があります。

于 2012-09-10T22:35:22.587 に答える