美文网首页
数据结构

数据结构

作者: labi3285 | 来源:发表于2017-09-14 22:02 被阅读14次

本节来讨论c语言主要的数据结构,包括数组、结构体、共用体、枚举。首先从数组开始。

1、数组

数组为同一类型的基本数据的集合。我们知道,基本数据类型都占据一定的内存空间,基本数据类型的定义,实际上就是内存地址的分配过程,同样的,数组作为基本数据类型的集合,在创建时也必须进行内存的分配。以下都为正确的数组创建方法:

int num1[4]={0,1,2,3};  
int num2[4]={0,1};  
int num3[4]={[2]=2,[3]=3};  
int num4[]={0,1,2,3};  
int n=3;int num5[n];  
int num6[0]; 

错误的示例:

int num5[]; // 未明确范围  
int num6={0,1,2,3}; // 格式不对  
int num7[];num7={0,1,2,3}; // 整体赋值必须在定义时赋值  
int n=3;int num8[n]={0,1,2,3}; // 错误  
int num9[-1]; // 没有负数个  

特殊的数组:
a、字符数组(字符串)
在c语言中通过字符数组的方式表示字符串,字符串的结尾不是字符数组的结尾,而是字符数组中出现的第一个‘\0’。

char str[]={'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\0'};      
printf("%s\n", str);  

也可以采用下面的方式创建(这两者不等价):

char *str="Hello World!";  
printf("%s\n", str);  

b、多维数组
有的时候采用单一的数组也可能满足不了需求,这时候就需要用到多维数组,他的定义和普通的数组完全一样,只不过他的每一个元素本身都是一个数组。我们来看一下多维数组的存储方式:

int a[2][2]={{1,2},{1,2}};  
printf("a[0][0]: %p \n", &a[0][0]);  
printf("a[0][1]: %p \n", &a[0][1]);  
printf("a[1][0]: %p \n", &a[1][0]);  
printf("a[1][1]: %p \n", &a[1][1]);  

输出结果:

a[0][0]: 0x7fff5fbff8c0   
a[0][1]: 0x7fff5fbff8c4   
a[1][0]: 0x7fff5fbff8c8   
a[1][1]: 0x7fff5fbff8cc 

从上述结果中可以看出,多维数组和普通数组的存储方式完全一样,也是按次序摆放,只是调用的方式略有不同。

2、结构体

在数组中,所用元素的类型都必须是相同的,为了满足更个性化的需要,就出现了结构体,他是一种类似数组的结构,只不过其内部存储的变量不是单一的数据类型,可以由多种数据类型组成,甚至可以是某个函数。为了表示结构体的这种任意的特性,结构体需要开发者自己编写结构格式,典型结构体的格式定义如下(要放在主函数的前面):

struct student  {  
    int number;     //学号  
    int age;        //年龄  
    double height;  //身高  
    char name[8];     //姓名  
}; //注意分号  

该操作只是定义了一个名称为student的框架,并没有实际分配内存。
为了分配内存,我们需要对student结构体进行实例化:

struct student stu; // 获得student结构体实例stu  
// 地址及大小输出  
printf("stu            地址:%p 大小: %lu Byte \n", &stu, sizeof(stu));  
printf("stu.number     地址:%p 大小: %lu Byte \n", &stu.number, sizeof(stu.number));  
printf("stu.age        地址:%p 大小: %lu Byte \n", &stu.age, sizeof(stu.age));  
printf("stu.height     地址:%p 大小: %lu Byte \n", &stu.height, sizeof(stu.height));  
printf("stu.name       地址:%p 大小: %lu Byte \n", &stu.name, sizeof(stu.name)); 

在上面的方法中,我们通过点语法访问结构体实例的内部变量,并获取各变量的地址,输出结果:

stu            地址:0x7fff5fbff8c0 大小: 24 Byte   
stu.number     地址:0x7fff5fbff8c0 大小: 4 Byte   
stu.age        地址:0x7fff5fbff8c4 大小: 4 Byte   
stu.height     地址:0x7fff5fbff8c8 大小: 8 Byte   
stu.name       地址:0x7fff5fbff8d0 大小: 8 Byte 

可以看出,在结构体实例中,内存的分配是按照内部变量的次序依次排列的,结构体的地址为第一个变量的地址,这和前面的结论一致。

3、共用体

共用体和结构体的创建方法基本相同,所不同的是他的内部变量公用相同的存储单元。为什么要这样做呢?是因为并不是所有的硬件都有足够的内存供我们使用,在有些场合下,一个“结构体”的内部变量同时只用到一个,这时候使用共用体将大大节省内存开支。此外,在通信领域,有时候在接受数据时无法确定数据的类型,先把数据存储下来,然后再根据类型对应读取,举例如下:
创建共用体框架(同样要放在主函数前面):

union reciveData  {  
    int number;     // 数字  
    char character;  // 字符  
}; 

实例化及验证:

union reciveData data; // 实例化  
// 地址及大小输出  
printf("data                 地址:%p 大小: %lu Byte \n", &data, sizeof(data));  
printf("data.number          地址:%p 大小: %lu Byte \n", &data.number, sizeof(data.number));  
printf("data.character       地址:%p 大小: %lu Byte \n", &data.character, sizeof(data.character)); 

输出结果:

data                 地址:0x7fff5fbff8d8 大小: 4 Byte   
data.number          地址:0x7fff5fbff8d8 大小: 4 Byte   
data.character       地址:0x7fff5fbff8d8 大小: 1 Byte  

由输出结果可以看出,共用体实例的存储空间为共用体实例内部最大元素的尺寸,各元素的地址相同,都等于共用体的地址。

4、枚举

枚举是一种特殊的数据结构,他将某些固定的数值表示成有意义的标识符,以提高程序的可读性。
枚举和上面的结构体和共用体类似,也需要在主函数前面声明其框架,例如:

enum {spring, summer, autumn, winter} season; //不含类型标签,定义单一的变量  
enum color_led {red, green, blue}; //含类型标签,可定义多个变量  

这两个枚举分别定义了四季和LED灯的三种状态,不同的是,第一个例子中没有“框架名称”,直接声明了单一的枚举,其标识符为season。第二个例子中有“框架名称“color_led”,我们可以通过此名称创建多个相似的框架。注意,这里并没有分配空间!如果你尝试通过&指令输出地址的话,会报错!
第一个例子的输出:

printf("spring = %d\n", spring);  
printf("summer = %d\n", summer);  
printf("autumn = %d\n", autumn);  
printf("winter = %d\n", winter);

结果为:

spring = 0  
summer = 1  
autumn = 2  
winter = 3  

可见,这些标识符在真正运行的阶段还是以数字的形式进行流通,只是我们给他们换了一个叫发,方便了编程工作及思路的整理。顺便一提的是,我们可以在定义枚举的时候人为的改变这些默认值,方法如下:

enum {  
    spring,  
    summer = 2,  
    autumn,  
    winter
} season;  

此时,summer之后的数据根据summer依次递加,前面的保持不变,输出如下:

spring = 0  
summer = 2  
autumn = 3  
winter = 4 

5、总结

合理运用以上几种复杂数据类型,将使我们的程序变得完善和规范,同时便于我们思路的理清。务必弄清楚这几种数据的使用。

相关文章

  • IOS开发_数据结构

    1、数据结构; 2、算法; 3、数据结构与算法; 1、数据结构; 1.1 概念: 数据结构:数据结构是计算...

  • py基础

    5Python集合容器 数据结构数据结构 一般将数据结构分为两大类: 线性数据结构和非线性数据结构。 线性数据结构...

  • 思维导图之数据结构+算法

    数据结构+算法 = 程序 数据结构比较 参考文章 数据结构与算法数据结构与算法(java)

  • 数据结构与算法分析:大纲]

    00数据结构与算法分析:大纲01数据结构:数组02数据结构:链表03数据结构:栈03数据结构:队列 本系列课程主要...

  • 数据结构:数组

    00数据结构与算法分析:大纲01数据结构:数组02数据结构:链表03数据结构:栈03数据结构:队列 数组 数组是一...

  • 数据结构—概述

    数据结构概述 数据结构概述:程序设计 = 数据结构 + 算法数据结构:数据元素之间存在所有特定关系的集合,数据结构...

  • OVS 源码分析整理

    OVS 核心代码 OVS 架构 OVS 主要的数据结构数据结构关系图主要的数据结构和数据结构的参数数据结构代码 d...

  • 01. 数据结构与算法绪论

    一、数据结构 1. 什么是数据结构 2. 数据结构的分类 3. 常用的数据结构 4. 数据结构的应用表现 二、算法...

  • 数据结构与算法 - 查找

    数据结构与算法系列文章数据结构与算法 - 时间复杂度数据结构与算法 - 线性表数据结构与算法 - 树形结构数据结构...

  • C#之数据结构(上)

    数据结构 一般将数据结构分为两大类: 线性数据结构和非线性数据结构。 线性数据结构有: 线性表、栈、队列、串、数组...

网友评论

      本文标题:数据结构

      本文链接:https://www.haomeiwen.com/subject/msjjsxtx.html