我已经使用这段代码三天了。问题是我已经达到了谷底,我不知道如何在没有你们帮助的情况下解决这个问题。我有一个结构类型为char name,surname,persnbr的数组。
struct pers
{
char name[7];
char last_name[10];
char id_nbr[12];
};
我已经解决了在数组中添加名字姓氏和persnbr的问题,但现在我不知道如何删除它们。
这是queueEn函数
void queueEn(person p1){
strcpy(queue[last].name, p1.name);
strcpy(queue[last].last_name, p1.last_name);
strcpy(queue[last].id_nbr, p1.id_nbr);
}
和queueAdd函数
void queueAdd(person person1)
{
if(last<MAX_SIZE_QUEUE){
printf("Name: ");
scanf("%s", person1.name);
printf("Last name: ");
scanf("%s", person1.sur_name);
printf("Id-number: ");
scanf("%s", person1.id_nbr);
last++;
}else {
printf("Queue is full\n");
}
queueEn(person1);
}
此代码效果很好。
现在我有功能queueDe
和queueRemove
这是我到目前为止所做的:
void queueDe(person *personPoint){
first = (first + 1)% MAX_SIZE_QUEUE;
*personPoint = queue[first];
strcpy(personPoint->name, queue[first].name);
strcpy(personPoint->last_name, queue[first].last_name);
strcpy(personPoint->id_nbr, queue[first].id_nbr);
}
问题是我必须从数组中复制信息,所以我假设你是这样做的。该信息将显示给用户(队列中的最后一个人(FIFO结构))
这是函数remove_from_queue
void queueRemove(person personRem){
if(first < MAX_SIZE_QUEUE){
printf("Name: %s", personRem.name);
printf("Last Name: %s", personRem.last_name);
printf("Id-Number: %s", personRem.id_nbr);
first++;
}else{
printf("Queue is empty");
}
queueDe(&personRem);
}
变量first和last与数组的结尾和数组的开头是等价的。要删除数组中的最后一个人,我必须首先删除该人。两个变量在开始时初始化为0。我已经读过我需要将指针* personPoint初始化为malloc但我不知道如何在这种特定情况下使用它。
当我执行程序并想要删除该人时,没有任何事情发生。
我很感谢你的回答。
答案 0 :(得分:1)
循环队列是一种合理的数据结构,但您需要清楚地掌握队列的“空”和队列“完整”条件。首先,我们将定义一个循环队列结构,它包含first,last和queue []数组元素,
typedef struct circular_array_queue_s
{
person* queue[MAX_SIZE_QUEUE];
int first;
int last;
} CirQueue;
CirQueue cirq;
现在我们可以定义函数来报告队列是空的,是否已满,并报告元素数量的计数,
int queueEmpty()
{
if( cirq.first == cirq.last ) //queue empty
{
printf("Queue is empty");
return 1;
}
return 0;
}
int queueFull()
{
if( ((cirq.last+1%MAX_SIZE_QUEUE)) == cirq.first ) //queue full
{
printf("Queue is full\n");
return 1;
}
return 0;
}
int queueCount()
{
int count=0;
if( cirq.first<=cirq.last )
count=(cirq.last-cirq.first);
else //if ( cirq.first>cirq.last )
count=(cirq.last+MAX_SIZE_QUEUE)-cirq.first;
return count;
}
排队和出队的队列操作被简化,因为您在队列的最后位置入队,并从队列的第一个位置出队。由于你有一个循环队列,移动第一个和最后一个索引是通过递增一个,然后换行(使用模数MAX_SIZE_QUEUE)来完成的,
person*
queueEn(person* p)
{
//err
if( queueFull() ) { return NULL; } //queue full, fail
cirq.queue[cirq.last] = p;
cirq.last = (cirq.last+1)%MAX_SIZE_QUEUE; //one
return p;
}
person*
queueDe()
{
person* p;
//err
if( queueEmpty() ) { return NULL; } //queue empty, fail
p = cirq.queue[cirq.first];
cirq.queue[cirq.first] = NULL;
cirq.first = (cirq.first+1)%MAX_SIZE_QUEUE;
return p;
}
可以使用类似于
的函数完成整个行走(迭代)person*
queueIterate()
{
person* p;
int iter;
if( queueEmpty() ) { return NULL; } //queue empty, skip
for( iter=cirq.first; iter!=cirq.last; iter=(++iter)%MAX_SIZE_QUEUE )
{
personPrint(p = cirq.queue[iter]);
}
return p;
}
向队列中添加元素需要您创建要添加的元素(malloc),并在删除元素时正确处理元素(免费),
void queueAdd(person person1)
{
if( queueFull() ) { return; } //queue full, cannot add
personRead(&person1);
person* p;
queueEn(personCopy(p=personNew(),&person1));
}
person*
queueRemove(person* personRem)
{
person* p;
if(p = queueDe())
{
if(personRem) {
personCopy(personRem,p); personDel(p);
}
//if you don't give a personRem, you must free person p removed from queue
else
personRem=p;
}
return personRem;
}
您想测试这些队列函数,
int
main()
{
person per;
person* perp;
int done=0;
while(!done)
{
queueAdd(per);
if( queueFull() ) done=1;
if( queueCount() >= 3 ) done=1; //just do three
}
queueIterate();
while(!queueEmpty())
{
personPrint(perp=queueRemove(&per));
}
}
请理解C字符串以空值终止,因此使用N + 1惯用语句声明char []将清楚地传达可用的字符串大小,
typedef struct person_s
{
char name[9+1]; //size to N+1, makes clear the space, "Alexander"(9)
char last_name[10+1]; //room for null-terminator
char id_nbr[12+1]; //you really want to room for null-terminator
} person;
您会发现,拥有封装您的成员访问权限的函数可以使您的代码更具可读性,并支持DRY(不要重复自己)方法,并隐藏您可能不希望在任何地方公开和处理的细节,
person*
personNew()
{
person* pnew;
if( !(pnew=malloc(sizeof(person))) ) return NULL;
strncpy(pnew->name, ">name", sizeof(pnew->name));
strncpy(pnew->last_name, ">last_name", sizeof(pnew->last_name));
strncpy(pnew->id_nbr, ">id_nbr", sizeof(pnew->id_nbr));
return(pnew);
}
void personDel(person* p)
{
if( !p ) return; //fail, must have valid pointer
free(p);
return;
}
person*
personCopy(person* pd, person* ps)
{
if(!pd || !ps) return;
strncpy(pd->name, ps->name, sizeof(pd->name));
strncpy(pd->last_name, ps->last_name, sizeof(pd->last_name));
strncpy(pd->id_nbr, ps->id_nbr, sizeof(pd->id_nbr));
return(pd);
}
以下是设置成员值的函数(通常称为setter或mutators),
person*
personName(person* p1, char* name)
{
if(!p1 || !name) return p1;
strncpy(p1->name, name, sizeof(p1->name));
return(p1);
}
person*
personLastName(person* p1, char* last_name)
{
if(!p1 || !last_name) return p1;
strncpy(p1->last_name, last_name, sizeof(p1->last_name));
return(p1);
}
person*
personIdNbr(person* p1, char* id_nbr)
{
if(!p1 || !id_nbr) return p1;
strncpy(p1->id_nbr, id_nbr, sizeof(p1->id_nbr));
return(p1);
}
以下是阅读和打印个人结构的功能,
person*
personRead(person* personp) //two
{
if(!personp) return personp;
//you really should allow for more space here
char name[99+1];
char last_name[99+1];
char id_nbr[99+1];
printf("Name: "); scanf("%s", name);
printf("Last name: "); scanf("%s", last_name);
printf("Id-number: "); scanf("%s", id_nbr);
personName(personp,name);
personLastName(personp,last_name);
personIdNbr(personp,id_nbr);
return(personp);
}
void personPrint(person* personp) //five
{
if(!personp) return personp;
printf("Name: %s,", personp->name);
printf("Last Name: %s,", personp->last_name);
printf("Id-Number: %s\n", personp->id_nbr);
}
请注意,我始终使用malloc / free和person (指向person struct的指针)。如果你想用C。*
编程,你需要学习指针