从C数组元素复制到一个不同的数组 [英] Copy elements from C array into a different array

查看:87
本文介绍了从C数组元素复制到一个不同的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我整理了在需要时已满再增加一倍大小循环缓冲区工作。不过,我有麻烦搞清楚如何元素从旧缓冲区拷贝到新的缓冲区。我的code是如下:

 的#define startSize 10
#定义fiveMin 300CBUF * cbuf_init(){    CBUF *缓冲区=的malloc(sizeof的(CBUF)+ 9 *的sizeof(报价));
    buffer-> currSize = 0;
    buffer-> MAXSIZE = startSize;
    // buffer-> startAt = 0;
    buffer->启动= 0;
    buffer->结束= 0;
    buffer-> freeSlots = startSize;
    // buffer-> currIndex = 0;
    返回缓冲区;
}无效cbuf_update(CBUF * cb_ptr,无符号整型时间,双率){
    如果(cb_ptr-> freeSlots == 0){
        的printf(扩大循环缓冲区\\ n!);
        CBUF * newBuffer =的malloc(sizeof的(CBUF)+ 19 *的sizeof(报价));
        newBuffer-> MAXSIZE = cb_ptr-> MAXSIZE * 2;
        newBuffer->开始= cb_ptr->启动;
        newBuffer->结束= cb_ptr->结束;
        newBuffer-> freeSlots = newBuffer-> MAXSIZE - cb_ptr-> MAXSIZE;
        INT X;
        为(X = 0; X&下; cb_ptr-> MAXSIZE; X ++){
            的printf(从槽%d个\\ n复印,X);
            的printf(目前时间复制:%d个\\ t率:%F \\ N,cb_ptr-> quoteBuffer [X]。时间,cb_ptr-> quoteBuffer [X] .rate);
            newBuffer-> quoteBuffer [X]。时间= cb_ptr-> quoteBuffer [X]。时间;
            newBuffer-> quoteBuffer [X] .rate = cb_ptr-> quoteBuffer [X] .rate;
        }
        cb_ptr = newBuffer;    }    //如果起始指针已到达阵列的端和还有空闲时隙后面的阵列,循环开始了。
    如果(cb_ptr->启动== cb_ptr-> MAXSIZE&放大器;&放大器; cb_ptr-> freeSlots大于0){
        cb_ptr->启动= 0;
    };    cb_ptr-> quoteBuffer [cb_ptr->开始]。时间=时间;
    cb_ptr-> quoteBuffer [cb_ptr->开始] .rate =率;
    cb_ptr->开始= cb_ptr->启动+1;
    cb_ptr-> freeSlots = cb_ptr-> freeSlots -1;    //如果比较时,目前的报价,其标记为空并且移动指针到底了一个阵列中的任何报价超过5分钟以上。
    //此外,清除了freeSlot。
    INT X;
    为(X = cb_ptr->结束; X≤(cb_ptr->启动); X ++){        如果((时间) - (cb_ptr-> quoteBuffer [X]。时间)GT = fiveMin){
            cb_ptr->结束= cb_ptr->结束+ 1;
            cb_ptr-> quoteBuffer [X]。时间= -1;
            cb_ptr-> quoteBuffer [X] .rate = -1.00;
            cb_ptr-> freeSlots = cb_ptr-> freeSlots +1;
        }
    }}
无效cbuf_dump(CBUF * cb_ptr){
    的printf(***** \\ t倾销\\ t ***** \\ n);    如果(cb_ptr->开始>&cb_ptr- GT端){
        INT X;
        为(X = cb_ptr->结束; X≤(cb_ptr->启动); X ++){
            的printf(%d个。)时间=%d个,使用\\ t率=%F \\ N,X(cb_ptr-> quoteBuffer [X]。时间)(cb_ptr-> quoteBuffer [X] .rate)) ;
        }
    }    / *
    如果启动指针已换回来绕到循环缓冲器的开始,那么最终指针必须比起始索引更大的索引。为此,我们需要从开始指针中的数据,从该端指向数组的末尾,然后将数据打印出到结束指针提供的数据不被标记为空(具有-1两个条目在报价结构)。
    * /
    如果(cb_ptr->结束> cb_ptr->启动){
        INT X;
        为(X = cb_ptr->结束; X< cb_ptr-> MAXSIZE; X ++){
            的printf(%d个。)时间=%d个,使用\\ t率=%F \\ N,X(cb_ptr-> quoteBuffer [X]。时间)(cb_ptr-> quoteBuffer [X] .rate)) ;
        }
        诠释Ÿ;
        对于(Y = 0; Y< cb_ptr->启动; Y ++){
            如果(cb_ptr-> quoteBuffer [Y]。时间!= -1){
                的printf(%d个。)时间=%d个,使用\\ t率=%F \\ N,Y(cb_ptr-> quoteBuffer [Y]。时间)(cb_ptr-> quoteBuffer [Y] .rate)) ;
            }
        }
    }    的printf(freeslots =%d个\\ N,cb_ptr-> freeSlots);
}诠释主(){    CBUF * CB1;    CB1 = cbuf_init();
    cbuf_update(CB1,60%,1.291);
    cbuf_update(CB1,63,1.287);
    cbuf_update(CB1,63,1.231);
    cbuf_update(CB1,69,1.229);
    cbuf_update(CB1,72,1.247);
    // cbuf_dump(CB1);
    cbuf_update(cb1,361,1.291);
    // cbuf_dump(CB1);    cbuf_update(CB1,411,1.291);
    // cbuf_dump(CB1);
    cbuf_update(CB1,412,1.281);
    cbuf_update(CB1,413,1.292);
    cbuf_update(CB1,414,1.284);
    // cbuf_dump(CB1);
    cbuf_update(CB1,414,1.290);
    // cbuf_dump(CB1);
    // cbuf_update(CB1,415,1.290);
    // cbuf_dump(CB1);    cbuf_update(CB1,511,1.241);
    cbuf_update(CB1,512,1.251);
    cbuf_update(CB1,513,1.232);
    cbuf_update(CB1,514,1.202);
    cbuf_update(CB1,517,1.119);
    cbuf_dump(CB1);
    返回0;}

问题是主,当它试图插入最后一个引号,需要扩大(最后一个引号之中:

  cbuf_update(CB1,517,1.119)

我的困惑是如何分配的newBuffer CBUF结构的cb_ptr缓冲区。它们都指向cbufs,但我怎么分配cb_ptr到newBuffer?

我的输出是目前:

 风琴循环缓冲区!
从插槽0复制
目前,复制时间:414价格:1.290000
从插槽1复制
目前,复制时间:511价格:1.241000
从插槽2复印
目前,复制时间:512价格:1.251000
从插槽3复制
目前,复制时间:513价格:1.232000
从插槽4复印
目前,复制时间:514价格:1.202000
从槽5复印
目前,复制时间:361价格:1.291000
从插槽6复印
目前,复制时间:411价格:1.291000
从槽7复制
目前,复制时间:412价格:1.281000
从插槽8复制
目前,复制时间:413价格:1.292000
从插槽9复制
目前,复制时间:414价格:1.284000
***** ***** DUMPING
freeslots = 0


解决方案

除阵列(其衰减到一个指向他们的基地)的所有的用C必须按地址传递,如果你想修改它,包括指针的。其他任何事情一样,声明该参数是指向要修改(在这种情况下,这将是一个指针的指针到CBUF),再传给发送方<​​/ p指针的地址类型>

我能想到的您code最起码的变化是:

 无效cbuf_update(CBUF ** cb_pptr,无符号整型时间,双速率)
{
    //提取存储在输入/输出参数指针值
    CBUF * cb_ptr = * cb_pptr;    如果(cb_ptr-&GT; freeSlots == 0)
    {
        的printf(扩大循环缓冲区\\ n!);
        CBUF * newBuffer =的malloc(sizeof的(CBUF)+ 19 *的sizeof(报价));
        newBuffer-&GT; MAXSIZE = cb_ptr-&GT; MAXSIZE * 2;
        newBuffer-&GT;开始= cb_ptr-&GT;启动;
        newBuffer-&GT;结束= cb_ptr-&GT;结束;
        newBuffer-&GT; freeSlots = newBuffer-&GT; MAXSIZE - cb_ptr-&GT; MAXSIZE;
        INT X;
        为(X = 0; X&下; cb_ptr-&GT; MAXSIZE; X ++){
            的printf(从槽%d个\\ n复印,X);
            的printf(目前时间复制:%d个\\ t率:%F \\ N,cb_ptr-&GT; quoteBuffer [X]。时间,cb_ptr-&GT; quoteBuffer [X] .rate);
            newBuffer-&GT; quoteBuffer [X]。时间= cb_ptr-&GT; quoteBuffer [X]。时间;
            newBuffer-&GT; quoteBuffer [X] .rate = cb_ptr-&GT; quoteBuffer [X] .rate;
        }
        免费(cb_ptr);
        * cb_pptr = cb_ptr = newBuffer;
    }    //如果起始指针已到达阵列的端和还有空闲时隙后面的阵列,循环开始了。
    如果(cb_ptr-&GT;启动== cb_ptr-&GT; MAXSIZE&放大器;&放大器; cb_ptr-&GT; freeSlots大于0){
        cb_ptr-&GT;启动= 0;
    };    cb_ptr-&GT; quoteBuffer [cb_ptr-&GT;开始]。时间=时间;
    cb_ptr-&GT; quoteBuffer [cb_ptr-&GT;开始] .rate =率;
    cb_ptr-&GT;开始= cb_ptr-&GT;启动+1;
    cb_ptr-&GT; freeSlots = cb_ptr-&GT; freeSlots -1;    //如果比较时,目前的报价,其标记为空并且移动指针到底了一个阵列中的任何报价超过5分钟以上。
    //此外,清除了freeSlot。
    INT X;
    为(X = cb_ptr-&GT;结束; X≤(cb_ptr-&GT;启动); X ++){        如果((时间) - (cb_ptr-&GT; quoteBuffer [X]。时间)GT = fiveMin){
            cb_ptr-&GT;结束= cb_ptr-&GT;结束+ 1;
            cb_ptr-&GT; quoteBuffer [X]。时间= -1;
            cb_ptr-&GT; quoteBuffer [X] .rate = -1.00;
            cb_ptr-&GT; freeSlots = cb_ptr-&GT; freeSlots +1;
        }
    }
}

相信我,它不会比这更最小的变化。不幸的是,你将不得不改变所有的更新调用。不解决这个越来越。他们会采取这种形式:

  cbuf_update(安培; CB1,60,1.291);

如果你这个东西回发送方,免费为正常:

 免费(CB1);

希望是有道理的。绝对探索的memcpy()的美德的实际数据副本。这将使其大​​大减少杂乱。

I am finishing up working on a circular buffer that needs to double it size when it becomes full. However, I am having trouble figuring out how to copy the elements from the old buffer into the new buffer. My code is as follows:

#define startSize 10
#define fiveMin 300

cbuf* cbuf_init(){

    cbuf *buffer = malloc(sizeof(cbuf) + 9 * sizeof(quote));
    buffer->currSize = 0;
    buffer->maxSize = startSize;
    //buffer->startAt = 0;
    buffer->start = 0;
    buffer->end = 0;
    buffer->freeSlots = startSize;
    //buffer->currIndex = 0;
    return buffer;
}

void cbuf_update(cbuf *cb_ptr, unsigned int time, double rate){


    if(cb_ptr->freeSlots == 0){
        printf("EXPANDING CIRCULAR BUFFER!\n");
        cbuf *newBuffer = malloc(sizeof(cbuf) + 19 * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int x;
        for(x = 0; x < cb_ptr->maxSize; x ++){
            printf("Copying from slot %d\n", x);
            printf("Currently Copying time: %d\t Rate: %f\n", cb_ptr->quoteBuffer[x].time, cb_ptr->quoteBuffer[x].rate);
            newBuffer->quoteBuffer[x].time = cb_ptr->quoteBuffer[x].time;
            newBuffer->quoteBuffer[x].rate = cb_ptr->quoteBuffer[x].rate;
        }
        cb_ptr = newBuffer;

    }

    //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.   
    if(cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0){
        cb_ptr->start = 0;
    };

    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
    //Also, clear up a freeSlot.
    int x;
    for(x = cb_ptr->end; x < (cb_ptr->start); x ++){

        if((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin){
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }



}


void cbuf_dump(cbuf *cb_ptr){
    printf("*****\t DUMPING \t*****\n");

    if(cb_ptr->start > cb_ptr->end){
        int x;
        for(x = cb_ptr->end; x<(cb_ptr->start); x++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
    }

    /*
    If the start pointer has been wrapped back around to the beginning of the circular buffer, then the end pointer must be at an index that is         greater than the start index. For this, we need to print out the data ranging from the end pointer to the end of the array, and then the        data from the start pointer to the end pointer provided the data isn't flagged as null (having -1 for both entries in the quote struct).
    */
    if(cb_ptr->end > cb_ptr->start){
        int x;
        for(x=cb_ptr->end; x < cb_ptr->maxSize; x ++){
            printf("%d.) time = %d, \t rate = %f\n",x,(cb_ptr->quoteBuffer[x].time),(cb_ptr->quoteBuffer[x].rate));
        }
        int y;
        for(y = 0; y < cb_ptr->start; y ++){
            if(cb_ptr->quoteBuffer[y].time != -1){
                printf("%d.) time = %d, \t rate = %f\n",y,(cb_ptr->quoteBuffer[y].time),(cb_ptr->quoteBuffer[y].rate));
            }
        }
    }

    printf("freeslots = %d\n", cb_ptr->freeSlots);
}

int main(){

    cbuf *cb1 ;

    cb1 = cbuf_init() ;
    cbuf_update(cb1, 60, 1.291) ;
    cbuf_update(cb1, 63, 1.287) ;
    cbuf_update(cb1, 63, 1.231) ;
    cbuf_update(cb1, 69, 1.229) ;
    cbuf_update(cb1, 72, 1.247) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1,361,1.291);
    //cbuf_dump(cb1);

    cbuf_update(cb1, 411, 1.291) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1, 412, 1.281) ;
    cbuf_update(cb1, 413, 1.292) ;
    cbuf_update(cb1, 414, 1.284) ;
    //cbuf_dump(cb1);
    cbuf_update(cb1, 414, 1.290) ;
    //cbuf_dump(cb1);
    //cbuf_update(cb1, 415, 1.290) ;
    //cbuf_dump(cb1);

    cbuf_update(cb1, 511, 1.241) ;
    cbuf_update(cb1, 512, 1.251) ;
    cbuf_update(cb1, 513, 1.232) ;
    cbuf_update(cb1, 514, 1.202) ;
    cbuf_update(cb1, 517, 1.119) ;
    cbuf_dump(cb1);
    return 0;

}

The issue is in main when it tries to insert the last quote and needs to expand (the last quote being:

cbuf_update(cb1, 517, 1.119)

My confusion is how to assign the newBuffer cbuf struct to the cb_ptr buffer. They are both pointers to cbufs, but how do I assign cb_ptr to the newBuffer?

My output is currently:

EXPANDING CIRCULAR BUFFER!
Copying from slot 0
Currently Copying time: 414  Rate: 1.290000
Copying from slot 1
Currently Copying time: 511  Rate: 1.241000
Copying from slot 2
Currently Copying time: 512  Rate: 1.251000
Copying from slot 3
Currently Copying time: 513  Rate: 1.232000
Copying from slot 4
Currently Copying time: 514  Rate: 1.202000
Copying from slot 5
Currently Copying time: 361  Rate: 1.291000
Copying from slot 6
Currently Copying time: 411  Rate: 1.291000
Copying from slot 7
Currently Copying time: 412  Rate: 1.281000
Copying from slot 8
Currently Copying time: 413  Rate: 1.292000
Copying from slot 9
Currently Copying time: 414  Rate: 1.284000
*****    DUMPING    *****
freeslots = 0

解决方案

Save for arrays (which decay to a pointer to their base), everything in C must be passed by address if you want to modify it, including pointers. Like anything else, declare the parameter to be a pointer to the type you want to modify (in this case it will be a pointer to a pointer-to-cbuf), then pass the address of the pointer on the caller side

The most minimal change I can think of for your code would be:

void cbuf_update(cbuf **cb_pptr, unsigned int time, double rate)
{
    // extract pointer value stored in in/out parameter
    cbuf *cb_ptr = *cb_pptr;

    if(cb_ptr->freeSlots == 0)
    {
        printf("EXPANDING CIRCULAR BUFFER!\n");
        cbuf *newBuffer = malloc(sizeof(cbuf) + 19 * sizeof(quote));
        newBuffer->maxSize = cb_ptr->maxSize * 2;
        newBuffer->start = cb_ptr->start;
        newBuffer->end = cb_ptr->end;
        newBuffer->freeSlots = newBuffer->maxSize - cb_ptr->maxSize;
        int x;
        for(x = 0; x < cb_ptr->maxSize; x ++){
            printf("Copying from slot %d\n", x);
            printf("Currently Copying time: %d\t Rate: %f\n", cb_ptr->quoteBuffer[x].time, cb_ptr->quoteBuffer[x].rate);
            newBuffer->quoteBuffer[x].time = cb_ptr->quoteBuffer[x].time;
            newBuffer->quoteBuffer[x].rate = cb_ptr->quoteBuffer[x].rate;
        }
        free(cb_ptr);
        *cb_pptr = cb_ptr = newBuffer;
    }

    //If the start pointer has reached the end of the array and there are still free slots back at the beginning of the array, loop back.
    if(cb_ptr->start == cb_ptr->maxSize && cb_ptr->freeSlots > 0){
        cb_ptr->start = 0;
    };

    cb_ptr->quoteBuffer[cb_ptr->start].time = time;
    cb_ptr->quoteBuffer[cb_ptr->start].rate = rate;
    cb_ptr->start = cb_ptr->start +1;
    cb_ptr->freeSlots = cb_ptr->freeSlots -1;

    //If any quote in the array is older than 5 minutes when compared to the current quote, flag it as null and move the end pointer up one.
    //Also, clear up a freeSlot.
    int x;
    for(x = cb_ptr->end; x < (cb_ptr->start); x ++){

        if((time) - (cb_ptr->quoteBuffer[x].time) >= fiveMin){
            cb_ptr->end = cb_ptr->end + 1;
            cb_ptr->quoteBuffer[x].time = -1;
            cb_ptr->quoteBuffer[x].rate = -1.00;
            cb_ptr->freeSlots = cb_ptr->freeSlots +1;
        }
    }
}

Believe me, it won't get much more minimal-change than that. Unfortunately you will have to change all the update calls. No getting around that. They will take this form:

cbuf_update(&cb1, 60, 1.291);

If you free this thing back on the caller side, free as normal:

free(cb1);

Hope that makes sense. Definitely explore the virtues of memcpy() for your actual data-copy. It will make it considerably less cluttered.

这篇关于从C数组元素复制到一个不同的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆