数据结构

结构体:

将多个基本类型聚合在一起(也包括指针和数组),形成一个新的自定义类型,这就是结构体。

//一个描述飞机航班的结构体
struct flightType
{
    char flightNum[7];
    int  altitude;
    int  longitude;
    int  latitude;
    int  heading;
    double airspeed;
};


struct flightType plane; //声明一个flightType类型的变量,名称为plane

结构体变量的空间分配并没有什么特殊之处,都是局部变量分配在栈空间中,全局变量分配在全局数据空间中,但是结构体内部成员和函数的变量在栈空间的分布有所区别。

如下:

int x;
struct flightType plane;
int y;

在栈中的内存布局图如下

发现有何区别了吗?

是的,函数的局部变量的偏移量0到负值,地址从高往低,而结构体内部的成员地址偏移与之相反,是从低到高的。

typedef:

typedef提供了一种为已有数据重新命名的机制。typedef即可以重命名基本类型,又可以重命名结构体

typedef int Color; //Color做为int的一个别名
typedef struct flightType Flight; //将struct flightType命名为Flight
Flight plane; //等价于struct flightType plane

结构体数组:

Flight planes[100]; //100架飞机的数组

Flight *planePtr;
planePtr = plane; //将指针指向数组的第一个元素

int longitude = (*planePtr).longitude;
int longitude1 = planePtr->longitude; //这两句话是等价的

表达式"->"等价于间接引用符"*",但是"*"可以用于任何类型的指针,而"->"只能用于结构体中成员的引用。

动态内存分配:

C程序中,内存对象在内存中分配地方只有三种可能:栈(局部变量)、全局数据区(全局变量)、堆(动态数据对象)。

在实际情况中,我们无法事先就确定好数组的具体长度,这样就导致我们无法通过直接声明一个具体长度数组(分配太长造成内存空间浪费,分配太少造成内存不够,引发程序错乱甚至崩溃),动态内存分配应运而生。

动态内存分配就是在系统中,有个叫做“内存分配器”的程序,管理一个叫做“堆”的内存空间,程序通过内存分配器申请一段大小确定的连续内存,如果堆中空间足够,则分配器返回指向该地址的指针(起始地址)。堆中已分配的内存空间将永久保留直到程序主动释放。“内存回收器”接收程序的释放请求,将空间归还给堆,供下次申请使用。

Flight *planes; //声明一个Flight指针

int planeCount;
scanf("%d", &planeCount);

planes = malloc(sizeof(Flight) * planeCount); //申请一段连续的内存块

free(planes); //释放申请的指向planes的内存块

通过调用malloc申请空间,参数是内存空间大小,sizeof的作用是返回其参数(一个内存对象或者类型)占用的内存空间大小(目的是计算工作交给编译器完成,不用程序员自己手动计算)。

通过free释放掉malloc申请到的空间块,参数是一个指向这段内存块的指针。

注意,通过malloc申请了内存块,使用完毕后一定记得通过free来释放掉占用的内存区域,不然就造成内存泄露了,程序离开作用区域后指针已经销毁,这样就没有指针指向它了,但是这段空间还始终被占用着无法进行再次分配。

 

链表:

另一个非常重要的数据结构就是链表,在数组中,一个元素和其下一个元素在内存空间中是连续的,链表每个元素也有下一个,但他们的内存地址并不一定连续。

链表也是有头有尾,链表的头节点(head)由一个头指针指向它,尾节点(tail)指针指向NULL。

根据这个特性,就可以得出一些对链表操作的结论。

链表非常适合于插入和删除(只需改变相关的节点,而不用移动其他节点),但无法做到像数组一样的访问“随机性”,链表的每次访问必须从头部开始。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值