鱼C论坛

 找回密码
 立即注册
查看: 1292|回复: 5

[已解决]关于结构体数组初始化的一些问题

[复制链接]
发表于 2021-11-29 23:54:57 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
今天在学习数据结构的过程中,发现了一个问题
如果我定义了一个结构体,在main函数中再声明一个结构体指针变量p
将p直接在子函数中给各元素赋值,编译器警告我的指针p没有初始化
如果我让struct Book *p = NULL,再次运行程序,编译器没有警告了,但是程序没有任何输出
到最后如果我使用malloc函数进行内存分配,程序运行正常。

由上所述,我遇到的问题就是在主函数中声明的结构体指针,如果没有进行内存分配,程序就无法正常运行,哪怕给结构体指针赋值NULL也不行。
但是,在我之前学习结构体时写的另一个程序中,我也是在主函数中声明了一个结构体指针,只是给他赋值了NULL,程序却正常运行了。

综上,上述两者很矛盾,一个结构体指针只需要赋值null程序就能够正常运行,另一个结构体指针却必须分配内存空间才能正常运行。
我有问题的代码如下:
#include <stdio.h>
#include <stdlib.h>

struct Book{
    int arrays[10];
    int lens;
};
void InitLists(struct Book *t);

 void InitLists(struct Book *t){
    for (int i = 0; i < 10;i++){
    t->arrays[i] = 0;
    }
    
    t->lens = 0;
 }

 int main(){
    struct Book *p = NULL;  //如果只是赋值,程序无法运行
    // p = (struct Book *)malloc(sizeof(struct Book));  //将这一行取消注释以后,程序正常运行
    InitLists(p);
    for (int i = 0; i < 10;i++){
        printf("%d  =  %d\n", i, p->arrays[i]);
    }
    return 0;
}


下面的代码是我以前写的一个程序,代码很长,只需要关注main函数的前几行,我没有进行内存分配,程序仍然正常运行
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct Lists
{
    char name[128];
    char num[20];
    struct Lists *next;
};
void addPerson(struct Lists **head);
void findPerson();
void changePerson();
void delPerson();
void displayContacts();
void endPerson();
int welcome();

int welcome(){
    int num;
    printf("欢迎使用通讯录管理程序!\n");
    printf("1.插入新的联系人\n2.查找已有的联系人\n3.更改已有的联系人\n\
4.删除已有的联系人\n5.显示当前通讯录\n6.退出通讯录程序\n");
    printf("请输入数字选择需要的服务:");
    scanf("%d", &num);
    getchar();
    return num;
}

void addPerson(struct Lists **head){
    struct Lists *temp;
    temp = (struct Lists *)malloc(sizeof(struct Lists));
    static struct Lists *prior=NULL;
    // struct Lists *current=NULL;
    static struct Lists *tail = NULL;
    printf("您已选择插入新的联系人!\n");
    printf("请输入联系人姓名:");
    scanf("%s", temp->name);
    printf("请输入联系人电话:");
    scanf("%s", temp->num);
    if(prior == NULL){
        tail = temp;
        prior = tail;
        temp->next = NULL;
        *head = temp;
    }
    else{
        prior = tail;
        tail->next = temp;
        temp->next = NULL;
        // (*head)->next = 
    }
    printf("添加联系人成功!\n");
}

void findPerson(struct Lists **head){
    struct Lists *temp;
    temp = (struct Lists *)malloc(sizeof(struct Lists));
    temp = *head;
    printf("您已选择查找已有联系人!\n");
    int ch;
    printf("您是想根据姓名(1)查找还是根据号码(2)查找:");
    scanf("%d", &ch);
    switch (ch)
    {
    case 1:
        printf("您已选择根据姓名查找!请输入姓名:");
        char name[128];
        scanf("%s", name);
        while(temp != NULL && strcmp(temp->name,name)){
            
            temp = temp->next;
        }
        if(temp == NULL){
            printf("没有找到符合的条件!\n");
        }
        else{
            printf("找到适合的条件!\n");
            printf("姓名:%s", temp->name);
            printf("号码:%s", temp->num);
        }
        break;
    case 2:
        printf("您已选择根据号码查找!请输入号码:");
        char num[20];
        scanf("%s", num);
        while(temp != NULL && strcmp(temp->num,num)){
            temp = temp->next;
        }
        if(temp == NULL){
            printf("没有找到符合的条件!\n");
        }
        else{
            printf("找到适合的条件!\n");
            printf("姓名:%s", temp->name);
            printf("号码:%s", temp->num);
        }
        break;

    default:
        printf("请输入正确的选项!");
        break;
    }
}

void changePerson(struct Lists **head){
    struct Lists *temp;
    temp = (struct Lists *)malloc(sizeof(struct Lists));
    temp = *head;
    printf("您选择了更改已有联系人!");
    printf("请输入您要更改的联系人姓名:");
    char name[128];
    scanf("%s", name);
    while(temp != NULL && strcmp(temp->name,name)){
        temp = temp->next;
    }
    if(temp == NULL){
        printf("没有找到符合更改的名字!\n");
    }
    else{
        printf("找到可以更改的联系人!\n");
        printf("姓名:%s\n", temp->name);
        printf("号码:%s\n", temp->num);
        printf("您要更改姓名[1]还是号码[2]?");
        int ch;
        scanf("%d", &ch);
        switch (ch)
        {
        case 1:
            printf("请输入更改后的姓名:");
            scanf("%s", temp->name);
            break;
        case 2:
            printf("请输入更改后的号码:");
            scanf("%s", temp->num);
            break;

        default:
            printf("请输入正确的数字!");
            break;
        }
    }
}

void delPerson(struct Lists **head){
    printf("您选择了删除已有联系人\n");
    printf("请输入您想要删除的联系人姓名:");
    struct Lists *temp;
    struct Lists *prior = NULL;

    temp = (struct Lists *)malloc(sizeof(struct Lists));
    temp = *head;
    char name[128];
    scanf("%s", name);
    while(temp != NULL && strcmp(temp->name,name)){
        prior = temp;
        temp = temp->next;
    }
    if(temp == NULL){
        printf("没有找到符合删除的名字!\n");
    }
    else{
        printf("找到可以删除的联系人!\n");
        printf("姓名:%s\n", temp->name);
        printf("号码:%s\n", temp->num);
        printf("确认删除吗?[1][0]");
        int ch;
        scanf("%d", &ch);
        switch (ch)
        {
        case 1:
            if(prior == NULL){
                *head = (*head)->next;
            }
            else{
                prior->next = temp->next;
            };
            // printf("@@@@@@@@@@@@@@@@%p\n", temp->next);
            printf("已删除!");
            break;
        case 2:
            printf("取消成功!");
            break;

        default:
            printf("请输入正确的指令!");
            break;
        }
    }
}

void displayContacts(struct Lists **head){
    printf("以下为已存储的联系人信息:\n");
    struct Lists *temp;
    temp = (struct Lists *)malloc(sizeof(struct Lists));
    temp = *head;
    while(temp != NULL){
        printf("========================================\n");
        printf("姓名:%s\n", temp->name);
        printf("号码:%s\n", temp->num);
        temp = temp->next;
    }
}

void endPerson(struct Lists **head){
    printf("准备退出通讯录程序...\n");
    _sleep(1000);
    printf("开始释放内存...\n");
    free(*head);
    printf("内存释放完毕...\n再见!");
    exit(1);
}

int main(void){
    int choice;
    struct Lists *head = NULL;
    while(1){
        choice = welcome();
        switch (choice)
        {
        case 1:
            addPerson(&head);
            break;
        case 2:
            findPerson(&head);
            break;
        case 3:
            changePerson(&head);
            break;
        case 4:
            delPerson(&head);
            break;
        case 5:
            displayContacts(&head);
            break;
        case 6:
            endPerson(&head);
            break;

        default:
            printf("输入错误!请重新输入!");
        }

    }
}
最佳答案
2021-11-30 06:24:04
本帖最后由 jhq999 于 2021-11-30 06:25 编辑
temp = (struct Lists *)malloc(sizeof(struct Lists));//下面函数里 
上面的却没有申请内存空间,运行出错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-11-30 06:24:04 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jhq999 于 2021-11-30 06:25 编辑
temp = (struct Lists *)malloc(sizeof(struct Lists));//下面函数里 
上面的却没有申请内存空间,运行出错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-30 22:25:44 | 显示全部楼层
我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-30 22:26:29 | 显示全部楼层
jhq999 发表于 2021-11-30 06:24
上面的却没有申请内存空间,运行出错

谢谢您的回复,
我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-1 06:05:21 | 显示全部楼层
GodLordGee 发表于 2021-11-30 22:26
谢谢您的回复,
我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?

结构体变量已经实例化,有自己的内存空间。
说的是结构体指针变量,用的时候可以申请新的内存空间,也可以把现有的结构体实例的指针赋值给它,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-1 22:29:12 | 显示全部楼层
jhq999 发表于 2021-12-1 06:05
结构体变量已经实例化,有自己的内存空间。
说的是结构体指针变量,用的时候可以申请新的内存空间,也可 ...

谢谢您的回复!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-23 05:25

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表