开天辟地的卷毛 2022-11-08 19:20 采纳率: 83.7%
浏览 36

C语言结构体传参问题


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<string.h>
#define SIZE 66         //明示常量定义66,可以自行修改
//#define SIZE1 SIZE-1    //保证menu的返回的数组不会溢出
void eatline(void);
void answer_judge(char ch[]);
//void* s_gets(char* st, int n);

typedef int datatype;

//设计结构体,定义用户相关信息
typedef struct client
{
    datatype id;        //用户id序号
    char name[SIZE];    /*定义字符数组存储用户名字,可考虑用字符指针,
    但是字符指针不能逐个打印字符,暂且先用字符数组*/
    /*struct client* next;*/
}dclient, * nclient;

//设计队列节点类型(即节点的内容)
typedef struct node
{
    dclient data;       //队列节点的数据域具有dclient类型
    struct node*next;  //队列节点的next指针域
}ND, * PND;

//设计队列基本操作的指针,管理结构体
typedef struct linkqueue
{
    PND front;          //队头指针
    PND rear;           //队尾指针
}LQ, * PLQ;

//构造函数,用于建立链式队列
PLQ initqueue(void)
{
    //分配管理结构体内存空间
    PLQ queue = (PLQ)malloc(sizeof(LQ));  /*定义plq类型的队列,一定要进行 初始化 申请大小为队列操作本身lq的空间
                                          因为系统不会自动为指针申请一个可以使用的内存空间,为他提供存放结构体变量*/
    if (queue == NULL)                    //判断代码健壮性是否良好
        return NULL;

    PND phead = (PND)malloc(sizeof(ND));//定义一个PND类型的头指针,进行 初始化 申请大小为队列节点ND的空间
    if (phead == NULL)
    {
        printf("the phread malloc fail\n");
        free(queue);                     //因为phread申请失败,所以管理结构体queue也没有作用了。
        return NULL;
    }
    queue->front = phead;//队列 头尾指针 指向头结点
    queue->rear = phead;
    phead->next = NULL;  //头节点的next指向空
    return queue;       //将*plq类型的queue返回

    //also you can do
    //queue->front = (PND)malloc(sizeof(ND));
    //if (queue->front == NULL)
    //{
    //    printf("malloc fail\n");
    //    free(queue);
    //    return NULL;
    //}
    //queue->rear = queue->front;
    //queue->front->next = NULL;
    //return queue;
}

bool enqueue(PLQ queue)
{
    static datatype tid = 0; /*定义静态整型变量总派发tid,刚开始id空为0
                             static具有静态存储期, 文件作用域
                             块作用域中的静态变量贯穿整个程序的生命周期*/
    PND pnew = (PND)malloc(sizeof(ND));    //定义一个node类型新节点用于存放新用户信息
    if (pnew == NULL)                      //判断代码健壮性好坏
        return false;
    pnew->next = NULL;                     //pnew的next指向空
    //memset(pnew->data.name, 0, SIZE);      //memset()初始化函数,将pnew的name 的 SIZE范围 全部变成 0
                                           //该函数在string.h库里
    printf("please enter the client name: ");
    gets(pnew->data.name);      /*atttion: 表达data的name,需要用.结构成员运算符。否则
                                          出现E3364错误, 结构体变量是用"."*/
    //eatline();
    tid++;                                 //输入用户名字成功,总id递增 
    pnew->data.id = tid;                   //插入用户名后,用户获得一个id,id+1
    
    queue->rear->next = pnew;              //将rear的next指向新节点,完成节点的连接
    queue->rear = pnew;                    //将rear的位置移到最新节点位置,保证始终为队尾
    return true;
}

bool is_empty(PLQ queue)
{
    if ((queue->front == queue->rear)||(queue->front->next==NULL))       //如果队头就是队尾,则队列为空
        return true;
    else
        return false;
}
dclient dequeue(PLQ queue,dclient vall) //形参为queue管理结构体,以及dclient结构体变量val
{
    if (is_empty(queue))
    {
        printf("the linkqueue is empty\n");
        return;
    }
    PND ptamp = queue->front->next;
    vall = ptamp->data;              //将即将出队的用户名字存入指针
    queue->front->next = ptamp->next;
    printf("id: %d,name: %s is handing business\n", ptamp->data.id, ptamp->data.name);
    if (queue->front->next == NULL)
        queue->rear = queue->front;
        
    
    free(ptamp);
    return vall;
    //return true;
}

bool showqueue(PLQ queue)
{
    //datatype id = 0;                    //定义用户id,并赋值为0
    if (is_empty(queue))
    {
        printf("the linkqueue is empty\n");
        return false;
    }
    PND ptamp = queue->front->next;
    printf("******* queue *******\n");
    printf("id\tname\n");
    while (ptamp != NULL)  
    {
        //id++;
        //ptamp->data.id = id;        //每遍历到一个节点,就派发给用户一个id
        printf("%d\t", ptamp->data.id);
        printf("%s\t", ptamp->data.name);
        ptamp = ptamp->next;        //依次向后遍历
        printf("\n");
    }
    return true;
}

bool clearqueue(PLQ queue)           //下班,销毁队列节点,只剩头节点
{                    
    queue->rear = queue->front;      //将队尾指针指向队头指针,归位到头节点phead
    PND ptamp = queue->front->next;  //定义一个指向队列的临时指针,将临时指针指向首节点,方便后续节点删除操作
    while (ptamp != NULL)            //ptamp只要不等于NULL,就证明队列内依然有节点,执行删除操作
    {
        queue->front->next = ptamp->next; //参照出队操作,将front指向下一个节点
        free(ptamp);                      //将ptamp删除
        ptamp = queue->front->next;       //将ptamp节点再次指向新首节点
    }
    queue->front->next = NULL;            //队列没有节点后,头节点指向空.
    return true;
}

//处理fgets()函数存储'\n',的办法,这个办法封装一个函数
//char* s_gets(char* st_name, int size)/*返回char型指针,字符型指针st, 形参整型变量n
//                                     st存入实参的数组,n存入实参的数组最大数量*/
//{
//    char *ret_name;                  //定义一个字符指针ret_name
//    int i = 0;                       //整型i=0用于循环
//    ret_name = fgets(st_name, size, stdin);//从stdin标准输入中输入,读入size大小,放进st_name。
//    if (ret_name != NULL)
//    {
//        while (st_name[i] != '\n' && st_name[i] != '\0') //遍历,直到st_name的结尾
//            i++;
//        if (st_name[i] == '\n')                          //遇到\n将\n替换成\0
//            st_name[i] = '\0';
//        else
//            while (getchar() != '\n')      //遇到\0则将输入行多出来的字符(\0后面的字符)删去
//                continue;
//    }
//    return ret_name;
//}

//检查用户输入是否正确
void answer_judge(char ch[SIZE])
{
    while (strcmp(ch, "1") != 0 && strcmp(ch, "2") != 0 && strcmp(ch, "3") != 0
        && strcmp(ch, "4") != 0 && strcmp(ch, "5") != 0 && strcmp(ch, "6") != 0)
    {
        printf("please enter 1,2,3,4,5 or 6: ");
        //eatline();
        gets(ch);
    }
    return;
}

char menu(void)//菜单函数显示菜单
{
    char ch[SIZE]={0};//定义符号数组,用于存储用户输入的数据
    printf("******************** bank **************************\n");
    printf("please enter your choice(q to quit): \n");
    printf("1) call and queue        2) handle the business\n");
    printf("3) display the queue     4) knock off the work\n");
    printf("5) claer the screen      6) quit\n");
    printf("****************************************************\n");
    //scanf_s("%s", ch,66);
    gets(ch);   //使用gets()可以存储空格
    answer_judge(ch);
    return ch[0]; //返回数组的首元素,其他元素也用不上嘛,在answer_judeg里被删除了
}

void eatline(void)
{
    while (getchar()!= '\n')   //清除剩余字符
        continue;               //持续从行缓冲区提取字符,直到遇到'\n'结束循环
    return;
}
//void other_clearqueue(plq queue)

int main(void)
{
    char ch;                    //定义符号变量ch
    struct client* vall=(struct client*)malloc(sizeof(struct client));//初始化nclient结构体指针val并申请空间类型大小为dclient的空间
    if (vall == NULL)
        return NULL;
    //datatype tid = 0;                            //定义整型指针item,以及总上班内总共派发的totle_id.totle_id赋值为0
    PLQ queue=initqueue();                         //定义plq结构体指针
    
    while ((ch=menu()) != '6')
    {
        switch (ch)
        {
        case '1':enqueue(queue);             break;
        case '2':dequeue(queue,*vall);       break;   //解引用val指针,变成结构体,将它作为实参传入dequeue
        case '3':showqueue(queue);           break;
        case '4':
        {
            clearqueue(queue);
            printf("clear sucess\n");
            break;
        }
        case '5':system("cls");          break;

        }
    }
    printf("Done!");
    printf("the dequeue vall is:%d %s", vall->id, vall->name);
    return 0;
}

我想问一下为什么最后我打印vall结构体的数据时,是乱码的,看了一下dequeue返回的值,在main函数并没有找到,怎么解决呀

  • 写回答

1条回答 默认 最新

  • codears 2022-11-08 19:36
    关注

    typedef struct client内部缺少拷贝构造函数,name不能自动拷贝过去。你加个拷贝构造函数试试。

    评论

报告相同问题?

问题事件

  • 创建了问题 11月8日

悬赏问题

  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 R语言卸载之后无法重装,显示电脑存在下载某些较大二进制文件行为,怎么办
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?
  • ¥15 关于#vue.js#的问题:修改用户信息功能图片无法回显,数据库中只存了一张图片(相关搜索:字符串)
  • ¥15 texstudio的问题,