C语言-2

自定义类型

基本认识

/*
    引入:
        学生:姓名,学号,年龄,成绩
        请为学生们专门定制一个类型(创造一个类型)


    结构体格式:
        struct 标识符    // 标识符即自定义类型的名称
        {
            成员;    // 自己设置
        };    // 这里要注意不要漏了分号


    struct Students        // 定义一个学生类型
    {
        char name[12];
        int id;
        int age;
        int score;
    };


    我们知道:

        类型    变量名;
        int          x;
           x = 10;        // 赋值操作
        ---初始化操作 int y = 10;



    那么同理:

        结构化类型        结构体变量名;
      struct Students        stu_1;
        stu_1 = {"张三", 52, 18, 616};    // 为4个成员初始化

        其他内容补充:
            1.访问结构体变量的成员
                stu_1.name;
                stu_1.id;
                stu_1.age;
                stu_1.score;

            2.成员赋值
                stu_1.name = "张三";    // 操作错误!!
                正确操作为:
                    1.引入头文件<string.h>
                    2.strcpy(stu_1.name, "张三")    // 作用:将后面字符串"复制到"前面


                stu_1.id = 52;    // 操作正确
                stu_1.age = 18;    // 操作正确
                stu_1.score = 616;    // 操作正确

*/


# include <stdio.h>
# include <string.h>

// 定义一个学生类型,类似于创造int、long...这些类型,只不过学生类型是自定义罢了
struct Students
{
    char name[12];
    int id;
    int age;
    int score;
};

int main()
{
    struct Students    stu_1;
    stu_1.age = 18;
    strcpy(stu_1.name, "张三");
    printf("%s, %d\n", stu_1.name, stu_1.age);

    struct Students    stu_2 = { "李四", 39, 17, 553 };
    printf("%s, %d\n", stu_2.name, stu_2.age);
}

取别名

# include <stdio.h>

struct Human    // 定义一个 (struct)Human 类型
{
    char name[12];
    int age;
};

int main()
{
    typedef int Myint;    // 将int类型“取别名”为 Myint
    int x = 1;
    Myint y = 1;
    printf("%d\n", x + y);

    typedef struct Human hm;    // 将 struct Human 类型取别名hm
    hm obj_1 = { "tomato", 18 };
    printf("%s %d \n", obj_1.name, obj_1.age);

    return 0;
}
/*
    补充:
        在定义一个自定义类型的时候
        往往直接当场取别名,而不是以后才取
    e.g.
        struct Human    // 定义一个 (struct)Human 类型
        {
            char name[12];
            int age;
        }typedef hm;    // 直接当场取别名为hm
*/

结构体数组

# include <stdio.h>

// 定义一个类型
struct Hero
{
    char name[12];
    int level;
}typedef hr;    // 取别名

int main()
{ 
    // 初始化
    hr hero_1 = { "钢铁侠", 8 };
    hr hero_2 = { "蜘蛛侠", 7 };

    // 初始化
    hr hero_arr[9] = {    
        { "惊奇队长", 10 },
        { "美国队长", 7 },
        { "雷神", 8 },
        { "绿巨人", 9 },
        // 剩下的使用默认
    };

    // 修改
    hero_arr[0] = hero_1;

    return 0;
}

联合类型

/*
    union语法形式如下所示:

        union 名字    // union 关键字是用来定义"联合类型"
        {
            成员;    // 见详情
        }


        详情:
            修改一个成员的值,所有成员的值都会相应的产生变化
            原因:所有成员,内存是相同的(---如何理解?)
        ---如何理解?
            如下面代码中,num、d、ch 并不是各自独立占据一块内存,
            而是先看谁最大,因为 double 占8个字节,比 int 占的4个字节
            和 char 占的1个字节都要大,即 double > int > char
            所以,所有的成员,即整体一共被分配了8个字节
            因此,不同成员之间会出现联合占据某块内存空间的情况
            而在本例中,double 占了8/8,int 占了4/8,char 占了1/8
*/

# include <stdio.h>

union HUMAN
{
    int num;
    double d;
    char ch;
}typedef hm;    // 取别名

int main()
{ 
    hm u_1;
    u_1.num = 66;
    u_1.d = 10.0;
    u_1.ch = 'A';

    return 0;
}

枚举

/*
    语法:
        
        enum 名称
        {
            枚举元素0,
            枚举元素1,
            枚举元素2,
            枚举元素3,
            枚举元素4,
            枚举元素5
        }


        enum WEEK
        {
            Monday,        // --> 0
            Tuesday,    // --> 1
            Wednesday,    // --> 2
            Thurday,    // --> 3
            Friday = 15,// --> 15
            Saturday,    // --> 16
            Sunday        // --> 17
        };

        枚举元素不能叫同样的名字,即使是不在同一个“枚举集合体”下

*/

# include <stdio.h>

// 创造一个关于星期的枚举类型
enum WEEK
{
    Monday,            // --> 0
    Tuesday,        // --> 1
    Wednesday,        // --> 2
    Thurday,        // --> 3
    Friday,            // --> 4
    Saturday,        // --> 5
    Sunday            // --> 6
};

int main()
{ 
    enum WEEK week;    // 定义变量 week,其类型为 enum WEEK

    week = Friday;

    printf("星期五是>>>%d \n", week);

    // 枚举配合 switch 使用,天生一对
    switch (week)
    {
    case Monday:
        printf("%d \n", week);
        break;

    case Tuesday:
        printf("%d \n", week);
        break;

    case Wednesday:
        printf("%d \n", week);
        break;

    case Thurday:
        printf("%d \n", week);
        break;

    case Friday:
        printf("%d \n", week);
        break;

    case Saturday:
        printf("%d \n", week);
        break;

    case Sunday:
        printf("%d \n", week);
        break;

    default:
        printf("不存在这样的星期");
        break;
    }

    return 0;
}

预处理

基本认识

/*
    ---用 # 号开头的命令是预处理命令
    ---“预处理”即:预先处理,在编译前对代码进行一个预先处理
    
    include <文件.h>    // 这个是文件包含命令

    总上所述, # include <stdio.h>    即是:执行“预处理文件包含stdio.h”
*/

# include

/*
    当 main.c 这个主文件越写越大的时候
    我们可以将它其中的某些部分,通过写到其他文件的方式
    来达到将代码有条理地进行布局分离的目的
    从而实现高效维护和管理的目标
    如下所示:
*/

在这里插入图片描述

# define

/*
    1. # define 宏定义命令:使用一个表示符“表示”(或者说“完全替代”)一个字符串
    2. 语法:
        # define    宏名    字符串
*/

# include <stdio.h>

# define unint    unsigned int    // 宏名的规范写法为“全大写”,即 UNINT。
# define PI        3.14f
# define NAME    "tomato"
# define A        num * 2 + 1
# define B        (num * 2 + 1)

int main()
{    
    unint num = 1;
    printf("圆周率%f \n", PI);
    printf("我的名字%s \n", NAME);
    printf("结果%d \n", 3 * A);        // 结果:7
    printf("结果%d \n", 3 * B);        // 结果:9
    //printf("", );
    return 0;
}
# include <stdio.h>

# define M(x)        x*x+3*x
# define P(a,b)        a + b

int main()
{    
    int res = M(2);
    printf("结果为 %d \n", res);

    res = M(6);
    printf("结果为 %d \n", res);

    res = M(3 + 3);
    printf("结果为 %d \n", res);

    res = M(2 * 3);
    printf("结果为 %d \n", res);

    res = P(1, 2);
    printf("%d \n", res);

    return 0;
}

/*
    运行结果——————

        结果为 10
        结果为 54
        结果为 27
        结果为 54
        3
        请按任意键继续. . .
*/
# include <stdio.h>

# define    N(a,b)    a = a ^ b; b = a ^ b; a = a ^ b;    // ^ 异或,详情见底部
// 当一行内容过多的时候,可以用"\"符号实现“视觉上发生换行但代码本质还是一行”


int main()
{    
    int n = 9, m = 8;
    printf("%d %d \n", n, m);
    N(n, m);
    printf("%d %d \n", n, m);

    return 0;
}

/*
    运行结果——————

        9 8
        8 9
        请按任意键继续. . .
*/

/*
    上面的异或原理:

        打个比方a=11011,b=10101a和b做异或得到 01110
        将他赋值给a,则a=01110(a=a^b,a承载着a和b的不同),接着将a(01110)和b(10101)做异或得 11011
        发现就是原来a的值
        于是将它赋值给b,b=11011,则b现在就是a原来的值了(b=a^b),再将a(01110)和b(11011)异或得10101
        发现就是原来b的值,将它赋值给a,a=10101,则a现在就是b原来的值(a=a^b)
        这样就实现了互换a和b的值
*/
# include <stdio.h>

# define    STR(s)    #s
# define    NUM1(a,b)    a##e##b        // 连接成aeb
# define    NUM2(a,b)    a##b##99    // 连接成ab99


int main()
{    
    printf("%s \n", "abc123");
    printf("%s \n", STR("abc123"));
    printf("%s \n", STR(abc123));

    printf("%f \n", NUM1(1.23, 3));        // 连接成aeb,即 1.23e3 => 1.23 * 1000
    printf("%d \n", NUM2(12, 5));        // 连接成ab99,即 12599

    return 0;
}

/*
    运行结果——————

        abc123
        "abc123"
        abc123
        1230.000000
        12599
        请按任意键继续. . .
*/


/*
    上面的异或原理:

        打个比方a=11011,b=10101a和b做异或得到 01110
        将他赋值给a,则a=01110(a=a^b,a承载着a和b的不同),接着将a(01110)和b(10101)做异或得 11011
        发现就是原来a的值
        于是将它赋值给b,b=11011,则b现在就是a原来的值了(b=a^b),再将a(01110)和b(11011)异或得10101
        发现就是原来b的值,将它赋值给a,a=10101,则a现在就是b原来的值(a=a^b)
        这样就实现了互换a和b的值
*/

条件编译

# include <stdio.h>
/*
    条件编译(多种类型)
    1.    #if ... #endif        (可以穿插 #elif、#else)
    2.    #ifdef ... #endif    (可以穿插 #else)    
    3.    #ifndef ... #endif    (可以穿插 #else)
*/

# define NAME    // 对 NAME 进行宏定义,定义完成后,NAME就是宏名

int main()
{    
# if 1 - 1
    printf("My name is %s.\n", "tomato");
# elif 0
    printf("My name is %s.\n", "banana");
# else
    printf("My name is %s.\n", "apple");
# endif


# ifdef NAME        // 判断 NAME 是否为宏名,即是否进行了宏定义
    printf("111 \n");
# endif


# ifndef NAME        // if-not-def
    printf("222 \n");
# endif


    return 0;
}
/*
    使用场景:
        我们在 main.c 文件中编写代码时,
        有可能因为精神疲劳,而不小心造成错误
        例如:
        不小心引入了多次头文件<xxx.h>而导致出现“重定义”的情况
        我们如何解决这个问题?(下面有两个解决方案)
        方案1-----删除多余“引入头文件”的代码
        方案2-----我们能否在头文件上面做些手脚?使得它不论引入多少次,都只会执行一次。
*/



// 下面是头文件里面的代码
// 我们通过“条件编译”的知识来实现“方案2”

#ifndef MYFILE_H    // 判断:MYFILE_H 没有被定义?(ifndef => if-not-def)
#define MYFILE_H
struct Mystruct
{
    int num;
};
#endif                // 如果 #ifndef 的判断结果为‘错’,将跳到这行,直接结束

文件操作

/*
    1.文件路径:相对路径/绝对路径

    2.根目录---如:C盘、D盘、E盘

    3.操作文件:
        1.单个字符读写
        2.字符串读写
        3.格式化读写
        4.二进制形式读写
        5.指定位置读写
*/
# include <stdio.h>

int func_1();    // 声明

int main()
{
    FILE file;

    func_1();

    return 0;
}

// 1.单个字符读写
int func_1()
{
    // 打开文件 ==》 (读)操作文件 ==》 关闭文件 ==> 打开文件 ==》 (写)操作文件 ==> 关闭文件

    // 定义变量:文件
    FILE* file = NULL;

    // 打开文件:路径,打开方式
    file = fopen("/test.txt", "r");

    // (读)操作文件:
    char ch = 0;
    ch = fgetc(file);
    printf("%c \n", ch);    // 输出ch的内容
    putchar(ch);    // 也是输出ch的内容

    // 关闭文件:
    fclose(file);
    file = NULL;

    // 打开文件:注意!以 w 操作文件时,文件由"关闭状态"转为"打开状态"会清空文件里面的内容
    file = fopen("test.txt", 'w');

    // (写)操作文件:
    fputc('M', file);

    // 关闭文件:
    fclose(file);
    file = NULL;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity知识点详解】自定义程序集

今天来介绍一下Unity中的自定义程序集。在项目开发中我们经常接触到第三方插件的程序集&#xff0c;如DOTween、Newtonsoft.Json等。 使用自定义程序集有这么几个好处&#xff1a; 方便代码的的复用。当某一功能模块需要在多个项目中重复使用时&#xff0c;可以将代码编译成程…

新书速览|Kubernetes从入门到DevOps企业应用实战

从0到1&#xff0c;从零开始全面精通Kubernetes&#xff0c;助力企业DevOps应用实践 本书内容 《Kubernetes从入门到DevOps企业应用实战》以实战为主&#xff0c;内容涵盖容器技术、Kubernetes核心资源以及基于Kubernetes的企业级实践。从容器基础知识开始&#xff0c;由浅入深…

C#中使用OpenCvSharp4绘制直线、矩形、圆、文本

C#中使用OpenCvSharp4绘制直线、矩形、圆、文本 继之前的Python中使用Opencv-python库绘制直线、矩形、圆、文本和VC中使用OpenCV绘制直线、矩形、圆和文字&#xff0c;将之前的Python和C示例代码翻译成C#语言&#xff0c;很简单&#xff0c;还是借用OpenCvSharp4库中的Line、…

基于腾讯云服务器搭建幻兽帕鲁服务器保姆级教程

随着网络游戏的普及&#xff0c;越来越多的玩家希望能够拥有自己的游戏服务器&#xff0c;以便能够自由地玩耍。而腾讯云服务器作为一个优秀的云计算平台&#xff0c;为玩家们提供了一个便捷、稳定、安全的游戏服务器解决方案。本文将为大家介绍如何基于腾讯云服务器搭建幻兽帕…

Fink CDC数据同步(三)Flink集成Hive

1 目的 持久化元数据 Flink利用Hive的MetaStore作为持久化的Catalog&#xff0c;我们可通过HiveCatalog将不同会话中的 Flink元数据存储到Hive Metastore 中。 利用 Flink 来读写 Hive 的表 Flink打通了与Hive的集成&#xff0c;如同使用SparkSQL或者Impala操作Hive中的数据…

从MySQL到TiDB:兼容性全解析

MySQL 在高并发和大数据量场景下&#xff0c;单个实例的扩展性有限。而 TiDB 作为一款分布式NewSQL数据库&#xff0c;设计之初就支持水平扩展&#xff08;Scale-Out&#xff09;&#xff0c;通过增加节点来线性提升处理能力和存储容量&#xff0c;能够很好地应对大规模数据和高…

AS-V1000 视频监控平台产品介绍:客户端功能介绍(一)

目 录 一、引言 1.1 AS-V1000视频监控平台介绍 1.2平台服务器配置说明 二、软件概述 2.1 客户端软件用途 2.2 客户端功能 三、客户端功能说明 3.1 登陆和主界面 3.1.1登陆界面 3.1.2登陆操作 3.1.3主界面 3.1.4资源树 3.2 视频预览 3.2.1视频预览界面 3.2.…

python 基础知识点(蓝桥杯python科目个人复习计划33)

今日复习内容&#xff1a;以做题为主 例题1&#xff1a;小蓝的漆房 题目描述&#xff1a; 小蓝是一位有名的漆匠&#xff0c;他的朋友小桥有一个漆房&#xff0c;里面有一条长长的走廊&#xff0c;走廊两旁有许多相邻的房子&#xff0c;每间房子最初被涂上了一种颜色。 小桥…

Lambda表达式(匿名函数)

C11中引入了lambda表达式&#xff0c;定义匿名的内联函数。 我们可以直接原地定义函数而不用再跑到外面去定义函数跳来跳去。 同时在stl的排序上也有作用。 [capture] (parameters) mutable ->return-type {statement}下面逐一介绍各个参数的含义. [capture] : 捕获&#…

喜讯!亚信安慧斩获第六届金猿奖两大奖项!

近日&#xff0c;第六届金猿奖颁奖典礼在上海 “第六届金猿季&魔方论坛——大数据产业发展论坛”上隆重举行&#xff0c;湖南亚信安慧科技有限公司&#xff08;简称“亚信安慧”&#xff09;凭借AntDB数据库获评“2023大数据产业年度创新技术突破” 、“2023大数据产业年度…

解锁MyBatis Plus的强大功能:学习高级操作与DML技巧!

MyBatisPlus 1&#xff0c;DML编程控制1.1 id生成策略控制知识点1&#xff1a;TableId1.1.1 环境构建1.1.2 代码演示AUTO策略步骤1:设置生成策略为AUTO步骤3:运行新增方法 INPUT策略步骤1:设置生成策略为INPUT步骤2:添加数据手动设置ID步骤3:运行新增方法 ASSIGN_ID策略步骤1:设…

【数据结构 09】哈希

哈希算法&#xff1a;哈希也叫散列、映射&#xff0c;将任意长度的输入通过散列运算转化为固定长度的输出&#xff0c;该输出就是哈希值&#xff08;散列值&#xff09;。 哈希映射是一种压缩映射&#xff0c;通常情况下&#xff0c;散列值的空间远小于输入值的空间。 哈希运…

thinkadmin的form.html表单例子

<style>textarea {width: 100%;height: 200px;padding: 10px;border: 1px solid #ccc

JUC并发工具类的应用场景详解

目录 常用并发同步工具类的真实应用场景 1. ReentrantLock 1.1 常用API 1.2 ReentrantLock使用 独占锁&#xff1a;模拟抢票场景 公平锁和非公平锁 可重入锁 结合Condition实现生产者消费者模式 1.3 应用场景总结 2. Semaphore 2.1 常用API 2.2 Semaphore使…

VMware无法检测到插入的USB设备,虚拟机插拔USB无反应

原本正常使用的VMware虚拟机&#xff0c;在进行了重装软件后&#xff0c;发现虚拟机插拔USB设备都无法检测到&#xff0c;没有任何的反应和提示。 通过一系列的操作发现&#xff0c;在新安装了VMware workstation 软件后&#xff0c;存在一定的概率性会发生VMware虚拟机无法自…

在windows下安装docker部署环境运行项目----docker-compose.yml

前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注一下&#xff01; 也许一个人独行&#xff0c;可以走的很快&#xff0c;但是一群人结伴而行&#xff0c;才能走的更远&#xff01;让我们在成长的道路上互相学习&…

Android 13.0 原生SystemUI下拉通知栏每条通知默认展开

1.前言 在13.0的系统rom原生开发中,在在对SystemUI下拉通知栏做定制的时候,在下拉状态栏的时候,通知栏中最后一条通知默认是收缩的 点击按钮 就会展开 原生系统systemui就是如此,为了更美观 所以要求最后一条通知也默认展开,显得更美观 最终效果图: 2.原生SystemUI下拉通…

09. BI - 数据可视化,如何进行基本图形绘制

本文为 「茶桁的 AI 秘籍 - BI 篇 第 09 篇」 文章目录 EDA 作用可视化视图Python 进行可视化subplot Hi&#xff0c;你好。我是茶桁。 今天想给大家讲的是关于数据的可视化。在工作中很多时候我们不光要计算结果&#xff0c;还要把结果呈现出来&#xff0c;最好是一种图形化的…

斗地主登录界面(JAVA图形化界面)设置

1.实现代码 import CodeUtil.CodeUtil; import domain.User;import javax.swing.*; import java.awt.*; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList;public class LoginGame extends JFrame implements MouseListen…

png图片怎么转换成jpg?四个方法搞定不求人

在数字图像处理领域&#xff0c;PNG和JPG是两种常见的图片格式。PNG以无损压缩而闻名&#xff0c;适用于保存透明背景和保留图像细节&#xff1b;而JPG以有损压缩而著称&#xff0c;适用于在较小的文件大小下保持照片质量。有时候&#xff0c;您可能需要将PNG格式的图片转换为J…