通过看linux环境相关源码学习编程(持续更新)

开发自己的编程语言 编程是一门艺术,而编程语言则是这门艺术的缔造者。计算机系的很多学生都对编程语言涉及到的编译原理表示畏惧,其实编译原理本身并不复杂,不过由于目前市面上有关编译原理的书籍大部分都是由国外的原著翻译过来的,翻译过来的文字很多时候没办法完美的表达出原文的意思,所以有时候让人感觉像天书,例如国外有名的 龙书(Dragon book),龙书是Alfred V. Aho等人于1986年出版的,虽然时隔了几十年, 阅读详情

第一条:结合枚举enum声明和宏定义来定义变量:这样可以不用去定义一个enum变量(Form Memcahced)

enum
  {
    DT_UNKNOWN = 0,
# define DT_UNKNOWN	DT_UNKNOWN
    DT_FIFO = 1,
# define DT_FIFO	DT_FIFO
    DT_CHR = 2,
# define DT_CHR		DT_CHR
    DT_DIR = 4,
# define DT_DIR		DT_DIR
    DT_BLK = 6,
# define DT_BLK		DT_BLK
    DT_REG = 8,
# define DT_REG		DT_REG
    DT_LNK = 10,
# define DT_LNK		DT_LNK
    DT_SOCK = 12,
# define DT_SOCK	DT_SOCK
    DT_WHT = 14
# define DT_WHT		DT_WHT
  };

第二条:在定义结构体的时候,可以采用unsigned char格式,这样就避免字节填充(Form FastCGI)

typedef struct {
    unsigned char version;
    unsigned char type;
    unsigned char requestIdB1;
    unsigned char requestIdB0;
    unsigned char contentLengthB1;
    unsigned char contentLengthB0;
    unsigned char paddingLength;
    unsigned char reserved;
} FCGI_Header;

对于这个例子来说,本来requestID应该定义为int,为了防止字节填充所带来的内存浪费,采用上面的方式可以避免字节填充。即requestID=requestIDB1<<8+requestIDB2


第三条:当一个结构体包含的信息很多,当外部程序只需要内部的部分信息时,可以通过把该部分信息放在一个独立的结构体中,并把该小结构体放在大结构体的最前面,此时可以同一个首指针访问到两个结构体。这种信息的封装虽然不能保证信息安全,但是可以减少内部和外部程序之间耦合度和关联度(原先两个程序之间的关联是一个大结构,现在通过一个小的就可以了)(Form linux/ipc/)


大的结构体如下:

/* one msq_queue structure for each present queue on the system */
struct msg_queue {
	struct kern_ipc_perm q_perm;
	time_t q_stime;			/* last msgsnd time */
	time_t q_rtime;			/* last msgrcv time */
	time_t q_ctime;			/* last change time */
	unsigned long q_cbytes;		/* current number of bytes on queue */
	unsigned long q_qnum;		/* number of messages in queue */
	unsigned long q_qbytes;		/* max number of bytes on queue */
	pid_t q_lspid;			/* pid of last msgsnd */
	pid_t q_lrpid;			/* last receive pid */

	struct list_head q_messages;
	struct list_head q_receivers;
	struct list_head q_senders;
};
第一个小的结构体如下:

struct kern_ipc_perm
{
	spinlock_t	lock;
	int		deleted;
	int		id;
	key_t		key;
	uid_t		uid;
	gid_t		gid;
	uid_t		cuid;
	gid_t		cgid;
	umode_t		mode; 
	unsigned long	seq;
	void		*security;
};
这样就可以通过一个struct kern_ipc_perm的指针把部分信息(一个队列的基本特征信息)开放给外部程序,而struct msg_queue中list_head q_messages为真正队列内容,在有些程序只需要特征信息而不需要队列内容时候,不需要知道struct msg_queue结构。假如现在知道特征信息后,需要继续知道具体的队列内容,只需要对struct kern_ipc_perm进行转换为struct msg_queue,就可以得到具体队列内容。

第四条:利用结构体中隐性字段来存储该结构体的内容字段,利用直接字段来存储特征内容(Form linux /ipc)

struct msg_msg {	
	long  m_type;          
	int m_ts;           /* message text size */	
	/* the actual message follows immediately */
};

在上面的例子里面,该结构体是用来存储一个消息(包括特征和具体内容),但是该结构体中只有一个消息类别和消息大小的字段,没有一个字段来存储实际消息内容,其实里面是利用了一个隐性字段来存储消息内容。struct msg_msg *p+sizeof(msg_msg)+[0,p->m_ts]之间就是具体的消息内容。

该技巧在写类库的时候比较好用。比如一个queue的队列,提供队列的构造,元素添加,元素删除等功能。在类库的眼中,我只关心队列中每一个元素的next字段,而不关心队列元素其他内容字段。因此在类库中定义一个节点元素和一个队列如下:

struct queue_node{
     struct queue_node *next;
 };

 struct queue{
     struct queue_node *head;
     struct queue_node *tail;
};
在用户代码中,定义一个和struct queue_node结构体格式一样的结构体:第一个元素为next字段,后面可以添加内容字段。比如

struct myNode{
     struct myNode *next;
     int data;
};
类库函数的参数为void *指针,在内部可以把该指针转化为struct queue_node类型的指针进行处理。
类库函数的对该指针进行处理以后,返回一个void *,在用户代码,可以把指针转化为我们想要的节点指针。

//类库代码
int addTail(void *node,struct queue *queue)
{
struct queue_node *qn=(struct queue_node *)node;
//用户代码
struct  myNode *node=(struct myNode *)removeHead(q);

这样在类库代码中,不需要知道用户代码中具体节点的节点内容。不知道还有没有更好方法?


第五条:利用宏定义来简化函数的编写和函数的使用,针对参数为变量,指针,指针的指针的情况   (Form php/zend.h)

具体看例子:

#define Z_REFCOUNT_PP(ppz) Z_REFCOUNT_P(*(ppz))

#define Z_REFCOUNT_P(pz)   zval_refcount_p(pz)

#define Z_REFCOUNT(z)      Z_REFCOUNT_P(&(z))


static zend_always_inline zend_uint zval_refcount_p(zval* pz) {
return pz->refcount__gc;
}




《编程语言简介》 对于编程语言的个人看法,参考了很多网上文章 阅读详情

相关推荐

Shell教程:系统自带的解释型语言和解释器

Shell 参考资料: 菜鸟教程,免费的学习站点 C语言中文网,部分免费的一个学习站点,内容深入浅出,价格不贵,大家可以支持一下 Tips: Shell应该是理解Linux系统操作重要和基础的一步,使用Linux作为工作平台的人应该了解Shell; 作为解释型语言,Shell可以带来许多便利; 对于一般工科学生,这类工具够用即可,除非真的打算靠这方面的能力混口饭吃; 更新于19/09/13,...

weixin_45564064的博客 1410

linux应用程序开发详解(PDF+源码)

linux应用程序开发详解),包含了《linux应用程序开发 》的(PDF+源码)很好的学习资料

通过C#实现矩阵求逆-简单版

原理简单的C#求逆方法

Ratatoskr_01的博客 1705

献给新手,如何阅读Linux源码(转)

常常有人问:我想学习内核,需要什么基础吗?Linus Torvalds本人是这样回答的:你必须使用过Linux。 这个……还是有点太泛了吧,我想下面几个基础可能还是需要的,尽管不一定必需:   1, 关于操作系统理论的最初级的知识。不需要通读并理解《操作系统概念》《现代操作系统》等巨著,但总要知道分时(time-shared)和实时(real-time)的区别是什么,进程是个什么东西,CPU和系

学而时习之 2万+

Python自学教程第2期-求100以内奇数和

前言:Python是一门需要不断实践练习的编程语言,本文档将AI大学堂学员交流群的Python每周练习进行汇总,希望各位小伙伴能够多进行实践练习,逐渐爱上这门神奇的编程语言,掌握它并在生活中能够使用它。 1 解题思路 对100以内的奇数求和,有四种常见的解题方法: 用range函数遍历100以内的奇数,然后用sum函数求和 for 循环嵌套if语句,将100以内的奇数相加求和 while循环将100以内的奇数相加,并打印求和 用递归方法求和 2 解题方法 方法一: sum函数 首先用ra

AIdaxue1的博客 3万+

Scheme语言的循环实现

在Scheme中,循环是一种通过递归实现的复杂概念。这种以递归为基础的编程方式虽然不同于传统的命令式编程风格,但却使得方案更加简洁和优雅。通过理解基本的递归概念,掌握尾递归的优化技巧,以及熟练使用let和letrec构造,我们可以在Scheme中巧妙地实现各种循环功能。本文到此结束,探索了Scheme中循环实现的多种方法。尽管没有传统意义上的循环结构,仍然可以通过赋予编程更多的灵活性和创造性,从而实现强大的编程能力。

2501_90494588的博客 445

Linux应用开发自学之路

  前言         在 「关于我 」那篇博文里,朋友们应该知道了我不是科班出身,是由机械强行转行到Linux应用开发方向。下面我就详细向大家介绍自己这一路上的转行历程,希望对大家有所启发。   我是学机械专业的,对于机械专业我还是很感兴趣,而且当年这个专业也是我自己选择的。本科时成绩没排第一,但也排专业前列。硕士时成绩一直是专业第一,还拿过国家奖学金。由此可见,我还是挺热爱机...

码到成功 7万+

主流编程语言的特点分析

让编程菜鸟爱上iPhone开发1-Swift+iOS8版 考虑到很多读者从未接触过任何编程语言,这里对其它几个主流语言的特点和作用稍微说明一下: 1. Java语言是当今最普遍使用的开发语言,它简单易学(相对C++,C和Objective-C),且跨平台性非常强,对网络开发的支持令人称赞。很多企业使用Java语言来开发商业相关的网络应用。此外,Java语言也是开发Android应用的必

独立开发者 2501

Brainfuck极简编程语言:从图灵机模型到Hello World实战

图灵机是计算机科学的理论基础模型,它通过无限长的纸带、读写头和状态控制器定义了计算的基本原理。基于这一模型,图灵完备性成为衡量编程语言计算能力的核心标准,意味着语言能够模拟任何可计算过程。Brainfuck作为一门极简的图灵完备语言,其技术价值在于用仅有的八个指令(如指针移动、数值增减和循环控制)直接映射底层内存操作,为开发者提供了理解计算本质的独特视角。在工程实践中,Brainfuck常用于编程思维训练、代码高尔夫挑战和编译原理教学,通过亲手实现内存管理和控制流,帮助程序员深化对高级语言抽象机制的理解。本

weixin_33912453的博客 324

纯C打造轻量级brainfuck脚本语言解释器

本人大一,最近在搞CTF的时候偶然发现一种很好玩的脚本语言(应该算是吧)brainfuck,顾名思义这种语言很变态(强奸你的脑子)brainfuck是一种极小化的编程语言,只有8种指令。brainfuck是图灵完全的,也就是说,你用C写的所有程序、算法都可以用brainfuck实现。 它是由Urban Müller在1993年创建的。由于fuck在英语中是脏话,这种语言有时被称为brainf

言叶之庭 2668

Rust语言的循环实现

Rust的循环结构提供了强大的控制能力,使得开发者可以根据需求选择最合适的循环方式,从简单的无限循环到复杂的条件和多层嵌套循环,Rust都能轻松应对。同时,结合强大的迭代器特性,使得在循环中处理数组和集合变得更加高效和简洁。通过实际示例,本文展示了Rust中各种循环的使用场景和基本语法。无论是在处理简单的计数、复杂的模式匹配,还是操作集合,掌握这些循环结构是学习Rust编程的重要一步。希望本篇文章能帮助读者更好地理解Rust中的循环实现,进而在实际项目中灵活应用。

2401_90032281的博客 768

从零实现C语言解释器:编译原理实战与编程语言设计入门

编程语言是现代软件开发的基础工具,其核心原理涉及词法分析、语法解析和解释执行等关键技术。理解这些底层机制不仅能提升对现有语言特性的洞察力,还能为设计领域特定语言(DSL)奠定基础。通过实现一个精简的解释器,开发者可以直观掌握抽象语法树(AST)的构建与遍历、递归下降解析等核心概念。本文以GitHub热门项目daughter为例,剖析如何用C语言构建微型编程语言,并演示如何为其添加内置函数。这种实践方法将编译原理从抽象理论转化为可调试的代码,特别适合希望深入理解语言运行时机制和解释器设计的开发者。通过动手实现

weixin_34292402的博客 348

Otterlang编程语言设计解析:从解释器实现到脚本语言开发实践

编程语言设计是计算机科学的核心领域,涉及从底层原理到上层应用的完整技术栈。解释型语言通过词法分析、语法分析和抽象语法树构建,将源代码转换为可执行指令,其动态类型系统和灵活的数据结构为快速开发提供了便利。在工程实践中,脚本语言因其简洁语法和快速迭代特性,常被用于自动化任务、原型开发和领域特定语言构建。Otterlang作为一个实验性编程语言项目,展示了如何通过极简主义语法设计、函数作为一等公民等现代语言特性,在保证表达力的同时提升代码可读性。该项目不仅实现了完整的解释器工作流程,包括递归下降解析器和基于哈希表

weixin_30723433的博客 392

shell编程之循环语句与函数

判断while后的条件测试操作结果,如果条件成立,则执行do……done循环体中的命令序列,返回while后再次判断条件测试结果,如果条件仍然成立,则继续执行循环体,再次返回到while后,判断测试条件结果……作用:在执行循环语句时,可以根据特定条件反复执行命令序列,直到该条件不满足时,在脚本中避免死循环情况,可在循环体内的命令序列中修改测试条件的语句,当测试条件不再成立时,从而结束循环。注:在使用函数参数时,函数名称在前参数在后,函数名与参数之间用空格分隔,可以有多个参数,参数使用$1、 2、3……

m0_62479059的博客 1474

Python基础—基础语法、选择循环、函数

Python基础篇:主要介绍了python相关的前言简介、基础语法、选择循环结构以及函数的使用,后续将进一步深入python的学习,和Java还是有点区别的。

weixin_49383196的博客 868

大话编程:非常有趣的循环(Python语言可视化海龟画图演示)

在日常工作和生活中,我们经常会遇到一件事情要重复做很多次的这种情况发生。在编程中,我们也会遇到这种情况,循环这种机制,就是专门用来处理这种需要不断重复做的事情的方法。通过几分钟的阅读,你将会掌握这种机制和编程手法。 循环就是一件事情重复做 首先我们来看一下一个编程例子,现在我们要使用Python中的海龟库来画几个圆(如果你不了解海龟库可以关注我查看之前的文章哦,有详细的入门介绍) 首先...

大周的技术屋 2869

JavaScript—分支结构和循环结构整理

流程控制是指通过控制代码的执行顺序来完成要实现的功能,流程控制的3种结构如下:if语句也称为条件语句、单分支语句,当满足某种条件时,就进行某种处理。当条件表达式为真时,执行下面的代码。 在没有'{}'的时,if控制范围是到其后的第一条语句 2. if…else语句 if…else语句也称为双分支语句,当满足某种条件时,就进行某种处理,否则进行另一种处理。 注意:else是关键字,但是不能单独使用,必须和if结合使用。 if…else if语句也称为多分支语句,可针对不同情况进行不同的处理。

m0_57781768的博客 598

S7-200SMART系列全套接线说明

SMART200接线方法,输入,输出,模拟量,面板,扩展糟等,并且详细说明接线原理。

文都龙哥 1万+
上一篇: linux 常用头文件
下一篇: CGI运行机制和基本环境变量备忘
ColZer
博客等级 码龄14年 42粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值