• c博客06-结构体&文件


    1.本章学习总结

    1.1 学习内容总结

    • 结构体的定义、成员的赋值:
      结构体的一般定义形式(单独定义):
    struct 结构名
    {
    类型名 结构体成员名1;
    类型名 结构体成员名2;
    ...
    类型名 结构体成员名n;
    };
    

    struct是定义结构类型的关键字,在struct之后,自行命名一个结构名,它必须是一个合法的C标识符,struct与结构名两者合起来共同组成结构类型名,如struct student

    结构体的定义形式还有混合定义:

    struct 结构名
    {
    类型名 结构体成员名1;
    类型名 结构体成员名2;
    ...
    类型名 结构体成员名n;
    }结构变量名1,结构变量名2;
    

    还有无类型名定义:

    struct
    {
    类型名 结构体成员名1;
    类型名 结构体成员名2;
    ...
    类型名 结构体成员名n;
    };
    

    前者与单独定义形式的实质是一样的,而后者定义结构变量时省略了结构名,所以也导致了变量不能再增加,否则重新定义结构体,不推荐使用。

    有关typedef定义结构体:

    typedef struct 结构名
    {
    类型名 结构体成员名1;
    类型名 结构体成员名2;
    ...
    类型名 结构体成员名n;
    }STRUCT;
    

    用typedef定义,则上面的STRUCT==struct+结构名,这样子之后定义结构体变量的时候,就可以用STRUCT来简化代码了。因此推荐使用typedef。

    成员的赋值:
    在C语言中,用结构成员操作符‘.’来引用成员;格式为:结构变量名.结构成员吗,比如stu.num或stu.name
    引用成语后,对成员的赋值方法与同类型的变量完全相同,比如:

    stu.num=119;
    strcpy(stu.name,"hello");
    
    • 结构体数组排序做法:

    结构体数组的排序,其实就是数组的排序,可以用常见的选择法与冒泡法排序
    (比如将students[n]中按照students中的num排序)
    1、冒泡法(把最大的沉下去):
    使用两层循环

    for(i=1;i<n;i++)//外循环n-1次
    {
        for(j=0;j<n-1-i;j++)
            {
                if(students[j].num>students[j+1].num) 交换students[j]与students[j+1];
            }//内循环结束后,将有一个最大值“沉”到未排序的最下面
    }
    

    两层循环后即可得到有序的重构数组students[n];

    2、选择法(先选择最大的,然后按照顺序排下来):
    这里也是要用到两层循环

    for(i=1;i<n;i++)
    {
        for(j=0;j<n-i;j++)
        {
            如果student[MaxIndex].num<students[j].num;则交换MaxIndex与j; //历遍数组,找出最大的值所在下标
        }
        //交换students[MaxIndex]与students[n-i]; //将最大的元素与(未排序)下标最大的数组元素交换
    }
    

    两层循环后即可得到有序的重构数组students[n];

    • 结构体指针的用法:
      作为函数参数:函数传递参数方面,由于结构体所包含的参数较多,如果直接传递结构体,则需要传递非常多的字节,效率不高,而如果用结构体指针传递一个指向结构体的指针,则只需要传递8个字节(一个地址)。用法同函数的参数传递。

    用结构体指针访问结构成员:
    1、用p访问:
    如:(
    p)->num=110;
    其中p表示的是p指向的结构变量,注意,(p)中的括号是必不可少的,因为‘’运算符的优先级低于‘.’运算符,若没有括号,则p.num等价于*(p.num),含义发生变化,会产生错误。
    2、用指向运算符->访问:
    如:p->num=110;
    上面两种公式得到的效果是一样的。但我们通常用指向运算符->;

    • 共用体、枚举类型做法
      • 共用体概念:使用同一段内存单元存放不同类型的变量,或者说使几个不同的变量共享同一段内存的结构,称为“共用体”类型的结构。(实际上很少用到,因为现代电脑内存单元都很充足)
        共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。共用体占用的内存等于最长的成员占用的内存。
        定义与声明:
    union Data{
        int n;
        char ch;
        double f;
    };
    union Data a, b, c;
    
    • 枚举类型:
      枚举类型的一般定义形式为:
      enum typeName{ valueName1, valueName2, valueName3, ...... };
      其中的数据枚举值默认从 0 开始,往后逐个加 1;但我们也可以改变它的首元素对应的值,比如:
      enum typeName{ valueName1=2, valueName2, valueName3, ...... };
      这样枚举值就从 2 开始了.

    定义枚举变量:enum typeName a, b, c;
    当然也可以在定义枚举类型的同时定义变量,就像结构体的混合定义。
    有了枚举变量,就可以把列表中的值赋给它了:
    比如:

    enum week{ Mon , Tues, Wed, Thurs, Fri, Sat, Sun };
    enum week a = Mon, b = Wed, c = Sat;
    
    • 文件读写,文件中数据如何读进结构体数组:
      文件读写,就要用到文件打开函数:fopen()和文件关闭函数fclose()了,文件读取的时候记得考虑文件打开失败的情况
      配合读进结构体数组,比如:
    FILE *fp;
    int i=0;
    if((fp=fopen("abc.txt","r+"))==NULL)
    {
        printf("打开文件失败");
        exit(0);
    }
    //读进结构体数组:
    while(!feof(fp))
    {
        fscanf(fp,"%d%s%d",&student[i].num,student[i].name,&student[i].score);
        i++;
    }
    

    文件读取函数完整形式:fopen(char *filename,char *type);
    这里char *type为打开文件的操作形式
    其中字符型文件:
    "r" 只读;
    "w" 清空文件内容,只写;
    "a" 追加;
    "r+" 以读/写方式打开一个已存在的文件;
    "w+" 以读/写方式建立一个新的文本文件 ;
    "a+" 以读/写方式打开一个文件进行追加 ;
    二进制文件:
    "rb" 只读;
    "wb" 清空文件内容,只写;
    "ab" 追加 ;
    "rb+" 以读/写方式打开一个二进制文件;
    "wb+" 以读/写方式建立一个新的二进制文件 ;
    "ab+" 以读/写方式打开一个二进制文件进行追加 ;

    1.2 本章学习体会

    • 以前的那些编程,总感觉距离现实生活中的应用有点远,没有实际应用。学习到文件以后,感觉有了点可以在现实生活中操作的感觉,比如利用绝对路径删除某一个文件、修改某一个文件,让我想到了黑客的感觉,也觉得距离C语言的精髓更近了。由于打开、操作文件时会遇到一些系统崩溃或者系统异常的问题,所以同时也觉得文件这部分内容需要更加的小心去操作,要更细心,这是以前编程从未想过的问题。
    • 这两周代码量:785行。

    2.综合作业--“我爱成语”

  • 相关阅读:
    cyren提供安全规则
    AC自动机——1 Trie树(字典树)介绍
    代码静态分析工具——splint的学习与使用
    Aria2+WebUI,迅雷倒下之后的代替品
    立华科技
    centos平台基于snort、barnyard2以及base的IDS(入侵检测系统)的搭建与测试及所遇问题汇总
    Iperf使用方法与参数说明
    网络基本功(一):细说网络传输
    TCP窗口扩大选项
    TCP Nagle算法&&延迟确认机制
  • 原文地址:https://www.cnblogs.com/zhangpucyll/p/12046513.html
Copyright © 2020-2023  润新知