C深剖关键字(5)

简介: 目录一:union关键字二:enum关键字三:typedef关键字

一:union关键字

联合关键字:联合体内部共享空间,整个union的大小由内部最大的元素决定。

#include<stdio.h>
union un
{
  int a;
  char b;
  // a和b共用一个空间,不过空间总大小由a决定
};
int main()
{
  // a和b共用一个空间,不过空间总大小由a决定
  printf("%d\n", sizeof(union un)); // 4
  return 0;
}

联合体的访问和结构体类似都可以采用 . 操作符或 -> 指向操作符。

union un x;
x.a = 10;
union un* p = &x;
p->a;

union 的空间布局问题:

联合体的空间开辟由元素最大的为准,在这里由a决定。四字节,那b占用的是a的低地址处还是高地址处呢?image.png任何变量在开辟空间的时候,这个变量开辟后都有地址,这个地址一定是众多字节中最小的


我们将联合体变量的地址和联合体内最大元素的地址打印出来看看:

image.png

不难看出,在数值大小上是一样的


对于b来说,在申请空间的时候,所有的空间申请都是由较低地址处向上开始分配的,所以b是在最低地址开始的,换言之,内部成员b开辟的空间和联合体本身和a变量的地址值是一样的。

image.png

结论:


联合体内所有成员的起始地址都是一样的,每一个都是第一个元素。


b永远在a的低地址处!!!


利用联合体的空间分布可以巧妙判断出大小端:

image.png这里要把一组二进制序列 0x 00 00 00 01保存在a对应的空间里,此时四个字节每个都有地址,而地址具有高低之分,而我们的数据按字节对应的1bit位进行划分的时候,数据就有高低权值位之别,所以存储方案有两种,一种高权值位放在高地址处,低权值低地址处,如我们上图的左边存法,01放在低地址处,第二种方案相反,如上图右边将01放在高地址处,因为b永远在a的低地址处,b占一个字节,如上图x.b=1红色记号笔划分出,如果存储方案是第一种,那么b=1,如果是第二种,那么b=0,而第一种存储方案正式小端的存储法则,第二种正是大端的存储法则。


如代码展示:

#include<stdio.h>
union un
{
  int a;
  char b;
};
int main()
{
  union un x;
  x.a = 1;
  if (x.b == 1)
  {
    printf("小端\n");
  }
  else
  {
    printf("大端\n");
  }
  return 0;
}

image.png 

注意:联合体的整大小必须能整除联合体内任何一个元素的大小

#include<stdio.h>
union un
{
  int a;
  char b[5];
};
int main()
{
  printf("%d\n", sizeof(union un)); // 8
  return 0;
}

根据我们之前的认知,联合体空间由最大元素决定,b的大小是5,按理来讲联合体大小应该是5,但运行起来大小却是8,联合体的整大小必须能整除联合体内任何一个元素的大小

再看一段代码:

体现联合体和大小端的对应关系:

#include<stdio.h>
union un
{
  int i;
  char a[4];
}*p, u;
int main()
{
  p = &u;
  p->a[0] = 0x39;
  p->a[1] = 0x38;
  p->a[2] = 0x37;
  p->a[3] = 0x36;
  printf("0x%x", p->i); //0x36373839
  return 0;
}

image.png

二:enum关键字

enum枚举关键字作用:枚举一堆的常量,内部的常量直接可以被当作数据使用,枚举本身也是新增或设计了一种类型,换言之,我们可以使用枚举类型直接定义变量。如下:

#include<stdio.h>
enum color
{
  RED,
  YELLOW,
  BLACK,
  GREEN,
  BLUE
};
int main()
{
  enum color c = RED;
  printf("%d\n", RED); // 0
  printf("%d\n", BLACK); // 2
  printf("%d\n", BLUE); // 4
  return 0;
}

枚举出来的本质就是整数,对应的就是某种字面值,不可被修改的,所以RED,BLACK,BLUE就是真正意义上的常量


为什么要存在枚举?


1:现实世界中,有一大堆具有相关性的常量需要被在代码中体现出来。


2:一旦我们枚举常量之后,所有常量的常量名不是数字而是直接用英文单词去代表,这样写出来的代码具有自描述性。    


枚举常量的设定:


如果将第一个枚举常量的内容赋予一个特定的数字,那么后续的枚举常量会呈现加1式的递增,也可以分段式递增:

#include<stdio.h>
enum color
{
  RED=10,
  YELLOW,
  BLACK=-9,
  GREEN,
  BLUE
};
int main()
{
  enum color c = RED;
  printf("%d\n", RED);   // 10
  printf("%d\n", YELLOW);  // 11
  printf("%d\n", BLACK);  // -9
  printf("%d\n", GREEN);  // -8
  printf("%d\n", BLUE);   // -7
  return 0;
}

三:typedef关键字

本质:类型重命名。

#include<stdio.h>
//(1)
// 对结构体类型进行重命名
typedef struct stu {
  char name[16];
  int age;
  char sex;
}stu_t;
//(2)
//对unsigned int 重命名 u_int 简化
typedef unsigned int u_int;
//(3)
//对指针int*重命名
typedef int* int_p;
//(4)
typedef int a[10];  // 此刻a相当于一种数组类型
int main()
{
  u_int x = 0;
  int_p p = NULL;
  stu_t s;
  a b;
  return 0;
}

类型重命名,可以对一些不太好理解的数据类型进行简化。


但是也不是说typedef可以随便的重命名,如果对指针或者数组进行重命名的时候,那么使用的时候,就会忽略一些细节。比如说数组的元素有几个,类型是什么,指针是几维指针,什么类型的指针。过度的typedef本质其实变相就是一种让人困扰的东西,但是比较推荐大家在结构体的时候运用typedef关键字


typedef和#define的区别


先看代码:


此段代码用的是typedef

#include<stdio.h>
typedef int* int_p;
int main()
{
  //int* a, b;
  // 此时a为指针,b为int 整型类型
  //int* a = NULL, b = 0; //可读性太差
  int_p a, b;
  // 此时a 和 b均为指针,等价于int* a, * b;
  return 0;
}

千万不要把typedef类型重命名看作某种替换,不能直接把int_t理解为int*,二者不能直接替换。而应将int_t理解成一种全新的类型,所以就不存在*会和a先结合还是和b先结合的问题。这个*的类型会对其后的所有定义的变量全部起效,int_p就作为一种独立类型去使用。


再来用#define试试

#include<stdio.h>
#define ptr_t int*
int main()
{
  ptr_t a, b, c;
  //等价于
  int* a, b, c;
  //a为int*, b和c均为int;
  return 0;
}

结论:

typedef类型重命名,并不是本质的文本替换,形成了一个新的独立的类型

宏define做的是纯纯文本替换

案例:

#include<stdio.h>
#define INT32 int
typedef int int32;
int main()
{
  unsigned INT32 a; 
  //因为宏define是文本替换,所以INT32就相当于int,所以就是ungsigned int a;
  //unsigned int32 b; 代码报错
  return 0;
}

问题:typedef static int int32_t 行不行?image.png从图中很容易看出是不行的,此时编译器出错。

在32个关键字中,有五个存储类型关键字:

image.png

而存储类型关键字有个特点:

存储关键字,不可以同时出现,也就是说,在一个变量定义的时候,只能有一个。

所以typedef和static这两个关键字不能同时出现,所以上述代码会报错。

相关文章
|
7天前
|
人工智能 安全 API
CoPaw:5分钟部署你的 AI助理
源自阿里巴巴开源生态的个人 AI 助理——CoPaw。作为阿里倾力打造的开源力作,CoPaw 完美打通钉钉、飞书、Discord 等多平台对话通道,支持定时任务自动化。内置 PDF/Office 深度处理、新闻摘要等强大技能,更开放自定义扩展接口。坚持数据全程私有化部署,绝不上传云端,让每一位用户都能在大厂技术加持下,拥有安全、专属的智能助手。
|
10天前
|
人工智能 自然语言处理 JavaScript
2026年Windows+Ollama本地部署OpenClaw保姆级教程:本地AI Agent+阿里云上快速搭建
2026年OpenClaw凭借本地部署、私有化运行的特性,成为打造个人智能体的核心工具,而Ollama作为轻量级本地大模型管理工具,能让OpenClaw摆脱对云端大模型的依赖,实现**本地推理、数据不泄露、全流程私有化**的智能体验。本文基于Windows 11系统,从硬件环境准备、Ollama安装与模型定制、OpenClaw部署配置、技能扩展到常见问题排查,打造保姆级本地部署教程,同时补充阿里云OpenClaw(Clawdbot)快速部署步骤,兼顾本地私有化需求与云端7×24小时运行需求,文中所有代码命令均可直接复制执行,确保零基础用户也能快速搭建属于自己的本地智能体。
11355 96
|
8天前
|
人工智能 安全 JavaScript
阿里云上+本地部署OpenClaw(小龙虾)新手攻略:解锁10大必备Skills,零基础也能玩转AI助手
2026年,开源AI代理工具OpenClaw(昵称“小龙虾”)凭借“能实际做事”的核心优势,在GitHub斩获25万+星标,成为现象级AI工具。它最强大的魅力在于可扩展的Skills(技能包)系统——通过ClawHub插件市场的数百个技能,能让AI助手从简单聊天升级为处理办公、学习、日常事务的全能帮手。
7349 26
|
6天前
|
人工智能 JavaScript Ubuntu
5分钟上手龙虾AI!OpenClaw部署(阿里云+本地)+ 免费多模型配置保姆级教程(MiniMax、Claude、阿里云百炼)
OpenClaw(昵称“龙虾AI”)作为2026年热门的开源个人AI助手,由PSPDFKit创始人Peter Steinberger开发,核心优势在于“真正执行任务”——不仅能聊天互动,还能自动处理邮件、管理日程、订机票、写代码等,且所有数据本地处理,隐私完全可控。它支持接入MiniMax、Claude、GPT等多类大模型,兼容微信、Telegram、飞书等主流聊天工具,搭配100+可扩展技能,成为兼顾实用性与隐私性的AI工具首选。
5408 10
|
9天前
|
人工智能 自然语言处理 机器人
保姆级教程:Mac本地搭建OpenClaw及阿里云上1分钟部署OpenClaw+飞书集成实战指南
OpenClaw(曾用名Clawdbot、Moltbot)作为2026年最热门的开源个人AI助手平台,以“自然语言驱动自动化”为核心,支持对接飞书、Telegram等主流通讯工具,可替代人工完成文件操作、日历管理、邮件处理等重复性工作。其模块化架构适配多系统环境,既可以在Mac上本地化部署打造私人助手,也能通过阿里云实现7×24小时稳定运行,完美兼顾隐私性与便捷性。
6896 14
|
2天前
|
人工智能 安全 前端开发
Team 版 OpenClaw:HiClaw 开源,5 分钟完成本地安装
HiClaw 基于 OpenClaw、Higress AI Gateway、Element IM 客户端+Tuwunel IM 服务器(均基于 Matrix 实时通信协议)、MinIO 共享文件系统打造。
2886 9
|
4天前
|
人工智能 JavaScript 测试技术
保姆级教程:OpenClaw阿里云及本地部署+Claude Code集成,打造全能 AI 编程助手
在AI编程工具百花齐放的2026年,Anthropic推出的Claude Code凭借72.5%的SWE-bench测试高分、25倍于GitHub Copilot的上下文窗口,成为开发者追捧的智能编程助手。但单一工具仍有局限——Claude Code擅长代码生成与审查,却缺乏灵活的部署与自动化执行能力;而OpenClaw(前身为Clawdbot)作为开源AI代理框架,能完美弥补这一短板,通过云端与本地双部署,实现“代码开发-测试-部署”全流程自动化。
2105 13
|
11天前
|
人工智能 JSON JavaScript
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
手把手教你用 OpenClaw(v2026.2.22-2)+ 飞书,10分钟零代码搭建专属AI机器人!内置飞书插件,无需额外安装;支持Claude等主流模型,命令行一键配置。告别复杂开发,像聊同事一样自然对话。
6703 17
手把手教你用 OpenClaw + 飞书,打造专属 AI 机器人
|
4天前
|
人工智能 JSON API
保姆级教程:OpenClaw阿里云及本地部署+模型切换流程+GLM5.0/Seedance2.0/MiniMax M2.5接入指南
2026年,GLM5.0、Seedance2.0、MiniMax M2.5等旗舰大模型相继发布,凭借出色的性能与极具竞争力的成本优势,成为AI工具的热门选择。OpenClaw作为灵活的AI Agent平台,支持无缝接入这些主流模型,通过简单配置即可实现“永久切换、快速切换、主备切换”三种模式,让不同场景下的任务执行更高效、更稳定。
2382 2

热门文章

最新文章