黑马程序员——c语言学习---数据结构

来源:互联网 发布:sql平均分大于80 编辑:程序博客网 时间:2024/05/17 05:50

-----------Java培训Android培训IOS培训.Net培训期待与您交流!------------ 
本节来讨论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 = 0summer = 1autumn = 2winter = 3
可见,这些标识符在真正运行的阶段还是以数字的形式进行流通,只是我们给他们换了一个叫发,方便了编程工作及思路的整理。顺便一提的是,我们可以在定义枚举的时候人为的改变这些默认值,方法如下:
enum{    spring,    summer = 2,    autumn,    winter}season;
此时,summer之后的数据根据summer依次递加,前面的保持不变,输出如下:
spring = 0summer = 2autumn = 3winter = 4

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

-----------Java培训Android培训IOS培训.Net培训期待与您交流!------------ 

0 0
原创粉丝点击