How to write perfect C code
Several days ago, I was involved in an argument about choice of C or C++. What I ignored was "language is less important than coder". a bad C# writer only write shit-like C# but a professional C programmer could design perfect C, Notwithstanding C# is much more powerful than C,
So how to write perfect C code? We just illustrate that by cJson, a famous pure-C tiny json formatter.
1. Power C pointer, make point operation awesome
The string-comparison of cjson like melody, this ability might need you a lot experience:
static int cJSON_strcasecmp(const char *s1,const char *s2)
{
if (!s1) return (s1==s2)?0:1;
if (!s2) return 1;
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)
if(*s1 == 0) return 0;
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}
So how you write a same strcasecmp function? Try more C code.
2. Reasonable code indent
Someone might tell you write code with same indent-style, "the wrap position, where to put a bracket..." However, most people are accustomed to reading left to right without pause. So a better code reader understand is more important than that so-call rule and style just like follows:
static const char *parse_value(cJSON *item,const char *value)
{
if (!value) return 0; /* Fail on null. */
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
if (*value=='\"') { return parse_string(item,value); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value); }
if (*value=='{') { return parse_object(item,value); } ep=value;return 0; /* failure. */
}
Does Code below make it more easy to understand than standard indent style? As you can easily compare difference between each case of switch structure.
3. Chain-style function design
Chain-style function means you can invoke them with merge them into a chain, as A(B(C)).
Linq (a chain-style code sugar ) greatly improve beauty of C#, could
make your code designed like: Select.Where.Orderby... As standard C do
not offer extend-function. But you could still make the chain like
Order(Select(Where(Data))) . Some little bit harder ,but much more
easier than other code style, just like code in cJson:
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. *
The difficulty is the rope which connect modules into a chain. In
Linq, it's a interface called IEnumerable, a compiler-level state
machine. In cJson code behind, it's the position of processing pointer.
4. Hook me!
Standard C do not have delegate, function override. But there are some
other powerful mechanism called hook, achieved by function pointer. You
could change a function pointer behaviour by assign a different function
with same parameters and return value. Example as follow:
void cJSON_InitHooks(cJSON_Hooks* hooks)
{
if (!hooks) { /* Reset hooks */
cJSON_malloc = malloc;
cJSON_free = free;
return;
} cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
}
Awesome right? You can change memory allocation and free behaviour by using hook!
5. Offer default value of function parameters
In order to make your user more convenient when using your perfect library, please offer them some override functions! C might not allow you define two same name function by different parameter table. But you could still do this:
/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
6. Marco and #define
Marco is only way to make C transplant in different platform.
6. Improve algorithm!
C style code is different than C# or Java, the languages with powerful libraries. Sometimes because of compatibility or performance, using STL or some 3rd libraries is not a good choice. So you need to achieved them by yourself. This does not means you should write "Stack.c" or "Stack.h" to define a full-functional stack. It's too heavy and unnecessary,right? But the core algorithm of stack will greatly affect your code style by merge an easy array-achieved stack by several simple code.
The example in cJson is tree structure, as json is a
nature tree. The author merge tree algorithm into the code by recursive
and pointer without any trace. Perfect!
Try more C code, try more perfect improvement, guy!
How to write perfect C code的更多相关文章
- java代码格式化
Java source formatting You are probably familiar with the Eclipse hotkeys to automatically format yo ...
- Project Perfect让Swift在server端跑起来-Perfect in Visual Studio Code (四)
编者语 : 本系列文章已经被Perfect官方引用了,这样的感觉非常好.感恩!Thx all ! Visual Studio Code是一个轻量级的编辑器,但也功能丰富,通过插件你能够完毕如Cordo ...
- Peer Code Reviews Made Easy with Eclipse Plug-In
欢迎关注我的社交账号: 博客园地址: http://www.cnblogs.com/jiangxinnju/p/4781259.html GitHub地址: https://github.com/ji ...
- Perfect smooth scrolling in UITableViews
https://medium.com/ios-os-x-development/perfect-smooth-scrolling-in-uitableviews-fd609d5275a5 Diffic ...
- Unit Testing PowerShell Code with Pester
Summary: Guest blogger, Dave Wyatt, discusses using Pester to analyze small pieces of Windows PowerS ...
- Code Complete阅读笔记(二)
2015-03-06 328 Unusual Data Types ——You can carry this technique to extremes,putting all the ...
- Your Job Is Not to Write Code
I am lucky enough to work with a small team of fantastic engineers who truly care about their custom ...
- ResolveUrl in ASP.NET - The Perfect Solution
原文:ResolveUrl in ASP.NET - The Perfect Solution If you are looking for ResolveUrl outside of Page/Co ...
- 如何在python脚本开发做code review
在软件项目开发中,我们经常提到一个词“code review”.code review中文翻译过来就是代码评审或复查,简而言之就是编码完成后由其他人通过阅读代码来检查代码的质量(可编译.可运行.可读. ...
随机推荐
- Ubuntu环境变量(.profile)加载顺序
Ubuntu下启动的时候的的加载环境变量的过程大致为: /etc/enviroment /etc/profile -->/etc/bash.bashrc --> /etc/prof ...
- JS 将数字转化成为货币格式
最近由于项目的需要需要将数字format成货币格式,自己搞了半天效果不是很好,博客园有篇问题很好,再次转载记录一下 http://www.cnblogs.com/mingmingruyuedlut/a ...
- python 函数之day3
一 函数的语法及特性 什么是函数? 定义:函数是一个功能通过一组语句的集合,由名字(函数名)将其封装起来的代码块,要想执行这个函数,只要调用其函数名即可. 特性: 减少重复代码 使程序变的可扩展 使程 ...
- Java学习【1】
一.Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称. 2005年6月,SUN公司公开Java SE 6.Java ...
- Python之路第一课Day9--随堂笔记之一(堡垒机实例以及数据库操作)未完待续....
一.堡垒机前戏 开发堡垒机之前,先来学习Python的paramiko模块,该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接: ...
- centos 格式化分区
#格式化U盘,成fat32 fdisk -l #获取U盘设备信息 #Disk /dev/sdc: 16.0 GB, 16025387008 bytes, 31299584 sectors#Units ...
- WDM驱动加载方式理解
当PC得知有新设备插入时,总线驱动会创建相应的物理驱动PDO,然后提示有新设备插入,这时候调用相应Driver的AddDevice方法创建功能驱动FDO 下面是一个典型的AddDevice方法 #pr ...
- snmp学习笔记
snmp5.5 client 包含头文件 #include <net-snmp/net-snmp-config.h> #include <net-snmp/net-snmp-incl ...
- JAVA的continue用法
JAVA的continue用法: public class test{ public static void main(String [] args){ for(int i=0;i<=10;i ...
- 编写具有单一职责(SRP)的类
这两周我需要对一个历史遗留的功能做一些扩展,正如很多人不愿意碰这些历史遗留的代码一样,我的内心也同样对这样的任务充满反抗.这些代码中充斥着各种null判断(你写的return null正确吗?),不规 ...