web-dev-qa-db-ja.com

構造体をCの構造体にコピーする

同一の構造体を別の構造体にコピーし、後で最初の構造体と比較するために使用します。事は私がこのようなことをしているとき、私のコンパイラは私に警告を与えるということです!別の方法でそれを行う必要がありますか、これを間違っていますか:

ヘッダーファイル内:

extern struct RTCclk
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t mday;
uint8_t month;
uint8_t year;
}
RTCclk;

Cファイルの場合:

struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;

void FunctionDO(void)
{
   ... // Some Code
   /* Copy first struct values into the second one */
   memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}
60
Christian

単純な構造の場合は、memcpyを使用するか、単に一方から他方に割り当てることができます。

RTCclk = RTCclkBuffert;

コンパイラは、構造をコピーするコードを作成します。


コピーに関する重要な注意:memcpyの場合と同様に、浅いコピーです。つまり、たとえばポインタを含む構造体、コピーされるのは実際のポインタのみであり、ポインタが指すものではないため、コピー後、同じメモリを指す2つのポインタができます。

131

あなたのコードは正しいです。一方を他方に直接割り当てることもできます( Joachim Pileborg's answer を参照)。

後で2つの構造体を比較するときは、memcmpを使用する代わりに、メンバーを一度に1つずつ、長い間構造体を比較するように注意する必要があります。 Cで構造体の等価性をどのように比較しますか? を参照してください。

18
Graham Borland

cの構造をコピーするには、次のように値を割り当てる必要があります。

struct RTCclk RTCclk1;
struct RTCclk RTCclkBuffert;

RTCclk1.second=3;
RTCclk1.minute=4;
RTCclk1.hour=5;

RTCclkBuffert=RTCclk1;

rTCclkBuffert.hourの値は5になります

RTCclkBuffert.minuteの値は4です

RTCclkBuffert.secondの値は3です

3
Hemant Metalia

memcpyは、最初の2つの引数がvoid *であると想定しています。

試してください:memcpy( (void*)&RTCclk, (void*)&RTCclkBuffert, sizeof(RTCclk) );

追伸必須ではありませんが、慣例により、sizeof演算子の括弧が決まります。 Cで多くのことをやり遂げることができるため、コードを維持できなくなります。したがって、次の規則は優れた(雇用可能な)Cプログラマーの証です。

1
Dan

また、良い例.....

struct point{int x,y;};
typedef struct point point_t;
typedef struct
{
    struct point ne,se,sw,nw;
}rect_t;
rect_t temp;


int main()
{
//rotate
    RotateRect(&temp);
    return 0;
}

void RotateRect(rect_t *givenRect)
{
    point_t temp_point;
    /*Copy struct data from struct to struct within a struct*/
    temp_point = givenRect->sw;
    givenRect->sw = givenRect->se;
    givenRect->se = givenRect->ne;
    givenRect->ne = givenRect->nw;
    givenRect->nw = temp_point;
}
1
newrev426

memcpyコードは正しいです。

私の推測では、string.hのインクルードが不足しています。そのため、コンパイラはmemcpyの誤ったプロトタイプを想定しているため、警告が表示されます。

とにかく、単純にするために構造体を割り当てる必要があります(Joachim Pileborgが指摘したように)。

1
undur_gongor

警告を取り除くには、ポインターを(void *)にキャストする必要があると思います。

memcpy((void *)&RTCclk, (void *)&RTCclkBuffert, sizeof RTCclk);

また、角括弧なしでsizeofを使用します。変数でこれを使用できますが、RTCclkが配列として定義されている場合、sizeofは配列のフルサイズを返します。 typeでsizeofを使用する場合は、角括弧で使用する必要があります。

sizeof(struct RTCclk)
0
Alpha