蓝因子教育一种很酷的C语言技巧调用代码结构体c语言技巧assert

C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第一级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常有用的语法技巧和功能,只是没有多少人知道罢了。

☆指定的初始化

很多人都知道像这样来静态地初始化数组:

intfibs[]={1,1,2,3,5};

C99标准实际上支持一种更为直观简单的方式来初始化各种不同的集合类数据(如:结构体,联合体和数组)。

☆数组

我们可以指定数组的元素来进行初始化。这非常有用,特别是当我们需要根据一组#define来保持某种映射关系的同步更新时。来看看一组错误码的定义,如:

/*Entriesmaynotcorrespondtoactualnumbers.Someentriesomitted.*/#defineEINVAL1#defineENOMEM2#defineEFAULT3/*...*/#defineE2BIG7#defineEBUSY8/*...*/#defineECHILD12/*...*/

现在,假设我们想为每个错误码提供一个错误描述的字符串。为了确保数组保持了最新的定义,无论头文件做了任何修改或增补,我们都可以用这个数组指定的语法。

char*err_strings[]={[0]="Success",[EINVAL]="Invalidargument",[ENOMEM]="Notenoughmemory",[EFAULT]="Badaddress",/*...*/[E2BIG]="Argumentlisttoolong",[EBUSY]="Deviceorresourcebusy",/*...*/[ECHILD]="Nochildprocesses"/*...*/};

这样就可以静态分配足够的空间,且保证最大的索引是合法的,同时将特殊的索引初始化为指定的值,并将剩下的索引初始化为0。

☆结构体与联合体

用结构体与联合体的字段名称来初始化数据是非常有用的。假设我们定义:

structpoint{intx;inty;intz;

然后我们这样初始化structpoint:

structpointp={.x=3,.y=4,.z=5};

当我们不想将所有字段都初始化为0时,这种作法可以很容易的在编译时就生成结构体,而不需要专门调用一个初始化函数。

对联合体来说,我们可以使用相同的办法,只是我们只用初始化一个字段。

☆宏列表

C中的一个惯用方法,是说有一个已命名的实体列表,需要为它们中的每一个建立函数,将它们中的每一个初始化,并在不同的代码模块中扩展它们的名字。这在Mozilla的源码中经常用到,我就是在那时学到这个技巧的。例如,在我去年夏天工作的那个项目中,我们有一个针对每个命令进行标记的宏列表。其工作方式如下:

#defineFLAG_LIST(_)\_(InWorklist)\_(EmittedAtUses)\_(LoopInvariant)\_(Commutative)\_(Movable)\_(Lowered)\_(Guard)}

它定义了一个FLAG_LIST宏,这个宏有一个参数称之为_,这个参数本身是一个宏,它能够调用列表中的每个参数。举一个实际使用的例子可能更能直观地说明问题。假设我们定义了一个宏DEFINE_FLAG,如:

#defineDEFINE_FLAG(flag)flag,enumFlag{None=0,FLAG_LIST(DEFINE_FLAG)Total};#undefDEFINE_FLAG

对FLAG_LIST(DEFINE_FLAG)做扩展能够得到如下代码:

enumFlag{None=0,DEFINE_FLAG(InWorklist)DEFINE_FLAG(EmittedAtUses)DEFINE_FLAG(LoopInvariant)DEFINE_FLAG(Commutative)DEFINE_FLAG(Movable)DEFINE_FLAG(Lowered)DEFINE_FLAG(Guard)Total};

接着,对每个参数都扩展DEFINE_FLAG宏,这样我们就得到了enum如下:

enumFlag{None=0,InWorklist,EmittedAtUses,LoopInvariant,Commutative,Movable,Lowered,Guard,Total};

接着,我们可能要定义一些访问函数,这样才能更好的使用flag列表:

#defineFLAG_ACCESSOR(flag)\boolis##flag()const{\returnhasFlags(1<

☆编译时断言

这其实是使用C语言的宏来实现的非常有“创意”的一个功能。有些时候,特别是在进行内核编程时,在编译时就能够进行条件检查的断言,而不是在运行时进行,这非常有用。不幸的是,C99标准还不支持任何编译时的断言。

但是,我们可以利用预处理来生成代码,这些代码只有在某些条件成立时才会通过编译(最好是那种不做实际功能的命令)。有各种各样不同的方式都可以做到这一点,通常都是建立一个大小为负的数组或结构体。最常用的方式如下:

/*Forceacompilationerrorifconditionisfalse,butalsoproducearesult*(ofvalue0andtypesize_t),soitcanbeusede.g.inastructure*initializer(orwhereverelsecommaexpressionsaren'tpermitted).*//*LinuxcallstheseBUILD_BUG_ON_ZERO/_NULL,whichisrathermisleading.*/#defineSTATIC_ZERO_ASSERT(condition)(sizeof(struct{int:-!(condition);}))#defineSTATIC_NULL_ASSERT(condition)((void*)STATIC_ZERO_ASSERT(condition))/*Forceacompilationerrorifconditionisfalse*/#defineSTATIC_ASSERT(condition)((void)STATIC_ZERO_ASSERT(condition))

如果(condition)计算结果为一个非零值(即C中的真值),即!(condition)为零值,那么代码将能顺利地编译,并生成一个大小为零的结构体。如果(condition)结果为0(在C真为假),那么在试图生成一个负大小的结构体时,就会产生编译错误。

它的使用非常简单,如果任何某假设条件能够静态地检查,那么它就可以在编译时断言。例如,在上面提到的标志列表中,标志集合的类型为uint32_t,所以,我们可以做以下断言:

STATIC_ASSERT(Total<=32)

它扩展为:

(void)sizeof(struct{int:-!(Total<=32)})

现在,假设Total<=32。那么-!(Total<=32)等于0,所以这行代码相当于:

(void)sizeof(struct{int:0})

这是一个合法的C代码。现在假设标志不止32个,那么-!(Total<=32)等于-1,所以这时代码就相当于:

(void)sizeof(struct{int:-1})

因为位宽为负,所以可以确定,如果标志的数量超过了我们指派的空间,那么编译将会失败。

THE END
1.C#经典源代码实战教程简介:本教程提供了一系列经典的C#源代码示例,涵盖了用户界面控件(如按钮、标签、文本框等)的实现,以及事件处理机制。通过分析和理解计算器源代码,初学者可以掌握C#中的函数、变量、条件判断、循环等基本编程概念。此外,教程还介绍了委托、事件、错误处理和异常处理等高级主题,帮助开发者构建健壮的C#应用程序。 https://blog.csdn.net/weixin_31620365/article/details/141614423
2.开源学习网站源码(C#)WeiSha100开源学习网站源码(C#) 这款在线学习培训系统集视频点播、题库刷题、考试于一体,让你随时随地都能进行高效学习。它不仅为学员提供海量优质学习资源,还通过智能化、数据化的管理方式,让教务管理更加便捷高效。这款系统还拥有强大的数据分析功能,能够实时了解学员学习情况,为教务管理提供强有力的数据支持。同时还提供完善https://blog.huzhan.com/nnwei/article/1049
3.hardC#学习笔记(李志著)完整pdf扫描版[75MB]附随书源码☉ 如果遇到什么问题,请评论留言,我们定会解决问题,谢谢大家支持! ☉ 本站提供的一些商业软件是供学习研究之用,如用于商业用途,请购买正版。 ☉ 本站提供的Learning hard C#学习笔记 (李志著) 完整pdf扫描版[75MB] 附随书源码资源来源互联网,版权归该下载资源的合法拥有者所有。https://www.jb51.net/books/550829.html
4.资源管理器源码(c#)码农集市专业分享IT编程学习资源资源管理器源码(c#)Ed**离殇 上传1.36 MB 文件格式 rar C#源码 一个简单的资源管理 器 c# 源码, 做的很简单点赞(0) 踩踩(0) 反馈 所需:1 积分 电信网络下载 Blog.Core 2024-12-10 11:19:05 积分:1 v2020 2024-12-10 11:18:22 积分:1 https://www.coder100.com/index/index/content/id/217375
5.C#社区C# 社区是以 C# 编程语言为核心的技术资源社区,面向 C# / .NET 编程的开发人员,提供 C# 论坛,C# 教程,C# 源码,C# 技术(.net,.net framework,asp.net,mvc,.net core,winform,wpf,wcf,wf,linq,ado.net,entity framework,web service,web api,webform)交流分享等。https://www.hicsharp.com/
6..NetFramework框架源码学习Asp.net教程.Net教程Vb.net教程Singleton模式,由于其实现相对简单,所以号称设计模式中最简单的模式. 但是static通常会给你造成一些障碍.不信啊,那你就看看吧,而且还有几个Effective 条款 :) 希望不会让你失望. 该篇并没有涉及到 Framework源码,就算是挂羊头卖狗肉吧.希望延续上篇的高质量. http://blog.chinaunix.net/uid-20773131-id-572408.html
7.C#/Winform入门进阶强化扩展知识体系完善等知识点学习C#/Winform入门、进阶、强化、扩展、知识体系完善等知识点学习、性能优化、源码分析专栏分享,作为一名C#的Winform开发者,势必经历过从入门到自学、从基础到进阶、从学习到强化的过程。当https://blog.51cto.com/BADAOLIUMANGQZ/11663048
8.C#从入门到精通程序设计高级编程实例视频学习教程附带源码.docx教程列表:教程 1: C#视频教程 Visual C#2010 从入门到精通视频教程 C#4.0 教程教程 2: C#程序设计基于 VS2008 编程开发范例 C# 开发范例大全教程 3: C#视频教程 21 天学通 C#第二版视频教程 送源码 /PPT 教案 / 案例视频教程 4: C#开发实战 1200 例第 2 卷第 1 卷 配套视频 / 配套源码 / 两卷完整https://max.book118.com/html/2020/1120/7013005064003021.shtm
9.YSGStudyHards/DotNetGuide:C#/.NET/.NETCore学习【C#/.NET/.NET Core学习、工作、面试指南】记录、收集和总结C#/.NET/.NET Core基础知识、学习路线、开发实战、编程技巧练习、学习视频、文章、书籍、项目框架、社区组织、开发必备工具、技术前沿周刊、常见面试题、面试须知、简历模板、人才招聘、以及自己在学习和工作中的一些微薄见解。希望能和大家一起学习,共https://github.com/YSGStudyHards/DotNetGuide
10.罗分明个人网络博客asp.net,C#,js,数据库,web前端,学习笔记我是罗分明,欢迎来到我个人网络博客,我的联系方式QQ78630559,主要记录,asp.net,C#,js,数据库,web前端,我个人平时学习,以及工作问题解决方案笔记https://www.luofenming.com/
11.C#入门教程源码首页 程序开发 C#入门教程 C#入门教程源码 分享 关注 C#入门教程 共329小节 已有1480142人学过 2015年11月推出 课程概要 本套C#入门教程将从基础入手,教会您使用C#进行应用软件的开发。学会C#,便可以编写各种Windows桌面应用程序、WindowsStore应用程序以及Web应用程序等等。 教程程度: 初级中级 软件版本: Visual https://www.51zxw.net/Material.aspx?cid=548
12.全套完结零基础ASP.NETC#网站开发实战教程,最后更新202008大型工业跨平台软件C++源码提供,建模,组态!【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步 编辑推荐: · 为什么需要[EnumeratorCancellation]? · 使用C# 入门深度学习:Pytorch 基础 · 案例分享-导致MySQL崩溃的SQL语句 · .NET Core https://www.cnblogs.com/star-studio/p/12035587.html
13.C#.NET的新式开放源代码编程语言与开发人员一起学习 C# 通过C# 初学者视频系列中的实时编码演示,了解 C# 编程语言的概念和语法。 了解基础信息后,请在.NET 视频页面中浏览其他课程,你可以在其中了解如何使用 C# 生成任何类型的应用。 浏览所有课程 数据源自TechEmpower 第 21 轮中提供的官方测试。 https://dotnet.microsoft.com/zh-cn/languages/csharp
14.C#开发实例大全(基错)源码+C#开发实例大全(基错+提高卷)PDFC#源码,PDF2017-09-12 上传大小:915B 所需:50积分/C币 C#开发WindowsService程序源码加文档.pdf C#开发Windows+Service程序源码,里面详细介绍了如何开发Windows服务程序,有完整的说明文档,有实例代码可供参考,是你学习WindowsServer的好帮手 上传者:caohao时间:2011-08-19 https://www.iteye.com/resource/q651478191-9974943
15.200个C#实例源码分享吾爱破解谢谢楼主,收藏,学习。https://www.52pojie.cn/thread-997149-1-1.html
16.c#29个非常好的源代码适合初学者开发实例源码下载【C#】 域天加密锁型号读取工具 hbzsp于 2024-12-04 上传 【C#】 modbus通信助手学习 雨笑烟燃于 2024-12-03 上传 【C#】 轻量型CSV表格在C#窗体DataGridView控件中相互显示与保存的示例 laser88于 2024-12-02 上传 【C#】 LearnSite信息科技学习平台 https://www.haolizi.net/example/view_316623.html
17.C#高级编程(第9版)——C#5.0&.NET4.5.1C#高级编程(第9 版)——C# 5.0 & .NET 4.5.1XII与.NET 的区别,以及如何编写Windows 8 模式的程序。第Ⅳ部分—— 数据本部分介绍如何使用ADO.NET 访问数据库,学习ADO.NET Entity Framework。我们可以使用核心ADO.NET 获得最佳性能,而使用ADO.NET Entity Framework 可以方便地把对象映射到关系上。还讨论了现在https://www.douban.com/note/435179469/