40

sourcememcpy へのパラメーターとしてハードコードされた char 配列を渡したい...次のようなもの:

memcpy(dest, {0xE3,0x83,0xA2,0xA4,0xCB} ,5);

これを clang でコンパイルすると、次のエラーが発生します。

cccc.c:28:14: error: expected expression

それを次のように変更した場合 (余分な括弧を参照):

memcpy(dest,({0xAB,0x13,0xF9,0x93,0xB5}),5);

clang によって表示されるエラーは次のとおりです。

cccc.c:26:14: warning: incompatible integer to pointer
              conversion passing 'int' to parameter of
              type 'const void *' [-Wint-conversion]

cccc.c:28:40: error: expected ';' after expression
memcpy(c+110,({0xAB,0x13,0xF9,0x93,0xB5}),5);

だから、質問:

( http://www.cplusplus.com/reference/cstring/memcpy/ )のソースパラメータとしてハードコードされた配列を渡すにはどうすればよいですかmemcpy

私が試してみました:

(void*)(&{0xAB,0x13,0xF9,0x93,0xB5}[0])  - syntax error
{0xAB,0x13,0xF9,0x93,0xB5}               - syntax error
({0xAB,0x13,0xF9,0x93,0xB5})             - see above
(char[])({0xE3,0x83,0xA2,0xA4,0xCB})     - error: cast to incomplete type 'char []' (clang)

そして、ここに書くのが恥ずかしいいくつかの非常識な組み合わせ...

覚えておいてください:配列を保持するために新しい変数を作成したくありません。

4

4 に答える 4

44

C99 以降を使用する場合は、複合リテラルを使用できます。( N1256 6.5.2.5)

#include <stdio.h>
#include <string.h>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}

更新:-pedantic-errorsこれは GCC 上の C++03 および C++11 で機能しましたが、オプションで拒否されました。これは、これが標準 C++ の有効なソリューションではないことを意味します。

#include <cstdio>
#include <cstring>
int main(void){
    char dest[5] = {0};
    memcpy(dest, (const char[]){(char)0xE3,(char)0x83,(char)0xA2,(char)0xA4,(char)0xCB} ,5);
    for (int i = 0; i < 5; i++) printf("%X ", (unsigned int)(unsigned char)dest[i]);
    putchar('\n');
    return 0;
}

ポイントは次のとおりです。

  • 配列を const にしないと、一時配列のアドレスの取得が拒否されます。
  • 数値を明示的にキャストしcharないと、縮小変換が拒否されます。
于 2016-03-02T11:18:35.210 に答える
25

パラメータとして文字列を送信するだけです。うまくコンパイルできたようです。

#include <iostream>
#include <string.h>
using namespace std;

int main() {
    char dest[6] = {0};
    memcpy(dest,"\XAB\x13\XF9\X93\XB5", 5);

    return 0;
}
于 2016-03-02T11:22:00.213 に答える
20

最善の解決策は、これをまったく行うのではなく、一時変数を使用することです。

const char src[] = {0xE3,0x83,0xA2,0xA4,0xCB};
memcpy(dest, src, sizeof(src));

このコードには「マジック ナンバー」が含まれていないため、最もメンテナンスしやすく、複合リテラル バージョンのように配列項目の欠落や配列範囲外のバグが含まれていません。

このコードは、C++ および C90 とも互換性があります。

ここで最も重要なことは、生成されたマシン コードがいずれにしても同一であることを理解することです。複合リテラルを使用して何らかの最適化を行っているとは思わないでください。

于 2016-03-02T12:09:45.867 に答える
11

複合リテラルを使用できます。

int main()
{
    unsigned char dest[5];
    size_t i;

    memcpy(dest, (unsigned char[]){0xE3,0x83,0xA2,0xA4,0xCB} ,5);

    printf("Test: " );
    for(i=0; i<sizeof(dest)/sizeof(dest[0]); i++)
        printf("%02X - ", dest[i] );
    printf("\n");
    return 0;
}
于 2016-03-02T11:20:44.117 に答える