C语言 可变长度的数组 -2

来源:互联网 发布:主力控盘指标公式源码 编辑:程序博客网 时间:2024/05/12 04:10

1、前言

在笔者的上一篇blog中,使用了“链表”这样一种数据结构来实现C语言版的可变数组;虽然它的功能强大,但是缺点也是很多的。例如,在释放内存的时候需要循环释放。假如链表中元素比较多,则释放内存就比较耗费时间;且其数据在内存中存放的位置不连续。

在此,笔者介绍另外一种方式,来实现可变数组:


2、基本思想

对于数组,想必大家应该是比较了解的。数组的在内存中是连续存放的,且其存放在内存的“栈”中。

最开始的时候,笔者想通过调用realloc()函数来扩展一个数组的存储区域。但是发现,执行报错。后来才知道,程序的栈是由系统维护的,能供给用户动态分配的内存区域只有“堆”。

既然“堆”可以让用户自己来分配,那么当我们发现有数据输入的时候,就向系统申请一段内存空间,吧数据保存进去。当发现还有数据要输入的时候,我们就扩充这个内存空间,然后把数据保存进去。这样的数据保存完毕之后,就能保证所存储的数据都是连续存放的,由一个指针(首地址)引用。这很类似于数组。


3、代码实现

既然基本思路有了,那么就以上一篇blog中的功能要求为例,继续改写代码。

代码如下:

#include <stdio.h>#include <stdlib.h>#include <string.h>#define Student struct stu#define Volume sizeof(struct stu)//声明结构类型struct stu{    char name[16];    int age;};int main(){    int len = 0;    char identify[15] = {0};    int old = 0;    //创建指向Student类型存储区域的首地址的指针,以及存储区内部指针    Student *head =NULL;    Student *innerp = NULL;    do{        printf("please enter student's name: ---->less than 15 bytes  ----> press Enter to quit\n");        gets(identify);        //判断输入的姓名是否正常,如果输入的是enter键,则退出        if(identify[0] == '\0'){            break;        }else{            printf("please enter student's age:\n");            scanf("%d%*c",&old);            len++;            if(len ==1){                head = malloc(Volume);            }else{                head = realloc(head,(Volume*len));            }            innerp = head+(len-1);         //确定存储区域内部指针位置            strcpy(innerp->name,identify);            innerp->age = old;        }    }while(1);    printf("input done. you have ended %d students.\n",len);    printf("start reading informations\n");    //如何head为NULL,则表示存储区域没有数据;    if(head != NULL){        innerp = head;   //存储区域内部指针重置        for(int i =0; i<len; i++){            innerp = head+i;                       //存储区域内部指针移动            printf("No:%-5d\tName:%-15s\tAge:%-5d\n",i,innerp->name,innerp->age);        }        printf("All informations have been displayed\n");    }else{        printf("this is no data in memory\n");    }    printf("program is ending...\n");    printf("program has ended.\n");    return 0;}

对于这两段代码会发现,使用这种方式,代码量少了很多,而且思路清晰,实现比较简单。相比上一段代码,它还具有几个优点:

  1. 结构体数据量少,比较节省内存空间;
  2. 数据是规则的连续存放的,这样可以很方便使用指针来查询;
  3. 指针变量少:上一个代码段中,结构体使用了一个指针,还使用了一个head指针和一个位置指针;而本段代码中,只使用了一个头指针和位置指针。事实上,位置指针都可以不用,可以像数组语言,用头指针加上一个偏移量,就是存储区域内的位置指针了。
  4. 内存的释放非常方便,只需要一句代码:free(head);即可。而上一段代码,却需要使用循环来释放空间。


5、写在最后

虽然笔者刚刚接触C语言才不过十几天而已,但是发现C语言太难了。它的难点在于直接操作内存,而不像.net 那样,有clr维护内存;它的难点还在于,知识体系的简单,没有过大的框架,全部由底层的数据类型,函数来构建程序。这因为如此,C语言给了程序员非常宽松的思想空间。只要你有想法,就可以(几乎是)任意操作计算机。

以上所写,纯属个人实践。如有错误,还请各位不吝赐教。

0 0
原创粉丝点击