基于C

时间:2016-06-25 07:07:13

标签: c

我目前正在努力了解一系列结构是如何运作的。供参考,这是完整的代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 14
/******************************************************************
 * Data Structure Definition                                      *
 ******************************************************************/
typedef struct {
  unsigned int prodID;    /*  product ID, uniquely identifies an element */ 
  char prodDesc[50];      /*  product description*/  
  float prodPrice;        /*  product price*/  
  int prodQty;            /* product count or quantity  */
}product, products[SIZE];                 /* product record */

typedef struct cell {
   products item;             /* array of products */
   int prodCtr;           /* number of products in the list */
}*chocoList;              /*  Definition of the ADT List ver 2 */  

typedef enum {
    TRUE, FALSE
}boolean;

/******************************************************************
 * Function Prototypes                                            *
 ******************************************************************/
void initializeList(chocoList *L);             
void populateSortedList(chocoList L);         
void displayList(chocoList L, char * listName);
void displayProduct(product X);                 
int insertSorted(chocoList L, product X);    
product deleteFirstOccurence(chocoList L, float prodPrice);

int main(void) 
{
    chocoList  L;      /* sorted List  */
    product deleted;     /* container for the deleted record */

    /*---------------------------------------------------------------------------------
    * Problem #1 :: Initialize the choco list. Display the products in the list after* 
    * calling populateSortedList().                                                  *
    * printf("\n\n\nProblem #1:: ");                                                 *
    *--------------------------------------------------------------------------------*/
    printf("\n\n\nProblem #1:: ");
    initializeList(&L); 
    populateSortedList(L);
    displayList(L, "Problem 1");

    /*---------------------------------------------------------------------------------
    * Problem #2 :: Delete 1 product from the list by calling deleteFirstOccurence(). * 
    * Display the returned product record by calling displayProduct().               *
    * printf("\n\n\nProblem #2:: ");                                                 *
    *--------------------------------------------------------------------------------*/
    printf("\n\n\nProblem #2:: ");     
    deleted = deleteFirstOccurence(L, 75.50);
    displayProduct(deleted);

    /*---------------------------------------------------------------------------------
    * CHALLENGE :: Redo Problem #s 1 & 2 using either versions 3 or 4                       *
    * Keep in mind the changes when converting the ADT List Versions                 *
    *--------------------------------------------------------------------------------*/

    getch();
    return 0;
}

/****************************************************************************************
 * This function initializes the list for its first use.                                     *
 ****************************************************************************************/
void initializeList(chocoList *L)
{
    *L = (chocoList)malloc(sizeof(struct cell));
    (*L)->prodCtr = 0;
}

/****************************************************************************************
 * This function populates the list by calling insertSorted().                          *
 ****************************************************************************************/
void populateSortedList(chocoList L)
{
    int x, result = 1;

    product data[] = {  {1501, "Hersheys", 100.50, 10},
                                {1502, "Hersheys Almond", 100.50, 15},
                                {1503, "Hersheys Krackel", 100.50, 15},
                                {1701, "Toblerone", 150.75, 20},
                                {1702, "Toblerone Milk", 150.75, 40},
                                {1703, "Toblerone Honey", 150.75, 10},
                                {1550, "Cadbury", 200.00, 30},
                                {1201, "Kitkat", 97.75, 40},
                                {1450, "Ferrero", 150.50, 50},
                                {1601, "Meiji", 75.50, 60},
                                {1301, "Nestle", 124.50, 70},
                                {1525, "Lindt", 175.50, 80},
                                {1545, "Valor", 100.50, 90},
                                {1455, "Tango", 49.50, 100}
                    };
    for(x = 0; x < 10 && result == 1; x++){
        result = insertSorted(L, data[x]);
    }                 
}

/****************************************************************************************
 * This function display the details of all products in the list.                       *
 ****************************************************************************************/            
void displayList(chocoList L, char * listName) 
{
    int x;
    system("CLS");       /* clears the screen before displaying succeeding lines */

    if(L->prodCtr != 0){
        printf("\nElements of the Product List %s:", listName);
        printf("\n\n%-10s%-15s%10s%10s","ID","Description","Price","Quantity");
        printf("\n%-10s%-15s%10s%10s","--","-----------","-----","--------");

        for(x = 0 ; x < L->prodCtr; x++){
            printf("\n%-10d", L->item[x].prodID);
            printf("%-15s", L->item[x].prodDesc);   
            printf("%10.2f", L->item[x].prodPrice);
            printf("%10d", L->item[x].prodQty);     
        }
    }else{
        printf("\n\tChoco list is currently empty!\n");
    }

    printf("\n\n Press any key to continue . . . ");
    getch();
}

/****************************************************************************************
 * This function inserts a product X in an alphabetically sorted list according to its  *
 * product description. It returns a value of 1 for successful insertion. Otherwise, 0. *
 * Use memcpy() in shifting the elements downward to provide space for the new product. *
 ***************************************************************************************/
int insertSorted(chocoList L, product X)
{
    int ctr;
    if(L->prodCtr<14){
        for(ctr=0; ctr<L->prodCtr && strcmp(L->item[ctr].prodDesc, X.prodDesc)<0;ctr++){    }
        memcpy(L->item + ctr + 1, L->item + ctr, sizeof(product) * (L->prodCtr - ctr));
        L->item[ctr] = X;
        L->prodCtr++;
        ctr = 1;
    }
    else{
        ctr = 0;
    }
    return ctr;
}

/****************************************************************************************
 * This function deletes the first occurence of a product given the prodPrice.It returns* 
 * the product record ones it is found. Otherwise, it returns a dummy record containing *
 * "XXX" for string values and 0 for integer and float values.  Use memcpy() in shifting *
 * the elements upward to avoid having empty indices within the array.                       *
 ***************************************************************************************/
product deleteFirstOccurence(chocoList L, float prodPrice)
{
    int ctr;
    product dummy;
    strcpy(dummy.prodDesc , "XXX");
    dummy.prodID = 0;
    dummy.prodPrice = 0;
    dummy.prodQty = 0;
    for(ctr = 0; ctr<L->prodCtr && L->item[ctr].prodPrice != prodPrice; ctr++){ }
    if(ctr!=L->prodCtr){
        dummy = L->item[ctr];
        memcpy(L->item + ctr, L->item + ctr + 1, sizeof(product) * (L->prodCtr - ctr));
        L->prodCtr--;
    }
    return dummy;
}

/****************************************************************************************
 * This function display the details of 1 product.                                       *
 ***************************************************************************************/
void displayProduct(product X)
{
    //system("CLS");       /* clears the screen before displaying succeeding lines */
    printf("\n\nElements of Product %d:", X.prodID);
    printf("\n\n%-10s%-15s%10s%10s","ID","Description","Price","Quantity");
    printf("\n%-10s%-15s%10s%10s","--","-----------","-----","--------");

    printf("\n%-10d", X.prodID);
    printf("%-15s", X.prodDesc);    
    printf("%10.2f", X.prodPrice);
    printf("%10d", X.prodQty);      

    printf("\n\n Press any key to continue . . . ");
    getch();    
}

我特别对这部分提出了几个问题:

int insertSorted(chocoList L, product X)
{
    int ctr;
    if(L->prodCtr<14){
        for(ctr=0; ctr<L->prodCtr && strcmp(L->item[ctr].prodDesc, X.prodDesc)<0;ctr++){    }
        memcpy(L->item + ctr + 1, L->item + ctr, sizeof(product) * (L->prodCtr - ctr));
        L->item[ctr] = X;
        L->prodCtr++;
        ctr = 1;
    }
    else{
        ctr = 0;
    }
    return ctr;
}

首先,有人可以向我解释这个陈述吗?

memcpy(L->item + ctr + 1, L->item + ctr, sizeof(product) * (L->prodCtr - ctr));

其次,在这种情况下使用memcpymemmove会更有效吗?

2 个答案:

答案 0 :(得分:1)

memcpy正试图移动数组的一部分,以便为新项目腾出空间。在视觉上,它正在这样做:

enter image description here

其中

  • green是数组中不需要移动的项目
  • blue是需要移动以为新项目腾出空间的项目
  • white是数组中未使用的项目
  • 黄色是新项目X

为了这个例子,我选择了这些值:

  • L->prodCtr最初为6
  • for循环将ctr设置为3

所以memcpy应该如何运作。第一个参数(L->item + ctr + 1)是目标地址,即移动后 后第一个蓝色项 的地址。第二个参数L->item + ctr是源地址,它是移动前 之前的第一个蓝色项 的地址。第三个论点由两部分组成。 sizeof(product)是每个项目的大小(以字节为单位)。 (L->prodCtr - ctr)是需要移动的项目数。将它们相乘以获得要移动的字节数。

这就是memcpy应该做的事情。但是,要回答第二个问题, 不能 使用memcpy来执行此操作。原因是memcpy仅在源和目标 不重叠 时才有效。另一方面,memmove即使源和目标重叠也能保证正常工作。所以这里没有任何选择,你必须使用memmove

答案 1 :(得分:0)

  

首先,有人可以向我解释这个陈述吗?

memcpy(L->item + ctr + 1, L->item + ctr, sizeof(product) * (L->prodCtr - ctr));

简单地memcpy()函数正在将sizeof(product) * (L->prodCtr - ctr)位置的大小(L->item + ctr)的内容复制到下一个位置,即(L->item + ctr + 1)。平均相同的内容将从(L->item + ctr + 1)

开始复制到下一个位置

<强>释

memcpy用于那些您不想将结构中每个成员的值复制到另一个结构手动的地方,尤其是当成员是嵌套结构和指针时。

struct student 
{
unsigned int marks;
unsigned int reg;
};


struct student mazhar, abbas; 
mazhar.reg = 50;
mazhar.marks = 800;

/* First way. Manually Copy value of each member to destination structure */

abbas.reg = mazhar.reg;
abbas.marks = mazhar.marks;

/* Above method is useful when struct members are not too much. 
   But when you have many members of the structure i.e. like nested 
   structures etc. then you can use memcpy function. */ 

memcpy(&abbas, &mazhar, sizeof(struct student));