C学习笔记

C语言

  • 基本数据类型
    • 数据类型
      • 基本类型
        • 整型
        • 浮点型
          • 单精度
          • 双精度
        • 字符型
      • 指针类型
      • 空(void)类型
      • 复合类型
        • 数组
        • 结构体
          • 结构体的大小计算
            • 对齐方式
              • 自然对齐
                • 标准的数据类型地址是长度的整数倍
                  • double:8, float:4, int:4, short:2, char:1
              • 指定对齐
                • GNU __attribute__((aligned(n)))  或者 #pragma pack(n)
                  • 取min(n, 自然数对齐)去对齐
            • 对齐规则
              • 结构体的每个成员分别对齐
              • 结构体默认对齐方式为它最大的成员的对齐方式
              • 结构体对齐后的长度是对齐值的整数倍;
              • struct TestS1 {     char a;     int b;     char c[10]; }S1;
                • 20
              • struct TestS2 {     char a;     short b;     short c; }S2;
                • 6
              • struct TestS3 {     struct TestS2 s;     int a; }S3;
                • 12
            • 只有内部类型没有成员的结构体的大小为0(可以理解为没有初始化是结构的大小是0)
              • struct TestS4 {     struct interS1{         char i;     };      struct interS2{         char j;     };     }S4;
              • vscode实际验证不是0,linux验证是0:个人理解,IDE在编译的时候,自动赋初值;
            • 存在字段为0的结构体,(如变长数据包场景的使用)
              • struct Packet1 {     char len;     char data[0]; }P1;
                • 1
              • struct Packet2 {     int len;     char data[]; }P2;
                • 4
                • 只要出现数组,那么其他的成员类型就都按照已经赋值的算,如果数组长度是0或者未指定,则该数组size为0;
          • 注:
            • 不能自己递归定义
        • 共用体(联合体)
          • 用法
            • 能够存储不同的数据类型,但是只能同事存储其中的一种类型。 也就是可以存储这个,或者那个,或者那个。
            • 数据项有多种数据格式,但不会同时使用的时候,使用联合体;
          • 联合体的大小
            • 取最大成员的大小,同时符合对齐规则(和结构体一样);
          • 注:
            • 联合体内的每个成员变量是共用同一段内存的,改变一个成员,其他成员的值也会改变;但是除了赋了值之外的成员,都是随机值;
            • 所有成员,相对于基地址的偏移都是0;
        • 枚举
          • 一个变量只有几种常量值,可以使用枚举类型提高代码的可读性;
    • 基本数据类型的大小
      • 很多数据类型不同的硬件架构下,大小不一样。
      • char
        • 1字节
      • short
        • 2字节
          • -2^8~2^8-1
      • unsigned short
        • 2字节
          • 0~2^16-1(65535)
      • int
        • 4字节
          • -2^16~2^16-1
      • usigned int
        • 4字节
          • 0~2^32-1
    • 数据类型的转换
      • 显式类型转换
      • 隐式类型转换
        • 隐式类型转换,把数据范围较小的类型转换为数据范围较大的类型:
          • 占用字节数少的类型,向占用字节数多的类型转换;
          • 占用字节数相同情况下,有符号向无符号转换;
          • 整数类型向浮点类型转换;
          • 单精度向双精度转换;
        • 例子:
          • void Test() {     int a = -1;     unsigned b = 10;      if (a > b)     {         printf("a is greater than b.\n");     }     else     {         printf("a is less than or equal b.\n");     } }
          • 输出
            • a is greater than b
          • 原因
            • a与b比较时发生隐式类型转换,a被提升为无符号数,即0xFFFFFFFF
          • 注:
            • 例子是在告诉我们这样用很危险,别这么用。
    • 浮点类型的数值范围和精度
      • float
        • 32位
          • 用1bit表示符号位,23bit表示尾数,8bit表示指数位;
          • 符号位决定正负,尾数位决定能表示的有效数字位数,即精度,而指数决定数值范围;
          • 2^23 = 8388608,因此float最多能表示7位,但能保证的是6位;
      • float,double,long double
        • Topic1

  • 函数的声明和实现
    • 函数
      • 是一段完成特定功能的程序,一般反复使用的程序会定义为函数;
    • 函数修饰
      • static
        • 限制了函数的作用域,限制函数只能再本文件调用;
      • extern
        • 告知编译器该函数或者变量已在别处定义,可以放心编译构建;
        • 函数默认就是extern
      • inline(函数内联)
        • 优点
          • 将函数在调用点展开,减少了调用开销(主要栈的开销),提高了代码的执行效率;
          • 相比宏,会进行类型检查,更加安全;
        • 缺点
          • 会带来代码体积的膨胀,要同时考虑性能和代码体积;
        • 函数的inline标记,只是给编译器提供了内联的建议,最终要不要进行内联是由编译器内部的一系列规则判定的;noinline倒是确定的。
  • 运算符的优先级
    • Topic1

      • Topic1

    • 顺序大致是:自加减,类型和sizeof等符号,乘除,加减,移位,比较,逻辑,加等减等组合运算。
  • 预处理
    • .i文件
    • 做的事情
      • 处理以#开头的指令,比如赋值#include包含的文件、#define宏定义的替换、条件编译,删除注释;
        • 主要处理以#开头的预编译指令
        • 对头文件的处理就是,展开头文件,把头文件的绝对路径展开;
    • 预处理的作用
      • 常量替换,类型定义,简化函数实现,头文件引入及防止重复,预定义宏方便调试,注释代码,跨平台,特性功能开关配置,编译器编译选项配置;
      • 简单说就是头文件,注释代码,静态运算符,环境变量啥的都搞好。
    • 命令
      • gcc -E hello.c -o hello.i
    • 条件预编译
      • 预处理指令
        • #define
          • 定义一个预处理宏
          • 对象宏: 不带参数的宏被称为"对象宏(objectlike macro)"。对象宏多用于定义常量、通用标识。
          • 函数宏:带参数的宏。
            • 利用宏可以提高代码的运行效率: 子程序的调用需要压栈出栈
            • 代码量小但运行频繁的代码如果采用带参数宏来实现会提高代码的运行效率
            • 但多数c++程序不推荐使用函数宏,调试上有一定难度,可考虑使用c++的inline代替
        • #undef
          • 取消宏的定义
        • #if
          • 编译预处理中的条件命令,相当于C语法中的if语句
          • #if可支持同时判断多个宏的存在,与常量表达式配合使用。如果常量表达式为一个未定义的宏, 那么它的值被视为0
          • 不仅仅是检查后面的宏有没有定义,还会检查其值,是空值报错,是0,就返回0(虽然存在,但还是0,所以不要用它判断宏是不是已经定义)
        • #elif
          • 若#if, #ifdef, #ifndef或前面的#elif条件不满足,则执行#elif之后的语句,相当于C语法中的else-if
        • #else
          • 与#if, #ifdef, #ifndef对应, 若这些条件不满足,则执行#else之后的语句,相当于C语法中的else
        • defined
          • 与#if, #elif配合使用,判断某个宏是否被定义
          • defined(name)
            • 若宏被定义,则返回1,否则返回0
            • #if defined(VAX) && defined(UNIX) && !defined(DEBUG)
        • #ifdef
          • 判断某个宏是否被定义,若已定义,执行随后的语句
          • #ifdef和#ifndef则仅支持判断一个宏是否定义
          • #ifdef、#ifndef、defined,只是检查后面的宏是否定义,而不管其值为多少
          • #ifdef、#ifndef、defined,测试的宏可以是对象宏,也可以是函数宏
        • #ifndef
          • 与#ifdef相反,判断某个宏是否未被定义
        • #endif
          • #if, #ifdef, #ifndef这些条件命令的结束标志.
        • 实例
          • #ifdef _DEBUG    // ... do some operations   #endif  #ifdef _WIN32  // ... use  Win32 API  #endif
          • #ifdef ABC  // ... codes while definded ABC  #elif (CODE_VERSION > 2)  // ... codes while CODE_VERSION > 2  #else  // ... remained cases  #endif // #ifdef ABC
          • #if 常量表达式1  // ... some codes  #elif 常量表达式2  // ... other codes  #elif 常量表达式3  // ... ...  #else  // ... statement  #endif
          • #include<stdio.h> #define AA #ifdef AA #define HELLO "hello world" #elif BB #define HELLO "hello CC" #endif int main() {         printf("%s\n",HELLO);         return 1; }   
        • 注:
          • 在判断某个宏是否被定义时,应当避免使用#if,#elif,#else, 因为该宏的值可能就是被定义为0。而应当使用#ifdef或#ifndef。
      • 条件编译
        • 一般情况下,源程序中所有的行都参加编译。但是有时希望对其中一部分内容只在满足一定条件才进行编译,也就是对一部 分内容指定编译的条件,这就是“条件编译”。
        • 条件编译命令最常见的形式为:
          • #ifdef 标识符 程序段1 #else 程序段2 #endif
          • 这种条件编译可以提高C源程序的通用性
    • 其他的预处理指示符
      • #include
      • #error
        • 常常和条件预编译一起使用,当缺少依赖时,直接报错退出编译流程,相当于断言;
      • #warning
        • 用于告警,不中断编译;
      • #line
        • 用于作为行号控制,会影响__LINE__预定义的值
      • #undef
        • 取消之前的宏定义,没有定义过,不会报错;
      • #pragma
        • C99引入_Pragma
          • 用于指示当前翻译单元使用某种编译特性进行编译;
      • #
        • 空指示符,用于代码格式的美观
  • 宏定义
    • 宏定义的基本用法
      • 宏替换
        • 常量替换
        • 类型定义
        • 函数宏
        • 防止头文件包含
      • 可变参数的宏定义
        • 可变参数的宏定义常用于输出的重定义
          • 自定义变量
          • 自动去除逗号
            • ##
          • Topic1

            • Topic1

      • #操作符和##操作符
        • #
          • 用于将参数转化为字符串插入定义中
        • ##
          • 用于把内容拼接到一起
          • Topic1

            • Topic1

      • 注:
        • 与函数调用不同,宏定义的展开是平行展开的
    • 预定义的宏的分类
      • C语言标准要求预定义的宏
      • 环境宏,编译器可选支持
        • Topic1

      • 条件特征宏,编译器可选支持
    • 宏定义常见误区
      • 运算优先级
        • Topic1

      • 多次运算的问题
        • Topic1

      • 宏内部变量命名太普通
        • Topic1

    • 注:
      • 宏定义是可以有参数的,宏调用时是以实参的形式传递;
      • 宏定义里所有的宏名都是一个字符串,最终在程序里只是一个字符串的替换;
      • 宏定义的查找顺序
        • <>
          • 在包含的目录去找,不是在源文件目录去找,(别的目录,或者库)
        • “”
          • 首先在当前源文件目录下去找,然后再到包含的目录下找;
  • 字节序
    • 大端序
      • 高位是在低地址存;
    • 小端序
      • 高位在高地址存;
    • 网络序
      • 大端序
    • 注:
      • 一句说话,小端就是高存高,低存低,大端相反。
      • 如果认为左边是低字节,那大端序和人眼看到的是一样的。
        • 比如0x12345678,大端序就是0x12 0x34 0x56 0x78;小端序是0x78, 0x56, 0x34, 0x12。
        • 比如0x123,大端是0x123,小端是0x2301。
      • 大端和小端的存储单位是一个字节,一个字节是8bit,也就是两位十六进制数,也就是说0x12的大端小端都是一样的存储。(0x12如果是char是的,如果是int不行,int是32bit,16进制是0x00000012)
内容概要:本文围绕VMware虚拟化环境在毕业设计中的应用,重点探讨其在网络安全与AI模型训练两大领域的实践价值。通过搭建高度隔离、可复现的虚拟化环境,解决传统物理机实验中存在的环境配置复杂、攻击场景难还原、GPU资源难以高效利用等问题。文章详细介绍了嵌套虚拟化、GPU直通(passthrough)、虚拟防火墙等核心技术,并结合具体场景提供实战操作流程与代码示例,包括SQL注入攻防实验中基于vSwitch端口镜像的流量捕获,以及PyTorch分布式训练中通过GPU直通实现接近物理机性能的模型训练效果。同时展望了智能化实验编排、边缘虚拟化和绿色计算等未来发展方向。; 适合人群:计算机相关专业本科高年级学生或研究生,具备一定虚拟化基础、网络安全或人工智能背景,正在进行或计划开展相关方向毕业设计的研究者;; 使用场景及目标:①构建可控的网络安全实验环境,实现攻击流量精准捕获与WAF防护验证;②在虚拟机中高效开展AI模型训练,充分利用GPU资源并评估性能损耗;③掌握VMware ESXi命令行与vSphere平台协同配置的关键技能; 阅读建议:建议读者结合VMware实验平台动手实践文中提供的esxcli命令与网络拓扑配置,重点关注GPU直通的硬件前提条件与端口镜像的混杂模式设置,同时可延伸探索自动化脚本编写与能效优化策略。
目录: 1、【coze自动化]基础和建立一个简单的机器人实操(2024).mp4 2、【coze自动化]实操案例用插件和工作流-提取文案1(做好.mp4 3、【coze自动化]实操案例用大模型+插件+工作流-提取文案2.mp4 4、【coze自动化]实操案例用2个大模型+插件+工作流-提取文案3.mp4 5、【coze自动化]实操案例完结-2大模型+4插件+工作流-提取文案4.mp4 6、【扣子coze插件篇,-探索和测试插件的系统方法1].mp4 7、【扣子Coze自动化]案例实操-文本转脑图1.mp4 8、【扣子Coze自动化]如何写工作流的代码?普通人就能搞定--简单实用.mp4 9、【扣子Coze自动化]实操案例--选择器的落地应用-判断链接还是文本,mp4 10、【扣子Coze自动化]选择器分支和代码联合高级应用-让工作流更灵活应对多种场景.mp4 11、【扣子Coze自动化]如何把机器人发布平台.mp4 12_【AI案例篇]coze工作流处理1万字长文本和详细操作思路和方法.mp4 13、【扣子Coze自动化]一天500条文案详细思路--引入自定义插件.mp4 14、【扣子Coze自动化]万能自定义扣子插件--小白也能轻松搞定代码逻辑18:08.mp4 15、【扣子Coze自动化]获取官方apikey和测试自定义插件.mp4 16、【扣子Coze自动化]coze批处理,一次提炼、润色100条小爆款文案-标题-配音.mp4 17、【附加高级篇-来线下过度]3分钟提炼近百条视频文案介绍-(1).mp4 18、【附加高级篇-来线下过度]实战-3分钟提炼近百条视频文案.mp4 19、【扣子Coze附加高级篇-来线下过度】完结升级润色提炼爆款标题-3分钟提近百条文案 ............... 网盘文件永久链接
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值