「C语言精髓_高级数据表示」从数组到链表

本文通过一个地址薄程序的设计,探讨了在C语言中如何从数组过渡到链表作为数据表示。通过示例代码,展示了如何创建、显示和清理链表,以及链表在动态内存分配和灵活性方面的优势。同时,文中也提到了程序设计中的不足及改进方向,如内存管理检查和抽象数据类型的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

假设您需要创建一个地址薄程序。您将使用何种数据形式来存储信息?

因为与每个项目相关的信息有很多类别,所以用一个结构来表示每一个项目显得很适合。

如何表示多个项目?是标准的结构数据、动态数据,还是其他形式?各个项目需要按字母顺序排序吗?需要能够按邮政编码来搜索项目吗?需要执行的特定的动作将影响到您对如何存储信息做出的决定。

简而言之,在开始编写代码之前,您需要做出许多设计上的决定。

让我们来看一个数据表示的实例。假设您想要写一个程序来输入您一年中看过的所有的电影的列示。对每一部电影,您想记录的各种信息,比如片名、发行年份、导演、主演、片长、影片类别,您的评价等。根据这种情况,可以对每一部电影使用一个数据结构,对电影列表使用结构数组。为了简化,我们将结构限制为只有两个成员:片名和您的评价(分为0到10十个等级)。

示例1 是使用这种方法的简单实现。

示例1:  films1.c程序

#include <stdio.h>
#define TSIZE 45  /*存放片名的数组大小*/
#define FMAX 5  /*最多的影片数*/

struct film {
    char title[TSIZE];
    int rating;
};

int main(void)
{
    struct film movies[FMAX];
    int i = 0;
    int j;

    puts("Enter first movie title: ");
    while(i<FMAX && gets(movies[i].title)!=NULL &&
          movies[i].title[0]!='\0')
    {
        puts("Enter your rating <0-10>: ");
        scanf("%d",&movies[i++].rating);
        while(getchar()!='\n')
            continue;
        puts("Enter next movie title(empty line to stop): ");
    }
    if(i==0)
        printf("No data entered. ");
    else
        printf("Here is the movie list: \n");

    for(j=0;j<i;j++)
        printf("Movie:%s Rating: %d\n",movies[j].title,
               movies[j].rating);
    printf("Bye!\n");
    return 0;
}
程序创建了一个结构数组,然后把用户输入的数据填充到这个数组中。直到数组满(FMAX判断),或者到达文件结尾(NULL判断),或者用户在首先按下回车键('\0'判断),输入才会终止。

这种方法有些问题。首先,程序可能会浪费大量空间,因为大多数电影的名字并没有40个字符。第二,电影的数量限制(5部)。同时,有些编译器对像movies这样的自动存储变量可用的内存大小设置了一个默认的限制,如此之大的数组可能会超过那个值。这可以通过将数组声明为静态或外部数组,或者指示编译器使用更大的堆栈来解决,但这样并不能解决根本问题。

这里的根本问题是数据表示不太灵活。您必须在编译时做出决定,而事实上在运行时做这些决定会更好。这就表明您应该转向使用动态内存分配的数据表示。您可以尝试以下方法:

#define TSIZE 45
struct film { 
    char title[TSIZE];
    int rating;
};
...
int n,i;
struct film *movies;  /*指向结构的指针*/
...
printf("Enter the maximum number of movies you'll enter: \n");
scanf("%d",&n);
movies = (struct film *)malloc(n*sizeof(struct film));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值