如何将数组的内容复制到两个大小不等的较小数组中

时间:2019-02-20 13:23:27

标签: c arrays

我正在尝试将一个较大数组的内容复制到两个各自大小不相等的较小数组(其大小可能会根据程序而变化)。我在下面的简化代码中有四个数组:

#define size 20
double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};
/*IndicatorArray is associated to bigArray as follows:
 if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};
double array10[count10], array20[count20]; /*count10 and count20 are 
counters from indicatorArray passed as a size of each array 
in earlier function not shown here*/
for (i=0;i<size;i++){
        if (indicatorArray[i]==10) {
            arr10[i]=bigArray[i];
        //  printf("%lf ",arr10[i]); /*this shows me correct results*/
        }
        else {
            arr20[i]=bigArray[i];
        }
    }
    for (i=0;i<count10;i++){
        printf("%lf ",arr10[i]);
    }
    printf("\n \n");
    for (i=0;i<count20;i++){
        printf("%lf ",arr20[i]);
    }

结果类似于

00.0000 00.0000 9.555 8.564 11.123 14.666 ....

14.553 13.653 00.000 ...... 00.000

但是我不希望出现零或结果中断,但是类似

9.55 8.564 ...... 7.123 和 14.533 13.653 ..... 11.123

为什么会发生这种情况以及如何以正确的方式做到这一点?

3 个答案:

答案 0 :(得分:3)

如注释中所述,在拆分数组的内容时,请识别每个元素都位于内存中特定的可寻址位置,这对于 memcpy() 而言是一项完美的工作。这是使用该概念的简单示例:

int main(void)
{
    double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5};
    double split1[3];
    double split2[7];

    memcpy(split1, &source[0], 3*sizeof(double));
    memcpy(split2, &source[3], 7*sizeof(double));

    return 0;   
}

如果您的项目具有在运行时已知的定义明确的静态参数,则可以使用一些常见的宏和一些其他变量,这可以变得更加通用。

下面的示例与上面的示例基本相同,但是循环地,可能是更适应的构造。

#define SPLIT_CNT 3

int main(void)
{
    double source[] = {3.4,5.6,2.3,4.5,6.7,8.9,10.1,11.1,12.3,4.5,8.5,9.5};
    double split1[3];                         // arrays if differing sizes
    double split2[7];
    double split3[2];
    size_t start_pos;                         //position accumulator
    size_t cpy_len[SPLIT_CNT] = {3,7,2};      //known array sections
    double *split[] = {split1,split2,split3}; //enables looping on arrays of differing sizes
    start_pos = 0;
    for(int i=0;i<SPLIT_CNT;i++)
    {
        if(i > 0)start_pos += cpy_len[i-1]; //move the start postition  
        memcpy(split[i], &source[start_pos], sizeof(double)*cpy_len[i]);
    }

    return 0;   
}

答案 1 :(得分:1)

正如一些programmerdude所评论的那样,您应该在复制数据时考虑使用memcpy。如果仍然要使用实现,则问题出在for循环中如何使用i。请记住,在这种情况下,i将是您要复制的数字出现在大数组中的位置。如果您希望从大数组复制的第一个元素位于较小数组之一的位置0,那么如果您使用arr10[i]arr20[i],则两种方法都不会发生。取而代之的是,您可以为每个较小的数组使用一个计数器,并在元素每次进入数组时递增。这是一个在对一些值进行硬编码之后使用在线编译器完成的简单示例:

int arr10Count = 0;
int arr20Count = 0;

int i;
for (i=0;i<size;i++){
        if (indicatorArray[i]==10) {
            arr10[arr10Count]=bigArray[i];
            arr10Count++;
        //  printf("%lf ",arr10[i]); /*this shows me correct results*/
        }
        else {
            arr20[arr20Count]=bigArray[i];
            arr20Count++;
        }
    }

答案 2 :(得分:0)

array10array20中的索引使用单独的计数器。

#define size 20

double bigArray[size]={14.553,13.653,9.555,8.564..and so on...9.324,11.123};

/*IndicatorArray is associated to bigArray as follows:
 if bigArray[i]<10 then indicatorArray[i]=10 else =20 */
int indicatorArray[size]={20,20,10,10,..and so on..};

double array10[count10], array20[count20]; /*count10 and count20 are 
counters from indicatorArray passed as a size of each array 
in earlier function not shown here*/

size_t i10; /* index for array10 *** */
size_t i20; /* index for array20 *** */

for (i=0, i10=0, i20=0; i<size; i++){
        if (indicatorArray[i]==10) {
            if(i10 < count10) { /* prevent array index out of range *** */
                arr10[i10++]=bigArray[i];
            }
        }
        else {
            if(i20 < count20) { /* prevent array index out of range *** */
                arr20[i20++]=bigArray[i];
            }
        }
    }
    for (i=0;i<count10;i++){
        printf("%lf ",arr10[i]);
    }
    printf("\n \n");
    for (i=0;i<count20;i++){
        printf("%lf ",arr20[i]);
    }