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

news2024/11/20 14:32:06

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

  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  31
    
    struct book {          // 结构模板:标记是book
        char 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};
        else
            readfirst = (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.coloradmin.cn/o/1337715.html

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

相关文章

Xcode 编译速度慢是什么原因?如何提高编译速度?

作为一个开发者&#xff0c;我们都希望能够高效地开发应用程序&#xff0c;而编译速度是影响开发效率的重要因素之一。然而&#xff0c;有时候我们会发现在使用 Xcode 进行开发时&#xff0c;译速度非常慢&#xff0c;这给我们带来了不少困扰。那么&#xff0c;为什么 Xcode 的…

分页合理化是什么?

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 只要是干过后台系统的同学应该都做过分页查…

神经网络介绍

目录 知识点介绍 知识点介绍 前馈神经网络&#xff1a;&#xff08;前馈网络的数据只向一个方向传播&#xff09; RNN循环神经网络&#xff0c;下图中多个 RNN 层都是“同一个层”&#xff0c;这一点与之前的神经网络是不一样的。

怎么下载landsat 8影像并在ArcGIS Pro中进行波段组合

Landsat 8&#xff08;前身为Landsat数据连续性任务&#xff0c;或 LDCM&#xff09;于2013年2月11日由 Atlas-V火箭从加利福尼亚州范登堡空军基地发射升空&#xff0c;这里为大家介绍一下该数据的下载的方法&#xff0c;希望能对你有所帮助。 注册账号 如果之前已经注册过的…

5、IDEA集成Git

IDEA集成Git 1. 配置Git忽略文件2. 定位Git程序3. 初始化本地库、添加暂存区、提交到本地库4. 切换版本5. 创建分支和切换分支6. 合并分支7. 解决冲突 1. 配置Git忽略文件 问题1&#xff1a;为什么要忽略他们&#xff1f; 与项目的实际功能无关&#xff0c;不参与服务器上部署…

学习笔记12——Spring的注解配置

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/192486.html SSM框架——注解配置&#xff08;Component Autowired 加载SpringConfig&#xff09; 注解开发&#xff08;Component注解、config扫描 加载SpringConfig&a…

https密钥认证、上传镜像实验

一、第一台主机通过https密钥对认证 1、安装docker服务 &#xff08;1&#xff09;安装环境依赖包 yum -y install yum-utils device-mapper-persistent-data lvm2 &#xff08;2&#xff09;设置阿里云镜像源 yum-config-manager --add-repo http://mirrors.aliyun.com/do…

EB tresos 配置I2c - 实现与PF8200的读写操作

文章目录 前言一、EB工具链配置1、I2c模块1&#xff09;新建模块2&#xff09;配置General3&#xff09;配置I2cChannel 2、Port模块1&#xff09;配置SDA2&#xff09;配置SCL 二、代码分析1、申明一个I2c配置结构体数组&#xff0c;用于I2c所有读操作。2、搭建读操作函数 三、…

GitLab 删除或移动项目

首先明说&#xff0c;删除后无法恢复 第一步&#xff1a;找到要删除的项目 第二步&#xff1a;进入目录后&#xff0c;左侧菜单&#xff0c;设置 >>> 通用&#xff0c;拉到最下面找到“高级”&#xff0c;点击右侧“展开” 第三步&#xff1a;点击“展开”后往下拉&a…

亚马逊云科技 re:Invent 2023 产品体验:亚马逊云科技产品应用实践 王炸产品 Amazon Q,你的 AI 助手

意料之中 2023年9月25日&#xff0c;亚马逊宣布与 Anthropic 正式展开战略合作&#xff0c;结合双方在更安全的生成式 AI 领域的先进技术和专业知识&#xff0c;加速 Anthropic 未来基础模型的开发&#xff0c;并将其广泛提供给亚马逊云科技的客户使用。 亚马逊云科技开发者社…

Python 实现Excel和CSV之间的相互转换

通过使用Python编程语言&#xff0c;编写脚本来自动化Excel和CSV之间的转换过程&#xff0c;可以批量处理大量文件&#xff0c;定期更新数据&#xff0c;并集成转换过程到自动化工作流程中。本文将介绍如何使用第三方库Spire.XLS for Python 实现&#xff1a; 使用Python将Exc…

ServletConfig对象.

是什么 ServletConfig是javax.servlet.包下的一个接口&#xff0c;ServletConfig它是Servlet的一个配置对象&#xff1b; ServletConfig是由tomcat容器创建&#xff0c;通过init方法传入给Servlet&#xff1b; ServletConfig对象如何获取? 在GenericServlet里面定义了&#x…

根据DCT特征训练CNN

记录一次改代码的挣扎经历&#xff1a; 看了几篇关于DCT频域的深度模型文献&#xff0c;尤其是21年FcaNet&#xff1a;基于DCT 的attention model&#xff0c;咱就是说想试试将我模型的输入改为分组的DCT系数&#xff0c;然后就开始下面的波折了。 第一次尝试&#xf…

【SpringCloud】-OpenFeign实战及源码解析、与Ribbon结合

一、背景介绍 二、正文 OpenFeign是什么&#xff1f; OpenFeign&#xff08;简称Feign&#xff09;是一个声明式的Web服务客户端&#xff0c;用于简化服务之间的HTTP通信。与Nacos和Ribbon等组件协同&#xff0c;以支持在微服务体系结构中方便地进行服务间的通信&#xff1b…

互联科技:全域托管云赋能百行百业的数字化转型

在这个数字经济时代&#xff0c;云计算技术为企业提供了更加高效的业务管理机会&#xff0c;百行百业加速上云。对比几种云网方案&#xff0c;目前公有云方案存在可控性低、数据暴露风险、个性化需求难以满足、服务受限等问题&#xff1b;私有云方案存在建设成本高、建设周期长…

TCP服务器的演变过程:IO多路复用机制select实现TCP服务器

IO多路复用机制select实现TCP服务器 一、前言二、新增使用API函数2.1、select()函数2.2、FD_*系列函数 三、实现步骤四、完整代码五、TCP客户端5.1、自己实现一个TCP客户端5.2、Windows下可以使用NetAssist的网络助手工具 小结 一、前言 手把手教你从0开始编写TCP服务器程序&a…

文献研读|Prompt窃取与保护综述

本文介绍与「Prompt窃取与保护」相关的几篇工作。 目录 1. Prompt Stealing Attacks Against Text-to-Image Generation Models&#xff08;PromptStealer&#xff09;2. Hard Prompts Made Easy: Gradient-Based Discrete Optimization for Prompt Tuning and Discovery&#…

Linux - 记录问题:怎么通过安装包的方式安装gRPC

适用场景 当docker 构建环境不能链接到github 的时候&#xff0c;就可以使用本地构建的方式 完成对应服务的构建需求。 参考案例 使用本地安装包的方式安装 gRPC 注意&#xff1a; 在Docker构建过程中&#xff0c;某些软件包可能会尝试配置时区&#xff0c;这通常需要交互式…

性能优化,让用户体验更加完美(渲染层面)

前言 上一篇我们已经围绕“网络层面”探索页面性能优化的方案&#xff0c;接下来本篇围绕“浏览器渲染层面”继续开展探索。正文开始前&#xff0c;我们思考如下问题&#xff1a; 浏览器渲染页面会经过哪几个关键环节&#xff1f;“渲染层面”的优化从哪几方面着手&#xff1f…

智能三维数据虚拟现实电子沙盘

一、概述 易图讯科技&#xff08;www.3dgis.top&#xff09;以大数据、云计算、虚拟现实、物联网、AI等先进技术为支撑&#xff0c;支持高清卫星影像、DEM高程数据、矢量数据、无人机倾斜摄像、BIM模型、点云、城市白模、等高线、标高点等数据融合和切换&#xff0c;智能三维数…