一个极简鲁棒的C语言的动态数据类型扩展,取代诸如C++/Rust那些愚蠢的东西

项目地址:https://github.com/shajunxing/banana-cvar

我用过很多高级语言,喜欢简单的东西,讨厌C++,一直在想C语言能不能用最简洁的手段扩充动态语言特性,并且支持垃圾回收呢?偶然迸发出灵感,网上查了查没有人做过,那么开始动手吧。

思路很简单:

  1. 首先定义存储动态变量的结构体var,变量类型简单起见,参照Json标准,null/boolean/number/array/object足够用了,动态变量的使用均采用指针指向堆上分配内存的方式,所有动态变量都托管在pvarroot全局链表上。
  2. 然后定义存储栈变量信息的结构体ref,栈变量就是c源代码里定义的var *变量,称之为引用,通过vdeclare/vassign宏登记引用的地址以及指向动态变量的地址,登记在全局链表prefroot上。
  3. 最后最关键的,在垃圾收集阶段,如果引用现在指向的地址与先前登记指向的地址不同,就意味着该引用已失效(比如函数调用返回后栈值变化了、或者人为修改了),执行删除操作,把有效引用指向的动态变量(array/object需要递归)标记为正在使用中,然后对未使用的动态变量执行删除操作。
  4. 后续按需扩充功能,考虑设计一套扩展的动态语法,并写个翻译器翻译成c代码。
  5. 全局变量很少,如果需要多线程支持,可以包进结构体里并作为函数参数传递,但我认为没有必要,且每个线程一套,又不能相互交互,怎么看怎么别扭。

为了遵循大部分动态语言的使用习惯,规定以下的设计准则:

  1. 务必用宏vdeclare/vassign/var创建动态变量,如无必要,勿直接操作var *指针,除非你知道自己在做什么;游离在外的var *指针没有调用refer登记为引用的,相当于弱引用,垃圾回收时候会被删除;未分配的var *指针(指向NULL)在大部分函数里都会异常退出。
  2. 将a变量赋值给b变量,实际传递的是地址;为了节省内存,null/true/false都是全局常量;所有赋number/string原始值的,都是创建新变量,而非修改原变量;array/object另有一套增删改的函数。
  3. 对于异常处理,所有无法恢复的错误均执行exitif宏退出进程。
  4. 我也忘了使用到C语言最新标准的什么特性,反正最新版本GCC编译通过就是了,包含MinGW的makefile,别的操作系统自行修改。
  5. 这不是玩具,我的想法是用它替代C++/Rust之类走入歧途的复杂东西,反正我测试过程中还没有发现内存泄露等严重问题。
  6. 函数命名规范:可选缩写+完整单词+可选后缀,缩写的含义如下,当前用到的后缀只有一个,_s表示字符串参数带长度参数的安全函数,C语言字符串字面量可以安全使用不带_s的函数,别的情况建议用带_s的。
缩写说明
v动态类型的变量
r引用
zzero、zilch、zip,表示null,参见https://www.englishtrackers.com/english-blog/zero-zilch-zip-nil-nought-nothing-whats-the-difference/
bboolean
nnumber
sstring
aarray
oobject
wworld、whole,表示整体的、全局的
sbstringbuffer辅助工具

以下是函数/宏列表,以及对应的常见动态语言的语法(你一看就懂),和举例:

函数/宏动态语法说明/例子
dump()打印所有常量、变量和引用信息
void gc()垃圾回收
vassign(a, b)a = b
vdeclare(a, b)var a = b
struct var *znew()返回指向null常量的地址
zdeclare(a)var a = null
struct var *bnew(bool b)返回指向true/false常量的地址
bdeclare(a, b)var a = truebdeclare(a, true)
bool bvalue(struct var *pv)返回boolean变量的原始值
struct var *nnew(double n)创建number变量
ndeclare(a, b)var a = 3.14ndeclare(a, 3.14)
double nvalue(struct var *pv)返回number变量的原始值
var *snew_s(const char *s, size_t slen)
var *snew(const char *sz)
创建string变量
sdeclare(a, b)var a = “hello”sdeclare(a, “hello”)
char *svalue(struct var *pv)返回string变量的原始值(指向\0结尾的字符数组)
size_t slength(struct var *pv)a.length()返回字符串长度
struct var *sconcat(size_t num, …)var a = “hi”
var b = “all”
var c = a + b
sdeclare(a, “hi”)
sdeclare(b, “all”)
vdeclare(c, sconcat(2, a, b))
var *anew(size_t num, …)var a = [null, true, 3.14, “hello”]创建包含0个或多个成员的array变量
vdeclare(a, anew(4, znew(), bnew(true), nnew(3.14), snew(“hello”)))
adeclare(a)var a = []
void aclear(struct var *pv)v.clear()清空数组
size_t alength(struct var *pv)v.length()返回数组长度
void apush(struct var *pv, struct var *pval)v.push(val)数组末端插入,长度+1
struct var *apop(struct var *pv)v.pop()数组末端弹出,长度-1
void aput(struct var *pv, size_t idx, struct var *pval)v[idx] = val数组指定下标写入替换原有值,下标越界则程序退出
struct var *aget(struct var *pv, size_t idx)v[idx]取数组指定下标的值,下标越界则程序退出
asort(…)数组排序,未实现
struct var *onew()创建空对象
odeclare(a)var a = {}
void oclear(struct var *pv)v.clear()清空对象
size_t olength(struct var *pv)v.length()返回对象的元素数量
void oput_s(struct var *pv, const char *key, size_t klen, struct var *pval)
void oput(struct var *pv, const char *key, struct var *pval)
v[key] = val写入键值对
struct var *oget_s(struct var *pv, const char *key, size_t klen)
struct var *oget(struct var *pv, const char *key)
v[key]读取键对应的值,注意可能返回NULL,程序务必要做判断
struct var *vtojson(struct var *pv)json化任意变量,结果以字符串变量返回,注意:禁止套娃,循环嵌套的忽略
tojson(pv)print([null, [3.140000, “hi”], false])返回变量json化后的C字符数组,用于printf等函数
printf(tojson(anew(3, znew(), anew(2, nnew(3.14), snew(“hi”)), bnew(false))))
fromjson(…)解析json字符串,构建变量,未实现。

更多示例代码,参见test_var.c

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

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

相关文章

vue3中使用antv-S2表格(基础功能版)

先看展示效果: 可以调整行宽、列宽、自定义字段图标、表头图标、添加排序、显示总计、小计等 首先确保搭建一个vue3项目环境,从0开始的小伙伴着重看第一点: 一、搭建vue3项目环境 首先创建一个vue3vitets项目,可以查看下面相关…

Mojo语言初次入手

Mojo的出现被认为是编程语言领域的一大进步,有观点认为它可能是几十年来最大的编程进步???!!! 让我来试试,看看是怎么回事。 安装Mojo 打开命令行界面。执行以下命令来安装Mojo SDK: curl -s https://get.modular.com | sh - 3.接下来&…

大厂Java笔试题之百钱买百鸡问题

题目:公元五世纪,我国古代数学家张丘建在《算经》一书中提出了"百鸡问题":鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。 百钱买百鸡,问鸡翁、鸡母、鸡雏各几何? 现要求你打印出所有花一…

uniapp——长按识别二维码

说明 转变思路&#xff0c;长按图片&#xff0c;进入预览图片&#xff0c;这时候再长按就可以了。 <view class"codeMain"><view class"codeWhite" longpress"handleLongPress(i.image(qrcode))"><image :src"i.image(qrc…

解决前端笔记本电脑屏幕显示缩放比例125%、150%对页面大小的影响问题--数据可视化大屏

近期在工作中遇到一个问题&#xff0c;记录一下&#xff0c;在项目上线之后&#xff0c;遇到一个问题&#xff0c;即缩放到90%时&#xff0c;页面字体比默认的100%字体大&#xff0c;一开始毫无头绪&#xff0c;经过一番的Google...Google...Google....&#xff0c;终于找到了解…

游戏服务器DDOS克星-抗D盾(游戏盾)

随着网络游戏市场的不断扩大和发展&#xff0c;游戏服务器遭受DDOS攻击的频率也在逐年增加。DDOS攻击的主要目的是使游戏服务器瘫痪&#xff0c;使得游戏无法正常进行&#xff0c;导致游戏运营商巨额损失。鉴于此&#xff0c;针对游戏服务器的防DDOS攻击技术德迅云安全自主研发…

冲刺2024年思维100春季线上比赛:做做历年思维100真题(附答案)

今天是2024年4月14日&#xff0c;距离2024年春季思维100活动第一阶段的线上比赛4月20日还有6天。那么2024年思维100活动的考试重点是什么呢&#xff1f;主办方未公布&#xff0c;我们可以从历年的思维100真题中来分析和推测&#xff0c;把历年真题和背后的知识点吃透了&#xf…

6.0 MapReduce 使用

6.0 MapReduce 使用 分类 编程 在学习了之前的 MapReduce 概念之后&#xff0c;我们应该已经知道什么是 Map 和 Reduce&#xff0c;并了解了他们的工作方式。 本章将学习如何使用 MapReduce。 Word Count Word Count 就是"词语统计"&#xff0c;这是 MapReduce 工…

深度剖析Java中的String类

目录 引言 String类的特性 String类的部分实现代码&#xff1a; 不可变性&#xff1a; 补充&#xff1a; 常量池&#xff1a; 不可变性的好处 创建String对象 创建String对象的常用的三种方法如下&#xff1a; 使用常量串构造&#xff08;最常用&#xff09;&#xf…

抖音滑块验证码加密的盐的位置

最近更新后之前很容易找到盐的位置的方法变了&#xff0c;抖音特意把盐隐藏起来了 {"reply": "RJC","models": "yAd8rl","in_modal": "DTn0nD2","in_slide": "ou7H0Ngda","move": …

Hystrix应用:如何在Spring Boot中使用Hystrix?

Hystrix应用&#xff1a;如何在Spring Boot中使用Hystrix&#xff1f; 引言 在微服务架构的发展过程中&#xff0c;面对复杂的服务依赖和不可预见的系统故障&#xff0c;如何提升系统的容错能力成为了一个非常急迫且重要的能力。 由 Netflix&#xff08;网飞&#xff09;公司…

基于java+springboot+vue实现的网上购物系统(文末源码+Lw+ppt)23-42

摘 要 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;网上购物系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为…

Ubuntu-22.04安装VMware虚拟机并安装Windows10

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、VMware是什么&#xff1f;二、安装VMware1.注册VMware账号2.下载虚拟机3.编译vmmon&vmnet4.加载module5.安装bundle 三、安装Windows101.基础配置2.进阶…

【leetcode面试经典150题】50. 插入区间(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

【算法】分治-快排

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 前言1. 75. 颜色分类1.1 分析1.2 代码 2. 912. 排序数组2.1 分析2.2 代码 3. 215. 数组中的第K个最大元素3.1 分析3.2 代码 4. LCR 159. 库存管理 III4.1 分析4.2 代码 前言 分治就是分而治之 1. 75. 颜色分类 1.1 分析…

滚雪球学Java(73):Java中的引用类型: 弱引用、软引用与强引用详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

Scrum.org认证PSM(Professional Scrum Master)官方认证班

课程简介 Scrum是目前运用最为广泛的敏捷开发方法&#xff0c;是一个轻量级的项目管理和产品研发管理框架&#xff0c;旨在最短时间内交付最大价值。根据2022年全球敏捷状态报告&#xff0c;Scrum的应用占比已经达到87%。 Scrum.org 由 Scrum 的联合创始人 Ken Schwaber 创立…

git log详解

文章目录 git log -p其他常用的参数 git log是用来查看历史提交记录的&#xff0c;那么这些记录包含什么呢&#xff1f;如果你不指定分支或者master&#xff0c;默认情况下git log显示的是目前你HEAD的位置的git提交日志&#xff0c;默认不加参数&#xff0c;git log显示如下&a…

【C++风云录】融入虚拟现实的魅力:借助 C++ 库打造沉浸式的游戏体验和交互效果

点燃创造力&#xff1a;解锁 C 库的潜力&#xff0c;构建令人惊叹的物理模拟和游戏应用 前言 在现代的游戏和虚拟现实应用中&#xff0c;物理模拟和真实的交互体验是不可或缺的要素。为了实现逼真的物理效果和流畅的游戏体验&#xff0c;开发人员需要依赖强大的物理模拟库和游…

如何在ADS中实现数据的导入和导出

1 MDIF接口 ADS提供了一种通用的MDIF格式文件&#xff0c;允许用户使用一个通用的数据接口实现导入和导出的功能&#xff0c;其Help文件中的简介如下&#xff1a; 2 数据的导入 实现数据导入功能之前&#xff0c;数据必须遵从一定的标准格式&#xff0c;如下图所示&#xff0c;…