使用指向文字的指针访问指针

时间:2015-02-19 13:37:01

标签: c arrays literals

我必须为数组写一些文字,但我只有数组的地址,所以我首先创建一个本地数组,用文字填充它,然后将内容复制到目标数组。这是一个例子:

void example(char *array) {
    char temp[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };    
    memcpy(array, temp, sizeof(temp));
}

这很好用,但我正在寻找一种在一行而不是两行内做同样事情的方法。有谁知道如何做到这一点?

5 个答案:

答案 0 :(得分:5)

我写这个答案是因为你评论说你想在一行中做这个,以避免让#34; 访问许多指针"。但是你没赢。任何体面的编译器都会优化它。带有-O1的GCC会在x86_64上为您的示例生成此代码,不会更改。它甚至不会拨打memcpy

example:
.LFB12:
    .cfi_startproc
    movb    $1, (%rdi)
    movb    $2, 1(%rdi)
    movb    $3, 2(%rdi)
    movb    $4, 3(%rdi)
    movb    $5, 4(%rdi)
    movb    $6, 5(%rdi)
    movb    $7, 6(%rdi)
    movb    $8, 7(%rdi)
    ret
    .cfi_endproc

要解释:$1$2等是文字的元素,%rdi是包含example的第一个参数的寄存器,即您指定的指针{ {1}}。

只需使用两条可读行。

答案 1 :(得分:3)

这比你的代码的可读性差,我会说,但如果你只是必须在一行中做到......

memcpy(array, "\x01\x02\x03\x04\x05\x06\x07\x08", sizeof("\x01\x02\x03\x04\x05\x06\x07\x08") - 1);

答案 2 :(得分:2)

您可以使用复合文字:

memcpy(array, (char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
       sizeof ((char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}));

您可以使用define来重复数组(如果您必须修改数组元素,则更容易出错):

#define ARRAY  ((char []) {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08})

memcpy(array, ARRAY, sizeof ARRAY); 

答案 3 :(得分:2)

编写代码的规范方法是:

void example(char *array) {
    static const char temp[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };    
    memcpy(array, temp, sizeof(temp));
}

这是非常易读的,也是最快的,因为每个函数调用都不会在堆栈上分配本地常量。但是,当然,编译器可能无论如何都会优化。

没有理由尝试进一步手动优化此代码。字符串文字将使代码更难阅读。复合文字将具有局部范围,理论上在每个函数调用的堆栈上分配,这将使代码在理论上变慢 - 实际上编译器可能会优化复合文字,以便它不会被压缩到堆栈上功能调用。

如果有几个函数需要使用相同的常量,那么在文件范围内声明它,但保留它static const,这样就不会使全局命名空间不必要地混乱。

答案 4 :(得分:1)

假设机器是LSB

*(unsigned long long *)array = 0x0807060504030201;

P.S。好吧,不要太认真; - )

P.P.S。让我在函数内部使用char[](而不是static char[])引入另一个论点。

虽然优化编译器可以有时排除恼人的堆栈变量,但它并不总是可行的。例如,考虑调用其他一些函数,比如printf("%s", temp)。它看起来很无辜,但是,由于printf的第二个参数不称为const,编译器必须创建整个数组的副本temp传递给printf之前,在堆栈上添加{{1}}。

对于某些大型阵列,这可能真的很痛苦!