GodLordGee 发表于 2021-11-29 23:54:57

关于结构体数组初始化的一些问题

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

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

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

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

void InitLists(struct Book *t){
    for (int i = 0; i < 10;i++){
    t->arrays = 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);
    }
    return 0;
}


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

struct Lists
{
    char name;
    char num;
    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;
      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;
      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;
    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("您要更改姓名还是号码?");
      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;
    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("确认删除吗?");
      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("输入错误!请重新输入!");
      }

    }
}

jhq999 发表于 2021-11-30 06:24:04

本帖最后由 jhq999 于 2021-11-30 06:25 编辑

temp = (struct Lists *)malloc(sizeof(struct Lists));//下面函数里
上面的却没有申请内存空间,运行出错

GodLordGee 发表于 2021-11-30 22:25:44

我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?

GodLordGee 发表于 2021-11-30 22:26:29

jhq999 发表于 2021-11-30 06:24
上面的却没有申请内存空间,运行出错

谢谢您的回复,
我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?

jhq999 发表于 2021-12-1 06:05:21

GodLordGee 发表于 2021-11-30 22:26
谢谢您的回复,
我可不可以这样理解,只要声明了一个结构体变量,我就要给他分配内存空间?

结构体变量已经实例化,有自己的内存空间。
说的是结构体指针变量,用的时候可以申请新的内存空间,也可以把现有的结构体实例的指针赋值给它,

GodLordGee 发表于 2021-12-1 22:29:12

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

谢谢您的回复!
页: [1]
查看完整版本: 关于结构体数组初始化的一些问题