按块填充字符数组

时间:2014-10-01 15:30:21

标签: c arrays casting

好奇心的问题 假设我有:

int main(void)
{
    char str[32];
    for (i = 0; i < 32; i++)
        str[i] = 0;
}

但我想要快4倍

int main(void)
{
    char str[32];
    for (i = 0; i < 32 / 4; i += 4)
        str[i] = (int)0;
}

我希望整个数组都会用零填充。 但是数组没有用零填充

我的问题:为什么数组没有被零填充?如何填充每个int块的数组?我的问题是研究c的功能,如何告诉编译器 - 写4个字节的块,即整数寄存器,它会将内存访问次数减少4倍,在x64处理器上减少8次

感谢所有人,顺利完成工作:

int main(int argc, char *argv[])
{
        char str[32];
        int i;
        for (i = 0; i < 32; i++)
                str[i] = 12;
        for (i = 0; i < 32 / sizeof(int); i++)
                ((int *) str)[i] = 0;
        printf("%d\n", i);
        for (i = 0; i < 32; i++)
                printf("%d\n", str[i]);
        return 0;
}

4 个答案:

答案 0 :(得分:4)

正确且最快的方法是将数组初始化为零

char str[32] = { 0 } ;

如果你想在之后将数组设置为零,那么使用memset并启用编译器优化和内部函数,编译器将找出将数组归零的最快方法。

memset( str , 0 , sizeof( str ) ) ;

答案 1 :(得分:1)

正如@ user2501所指出的,初始化为{0}或使用memset是最快捷正确的方法。

如果您想使用类似((int *)str)[i] = 0的内容,请不要这样做,这可能会导致访问不对齐。

作为memset的替代,在C99中(假设int是4个字节),您可以使用联合的类型惩罚功能:

#include <stdio.h>

typedef union {
    char as_string[32];
    int as_int[8];
} foo;

int main(void)
{
    foo x;
    int i;

    for (i = 0; i < 8; i++)
        x.as_int[i] = 0;
    for (i = 0; i < 32; i++)
        printf("%d", x.as_string[i]);
    printf("\n");
    return 0;
}

输出:

00000000000000000000000000000000

答案 2 :(得分:0)

似乎你被迫使用指针和强制转换,这个版本使用堆来为str正确对齐的地址分配int

#include <stdio.h>
#include <stdlib.h> /* malloc, free */
#include <stdint.h> /* intptr_t (pointer arithmetic using modulo division) */

#define MAX 32

int main(void)
{
    size_t i, align;
    char *ptr, *str;

    align = __alignof__(int);
    ptr = malloc(MAX + align);                 /* MAX + max align distance */ 
    str = ptr + align - (intptr_t)ptr % align; /* now str is properly aligned */
    for (i = 0; i < MAX / sizeof(int); i++)
        ((int *)str)[i] = 0;
    for (i = 0; i < MAX; i++)
        printf("%d\n", str[i]);
    free(ptr);
    return 0;
}

请注意,__alignof__gcc扩展名,如果您对__alignof感到满意,则Visual Studio如果您对_Alignof感到满意,则更改为C11 }。

答案 3 :(得分:-2)

您必须将指针强制转换为int,而不是值:

int main(void)
{
    char str[32];
    for (i = 0; i < 32/sizeof(int); i++)
       ((int *) str)[i] = 0xAABBCCDD; //Be careful of Endianness
}

可替换地:

int i;

union block_fill
{
    char arr[24];
    int iarr[6];
};

union block_fill block_arr;

for(i=0; i<6; i++)
    block_arr.iarr[i] = 0x11223344;

for(i=0; i<24; i++)
    printf("%x", block_arr.arr[i]);