【C Primer Plus第六版 学习笔记】第十四章 结构和其他数据形式

有基础,进阶用,个人查漏补缺

  1. 建立结构声明:描述该对象由什么组成,即结构布局

    格式:

    关键字 标记(可选){结构
    };
    举例:
    struct book{char title[2];char author[4];float value;
    };
    
  2. 定义结构变量

    结构布局告诉编译器如何表示数据,但是并未让编译器为数据分配空间。创建结构变量,则编译器会使用上述book模板为该变量分配空间。

    struct book library;
    

    在这里插入图片描述

    结构布局和结构变量合并声明

    struct book{char title[2];char author[4];float value;
    }library;//也可以这样,但是就无法多次使用该结构进行其他同结构的变量声明了
    struct{char title[2];char author[4];float value;
    }library;
    
  3. 初始化结构

    与初始化数组的语法类似

    struct book library = {"ab","1234",1.99
    };
    
  4. 访问结构成员

    library.title
    library.author
    library.value
    
  5. 结构的初始化器

    结构的初始化器使用点运算符和成员名标识特定元素

    //只初始化book结构和value成员
    struct book surprise = {.value = 10.99};//可以按照任意顺序使用指定初始化器
    struct book surprise = {.value = 10.99,.author = "ab",.title = "abds"};//此外
    struct book surprise = {.value = 10.99,.author = "ab",25};//赋给value的值是25,取代了10.99
    
  6. 嵌套结构

    #include <stdio.h>
    struct names {              //第一个结构char first[20];char last[20];
    };struct guy{                 //第二个结构struct names handle;char job[20];float age;
    };int main(void)
    {struct guy fellow = {{"Ewen", "Villard"},"coach",25};printf("Dear %s", fellow.handle.first);return 0;
    }
    /*输出:
    Dear Ewen
    
  7. 指向结构的指针

    地址的就使用“→”,标识符的就使用“.”

    #include <stdio.h>
    struct names {              //第一个结构char first[20]; //占用20字节内存char last[20];  //占用20字节内存
    };struct guy{                 //第二个结构struct names handle;char job[20];     //占用20字节内存char favfood[20]; //占用20字节内存float age;        //占用4字节内存
    };int main(void)
    {struct guy fellow[2] = {{{"Ewen", "Villard"},"coach","apple",25},{{"Rob", "Swill"},"editor","banana",30}};struct guy * him;       //声明指向结构的指针
    /*或者有一个guy类型的结构barney,也可以him = &barney*/printf("address #1: %p #2: %p\n", &fellow[0], &fellow[1]);him = &fellow[0];      //告诉编译器该指针指向何处printf("pointer #1: %p #2: %p\n", him, him+1);//两种访问方式printf("him->age is %.f; (*him).age is %.f\n", him->age, (*him).age);**//必须要是用圆括号,因为运算符.比*优先级高!!**him++;printf("him->job is %.s; him->handle.last is %.s\n", him->job, him->handle.last);return 0;
    }
    /*输出:
    address #1: 0x7fff5fbff820 #2: 0x7fff5fbff874  //相差54(十六进制,十进制为84),
    pointer #1: 0x7fff5fbff820 #2: 0x7fff5fbff874  //说明每个guy结构相差84字节内存
    him->age is 25; (*him).age is 25
    him->job is editor; him->handle.last is Swill
    
  8. 向函数传递结构的信息

    #include <stdio.h>
    #define FUNDLEN 50
    struct funds {char   bank[FUNDLEN];double bankfund;char   save[FUNDLEN];double savefund;
    };double sum1(double, double);       /* 1. 传递结构成员 */
    double sum2(const struct funds *); /* 2. 传递结构地址 */
    double sum3(struct funds moolah);  /* 3. 传递结构    */int main(void)
    {struct funds stan = {"Garlic-Melon Bank",4032.27,"Lucky's Savings and Loan",8543.94};/*均输出:Stan has a total of $12576.21.*//* 1. 传递结构成员 */printf("Stan has a total of $%.2f.\n",sum1(stan.bankfund, stan.savefund) );/* 2. 传递结构地址 */printf("Stan has a total of $%.2f.\n", sum2(&stan));/* 3. 传递结构    */printf("Stan has a total of $%.2f.\n", sum3(stan));return 0;
    }
    /* 1. 传递结构成员 */
    double sum1(double x, double y)
    {return(x + y);
    }
    /* 2. 传递结构地址 */
    double sum2(const struct funds * money)
    {return(money->bankfund + money->savefund);
    }
    /* 3. 传递结构    */
    double sum(struct funds moolah)
    {return(moolah.bankfund + moolah.savefund);
    }
    
  9. 结构和结构指针的选择

    1. 结构:
      1. 优点:①函数处理的是原始数据的副本,保护了原始数据;②代码风格更清楚
      2. 缺点:①老版本可能无法实现;②传递结构浪费时间和存储空间
    2. 指针结构:
      1. 优点:①任何C语言版本都可使用;②执行快,只需要传递一个地址
      2. 缺点:无法保护数据,但const解决了这个问题
    3. 通常,为了追求效率会使用指针结构作为函数参数,如果需要防止原始数据被意外修改,使用const限定符。处理小型结构最常用按值传递。
  10. 结构中的字符数组和字符指针

    struct names {char first[20];char last[20];
    };
    struct pnames {char * first;char * last;
    };/*以下三行代码没问题,但veep字符串均储存在结构内部,总共要分配40字节存储姓名,
    而treas的字符串储存在编译器储存常量的地方,结构本身只储存了两个地址,只占用16字节*/
    struct names veep = {"Taila", "Summers"};
    struct pnames treas = {"Brad", "Falling"};
    printf("%s and %s\n", veep.first, treas.first);/*就语法而言,没有问题*/
    /*对于会计师,其名字被储存在accountant结构变量的last成员中,该结构有一个储存字符串的数组*/
    /*对于律师,scanf()把字符串放到attorney.last表示的地址上,
    但这是未经初始化的变量,地址可以是任意值,程序可以把名放在任何地方,可能会导致程序崩溃*/
    struct names accountant;
    struct pnames attorney;
    scanf("%s", accountant.last);
    scanf("%s", attorney.last);
    
  11. 结构、指针、malloc()

    使用malloc()分配内存并使用指针储存该地址,会使得在结构中使用指针处理字符串比较合理。该方法优点是可以请求malloc()为字符串分配合适的存储空间。

  12. 复合字面量和结构(C99)

    C99的复合字面量特性可用于结构和数组

    #include <stdio.h>
    #define MAXTITL  41
    #define MAXAUTL  31struct book {          // 结构模板:标记是bookchar title[MAXTITL];char author[MAXAUTL];float value;
    };int main(void)
    {struct book readfirst;int score;printf("Enter test score: ");scanf("%d",&score);if(score >= 84)readfirst = (struct book) {"Crime and Punishment","Fyodor Dostoyevsky",11.25};elsereadfirst = (struct book) {"Mr. Bouncy's Nice Hat","Fred Winsome",5.99};printf("Your assigned reading:\n");printf("%s by %s: $%.2f\n",readfirst.title,readfirst.author, readfirst.value);return 0;
    }
    
  13. 伸缩型数组成员(C99)

    有两个特性:

    1. 该数组不会立刻存在
    2. 好像它确实存在并具有所需数目的元素一样

    声明伸缩型数组成员的规则:

    1. 伸缩型数组成员必须是结构的最后一个成员
    2. 结构中必须至少有一个成员
    3. 伸缩数组的声明类似普通数组,但其方括号中是空的
    struct flex {int count;double average;double scores[];//伸缩型数组成员
    };
    /*声明一个struct flex类型变量时,不能用scores做任何事,因为没有给这个数组预留存储空间
    C99希望你声明一个指向struct flex类型的指针,然后用malloc()来分配足够的空间,
    以储存struct flex类型结构的常规内容和伸缩型数组成员所需的额外空间
    */
    struct flex * pf;
    pf = malloc(sizeof(struct flex) + 5 * sizeof(double));
    pf->count = 5;
    pf->scores[2] = 18.5;
    
  14. 匿名结构(C11)

    //嵌套结构
    struct names {char first[20];char last[20];
    };
    struct person {int id;struct names name;//嵌套结构成员
    };//在C11中,可以用嵌套的匿名成员结构定义person
    struct person {int id;struct {char first[20];	char last[20];};//匿名结构
    };
    
  15. 联合(union)

    1. 联合(union)是一种数据类型,能在同一个内存空间中储存不同的数据类型(非同时储存)。就是把没有规律、事先不知道顺序的数据类型放在一个结构中

      //该结构可以储存一个int类型,一个double类型和char类型的值
      union hold{int a;double b;char c;
      };union hold A;
      A.a = 1;
      union hold A = B;//可以用另一个联合来初始化,也可以用指定初始化器
      
  16. 枚举类型(enum)

    可以使用枚举类型声明符号名称来表示整型变量。使用enum关键字,创建新“类型”并指定它可具有的值。实际上,enum常量是int类型,因此,只要能使用int类型的地方就可以使用枚举类型。枚举类型的目的是提高程序的可读性。

    //第一个声明创建spectrum作为标记名,允许把enum spectrum作为一个类型名使用
    enum spectrum {red, orange, yellow, green, blue, violet};
    //第二个声明color作为该类型的变量。
    enum spectrum color;
    //第一个声明中花括号内的标识符枚举了spectrum变量可能有的值,
    //因此color可能的值是red、orange、yellow、green、blue、violet,这些red等被称为枚举符
    color = blue;
    if(color == yellow)···;
    for(color = red; color <= violet; color++)···;
    

    虽然枚举符(如red等)是int类型,但是枚举符可以是任意整型变量。此处的spectrum的枚举范围是0~5,所以编译器可以用unsigned char来表示color变量。

    printf("red = %d, orange = %d\n", red, orange);
    /*输出:
    red = 0, orange = 1
    

    默认情况下,枚举列表中的常量都被赋予0、1、2等。

    在switch语句中,可以把枚举常量作为标签。

    赋值:

    enum levels {low = 100, medium = 500, high = 2000};
    enum feline {cat, lynx = 10, ouma, tiger};
    //cat的值为0(默认),lynx,ouma,tiger分别为**10,11,12**
    
  17. typedef

    利用typedef可以为某一类型自定义名称,由编译器解释,不是预处理器

    typedef unsigned char byte;//也可以用大写BYTE,遵循变量的命名规则即可
    byte x, y[10], *z;//该定义的作用域取决于typedef定义所在的位置
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/579197.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

欧洲影像学人工智能和影像组 学文章审稿指南解读(一)--本手稿是否专注于AI/影像组学的报告?

欧洲影像学人工智能和影像组 学文章审稿指南解读 针对人工智能&#xff08;AI&#xff09;和影像组学领域的研究文章&#xff0c;欧洲影像学&#xff08;European Radiology&#xff09;期刊为审稿人提出了一系列特别的说明和要求。这些要求不仅仅是审稿的准则&#xff0c;更是…

Git 查询某段时间所有用户提交的代码量并过滤文件格式

获取代码提交用户 git log --format%aN| sort -u | while read name; do echo -en "$name\t"; done;获取代码提交文件的修改情况 git log --authorforwardhuan --prettytformat: --numstat获取代码提交文件的修改情况(过滤文件类型) git log --authorforwardhuan …

使用TLS/SSL Pinning保护安卓应用程序

使用TLS/SSL Pinning保护安卓应用程序 在现代术语中&#xff0c;“SSL”&#xff08;安全套接层&#xff09;通常指的是“TLS”&#xff08;传输层安全&#xff09;。虽然 SSL 和 TLS 不是同一个东西&#xff0c;但 TLS 是 SSL 的改进和更安全的版本&#xff0c;并且在实践中已…

在k8s中将gitlab-runner的运行pod调度到指定节点

本篇和前面的 基于helm的方式在k8s集群中部署gitlab 具有很强的关联性&#xff0c;因此如果有不明白的地方可以查看往期分享&#xff1a; 基于helm的方式在k8s集群中部署gitlab - 部署基于helm的方式在k8s集群中部署gitlab - 备份恢复基于helm的方式在k8s集群中部署gitlab - 升…

基于gradio快速部署自己的深度学习模型(目标检测、图像分类、语义分割模型)

gradio是一款基于python的算法快速部署工具&#xff0c;本博文主要介绍使用gradio部署目标检测、图像分类、语义分割模型的部署。相比于flask&#xff0c;使用gradio不需要自己构造前端代码&#xff0c;只需要将后端接口写好即可。此外&#xff0c;基于gradio实现的项目&#x…

算法分析的

&#xff08;1&#xff09;一个顾客买了价值x元的商品&#xff08;不考虑角、分&#xff09;&#xff0c;并将y元的钱交给售货员&#xff1a;编写代码&#xff1a;在各种币值的钱都很充分的情况下&#xff0c;使售货员能用张数最少的钱币找给顾客 #include<stdio.h> int…

舒心减压,益路同行,黄埔区惠民社会服务中心开展残障人士冬至漫游活动

“走出家门&#xff0c;共享阳光”残障人士游读广州项目是由广州市慈善会、广州市善城社区公益基金会资助、广州市黄埔区惠民社会服务中心实施的第四届“创善*微创投”广州市社区公益微创投项目&#xff0c;黄埔区康园工疗站约120名残障人士为服务对象&#xff0c;通过游玩与教…

leetcode 371. 两整数之和(优质解法)

链接&#xff1a;371. 两整数之和 代码&#xff1a; class Solution {public int getSum(int a, int b) {while(b!0){int numa^b; //无进位值int bit(a&b)<<1; //进位anum;bbit;}return a;} } 题解&#xff1a; 要计算两个数相加并且不能使用 - 号&#xff0…

【代码混淆】react-native 代码混淆

​ 混淆是指对源代码进行加密、重命名等操作&#xff0c;以增加代码的复杂度&#xff0c;使其难以理解和反编译。 在React Native中&#xff0c;混淆可以通过以下步骤实现&#xff1a; 将JavaScript源代码转换为基于本机平台的二进制代码&#xff0c;可以使用工具如Metro Bun…

HarmonyOS4.0系统性深入开发04UIAbility组件详解(下)

UIAbility组件间交互&#xff08;设备内&#xff09; UIAbility是系统调度的最小单元。在设备内的功能模块之间跳转时&#xff0c;会涉及到启动特定的UIAbility&#xff0c;该UIAbility可以是应用内的其他UIAbility&#xff0c;也可以是其他应用的UIAbility&#xff08;例如启…

DBeaver Community(社区版)下载及安装自用版

DBeaver Community&#xff08;社区版&#xff09;下载及安装自用版 数据库管理工具好用的都收费&#xff0c;收费的都好用。 DBeaver Community&#xff08;社区版&#xff09;免费&#xff0c;功能够用&#xff0c;性能可以&#xff0c;推荐。商业版的强大&#xff0c;收费&a…

leetcode 面试题 17.19. 消失的两个数字 (hard)(优质解法)

链接&#xff1a;面试题 17.19. 消失的两个数字 代码&#xff1a; class Solution {public int[] missingTwo(int[] nums) {int lengthnums.length;int tmp0;//将完整数据以及 nums 中的数据都进行异或&#xff0c;得到的就是缺失的两个数字 a^b 的结果for(int i1;i<length…

vue3项目 - 使用 pnpm 包管理器来创建项目

创建项目 npm install -g pnpm pnpm create vue 输入项目名称、包名称、选择要安装的依赖&#xff0c;最后 pnpm install pnpm format #规范格式 pnpm dev #启动项目

使用vite创建vue3项目

1、使用管理员身份打开命令行窗口&#xff0c;输入命令: npm create vuelatest TypeScript语法选择是&#xff0c;其他依次选择否&#xff0c;创建完毕。 2、 创建完毕后打开项目&#xff0c;vscode会提示安装开发相关的插件&#xff0c;选择install 3、打开vscode终端&#x…

【力扣】199.二叉树的右视图

看到这个题目的一瞬间&#xff0c;我想递归&#xff0c;必须用递归。最近被递归折磨的有点狠&#xff0c;但是我感觉我快要打败它了&#xff0c;就是现在稍稍有点处于劣势。不过没关系&#xff0c;来日方长不是。 法一&#xff1a;递归 题解&#xff1a; 之前想的就是先递归&…

2024哪款洗地机最值得入手?热门洗地机推荐

近年来&#xff0c;洗地机的被大家熟悉&#xff0c;越来越多的家庭购置洗地机来清洁家里的卫生&#xff0c;集吸、拖、洗为一体的三重清洁方式&#xff0c;为经常打扫卫生的宝妈脱离了做家务的困境&#xff0c;不用再经历繁琐的清洁步骤(扫地→拖地→拖干)&#xff0c;一拖一拉…

华为数通方向HCIP-DataCom H12-831题库(多选题:221-240)

第221题 在割接项目的项目调研阶段需要对现网硬件环境进行观察,主要包括以下哪些内容? A、设备的位置 B、ODF位置 C、接口标识 D、光纤接口对应关系 答案:ABCD 解析: 在项目割接前提的项目调研阶段,需要记录下尽可能详细的信息。 第222题 以下哪些项能被正则表达式10*成…

2024年山东省安全员B证证考试题库及山东省安全员B证试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年山东省安全员B证证考试题库及山东省安全员B证试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大…

SQL server 数据库练习题及答案(练习2)

使用你的名字创建一个数据库 创建表&#xff1a; 数据库中有三张表&#xff0c;分别为student,course,SC&#xff08;即学生表&#xff0c;课程表&#xff0c;选课表&#xff09; 问题&#xff1a; --1.分别查询学生表和学生修课表中的全部数据。--2.查询成绩在70到80分之间…

JBoss JMXInvokerServlet 反序列化漏洞 CVE-2015-7501 已亲自复现

JBoss JMXInvokerServlet 反序列化漏洞 CVE-2015-7501 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在Oracle Rapid Planning 12.1/12.2.2中发现了一个被归类为“严重”的漏洞。受到影响的是一些未知的组件处理中间层。升…