我目前正在努力了解一系列结构是如何运作的。供参考,这是完整的代码。
#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));
其次,在这种情况下使用memcpy
或memmove
会更有效吗?
答案 0 :(得分:1)
memcpy
正试图移动数组的一部分,以便为新项目腾出空间。在视觉上,它正在这样做:
其中
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));