如何將C語言發揮到極致?

都說C語言是系統級編程語言,windows unix Linux 都用到C 。但是就我個人而言,就是有在硬體編程的時候才會用到C語言,而且感覺硬體編程所用的C非常簡單,用用控制結構阿數組阿位操作什麼的,感覺這只是非常淺非常表面的C,可能都沒有發揮出C真正威力的十分之一。所以我一直很好奇,如何將C發揮到極致?需要了解其他什麼知識才可以發揮到極致,數據結構?演算法?操作系統?編譯原理? 還是...?求大神賜教!


將一種語言發揮到極致並不是看語言的語法是簡單還是複雜,而是要看你用語言要實現的東西在設計上如何能發揮極致。就拿C語言來說,最直接的例子,Linux操作系統內核,其代碼不過也就是數據結構,位操作這些東西,但是困難的是操作系統的模型本身: 如何管理內存,如何調度線程,如何統籌資源……這些邏輯都包含很精巧的設計和很複雜的演算法,但是用C語言實現卻還是靠那些最基本的語法

最後,比C還要簡單粗暴的語言是彙編,那玩意兒直接和CPU指令集對應了,比C的語法還單調,要寫個結構體都很費勁,但是原始的操作系統和編程語言編譯器都是用彙編寫的


更大型的項目一般要用到面向對象程序設計的思想。

對,沒看錯,C,面向對象。

比如說把我們操作的某種通用類型定義為一組函數指針的集合:

// myclass.h

struct _MyObject;

typedef struct _MyClass{
struct _MyObject *(*_new)();
void (*_delete)(struct _MyObject*);
void (*init)(struct _MyObject*);
void (*destruct)(struct _MyObject*);
void (*set_data)(struct _MyObject*, int size, void *data);
void *(*get_data)(struct _MyObject*);
int (*work)(struct _MyObject*);
void (*release)(struct _MyObject*);
} MyClass;

typedef struct _MyObject{
MyClass *classptr;
} MyObject;

external MyClass SubClass;

typedef struct _SubClass_Object{
MyObject _myobject;
void *data;
}SubClassObject;

// myclass.c

static MyObject *subclass_new(){
return (MyObject*)malloc(sizeof(SubClassObject));
}

static void subclass_delete(MyObject *obj){
free(obj);
}

static void subclass_init(MyObject *ptr){
SubClassObject *_this = (SubClassObject*)ptr;
_this-&>_myobject.classptr = SubClass;
_this-&>data = NULL;
}

static void subclass_destruct(MyObject *ptr){
SubClassObject *_this = (SubClassObject*)ptr;
if(_this-&>data != NULL){
_this-&>_myobject.classptr-&>release(ptr);
}
}

static void subclass_set_data(MyObject *ptr, int size, void *data){
SubClassObject *_this = (SubClassObject*)ptr;
if(_this-&>data != NULL){
// Why not subclass_release(ptr)? Think about it.
_this-&>_myobject.classptr-&>release(ptr);
}
if(size &> 0){
_this-&>data = malloc(size);
memcpy(_this-&>data, data, size);
}
}

static void subclass_get_data(MyObject *ptr){
SubClassObject *_this = (SubClassObject*)ptr;
return _this-&>data;
}

static void subclass_release(MyObject *ptr){
SubClassObject *_this = (SubClassObject*)ptr;
if(_this-&>data){
free(_this-&>data);
_this-&>data = NULL;
}
}

MyClass SubClass = {subclass_new, subclass_delete, subclass_init, subclass_destruct,
subclass_set_data, subclass_get_data, NULL, subclass_release};

MyObject *create_object(MyClass *_class){
MyObject *newobj = _class._new();
_class.init(newobj);
return newobj;
}

void delete_object(MyObject *obj){
MyClass *class = obj-&>classptr;
class.destruct(obj);
class._delete(obj);
}

int main(){
MyObject *newobj;
char data[] = "Test data";
newobj = create_object(SubClass);
newobj-&>classptr.set_data(newobj, data, sizeof(data));
printf("%s
", (char*)(newobj-&>classptr.get_data(newobj)));
delete_object(newobj);
return 0;
}

其實就是C++裡面的類,為什麼一定要用C寫而不是直接用C++,你問我,我也不知道。


請參考 Vala 語言。

https://wiki.gnome.org/Projects/Vala

摘錄簡介如下:

Introduction

Vala is a programming language that aims to bring modern programming language features to GNOME developers without imposing any additional runtime requirements and without using a different ABI compared to applications and libraries written in C.

簡單來說就是個先變成 C 再由 C 編譯器去編譯的奇葩語言。(但是出奇地好用?)


c語言的宏是很強大的(當然也很容易變成大坑),可以看看lua的源碼。


C就這麼點語法,能被稱作極致的,大概也只有各種複雜宏+亂搞指針模擬出來的高級語言特性吧

你看有人已經說C用函數指針來模擬對象的成員函數了,估計還會有人說hack結構體內存布局達到的繼承吧


請參考 Cello 這個庫。

或者 eatonphil/Viola 也行。

當然,你也可以去研究下 GObject。

我以前也寫過個 C 支持面向對象的示例代碼:先有Class還是先有Object? - zpan 的回答 ,支持 metaclass 哦。準備以後做些擴展,弄完整一些,做成一個庫,放 GitHub 上去。


嗯……我猜,你可以試試把c變成動態語言?

//這是不是就是傳說中的jit啊


反正 C 是圖靈完備的,剩下的你自己看著辦。


昔年曾目睹某神用 assemble instruction set 這種 low 到極致的 low-level 語言在區域網八人對戰中作弊,瞠目結舌後,頓覺昨夜和基友們為語言運用觀點的所有爭論,還有無數次遊走在互毆邊際的所有相關探討,都是浮雲,皆為虛幻,我們特么的確實圖森破!圖樣都沒資格。

這一事件徹底扭轉了我當時尚未完全成熟的編碼世界觀,距今約十五年前。


邀請我幹啥

說實話看到這問題我很無語,將C發揮到極致,那你去參加信息學競賽吧。

但是我看到樓上的回答之後還是感到很強。

確實,函數指針好像真的可以實現閉包誒。

好像真的可以實現fake OOP誒。

不過在我個人看來,要不要試試用純C寫一個Android應用程序?Java只能重載Application,Java代碼量限制在3kb以內,剩下拿C寫,這應該是個很牛逼的事(另外,不能用圖片,全部手動造bitmap)


瀉藥。幹嘛用到極致?!!!蛋不疼么?!!邊際效應知道不?!!非得事倍功半才爽?


當然是 FFI 大法啦

使用 ECL 在 C 程序中調用 Lisp 代碼


用c寫個c++。

再用c++寫個遊戲引擎。

再用遊戲引擎寫個遊戲伺服器,遊戲客戶端。

用這個遊戲框架寫個文明5。


1. 定義數據量很大的數組時,直接用#include xxx.txt在定義體內

int array [] = {

#include "constants.txt"

};

2. compile time的ASSERT

#define ASSERT(cond) sizeof(int [!!(cond)]). 這個有很多寫法,比如這裡是利用了c語言里數組大小不能為0的規則。如果cond為false,則沒法通過編譯。比如,只想讓代碼能在int大小是4的平台上通過編譯,可以這樣寫

ASSERT(sizeof(int)==4):

3. 用setjmp和longjmp實現異常和協程。一些嵌入式系統metal bare programming可以直接用setjmp和longjmp實現一個協同式調度的os.


補充一下最高票的答案~

個人覺得,c語言中已經有了面向對象的思想了~

例如linux內核中的回調函數

我手上的這份linux內核源碼反正有幾百M


無論何種語言,所謂極致,取決於使用者的水平,C語言是系統級的,有多少語言本身是C實現的?但是,再厲害的武器,到了棒槌手裡也都是燒火棍。


數學開始只有1234加減乘除,推導出了微積分群論實變復變泛函………………


多看看一些優秀的開源項目你就知道了,比如linux內核,skynet,redis,nginx . 這麼說吧,程序寫的好不好的標準,其實是和語言沒多大關係的,語言是用來幫助你實現這些標準(目標)的工具


我覺得開源程序lua寫的很好啊,可以看看


C語言用發揮到極致么?已經這麼極致了----


推薦閱讀:

Windows 之後,什麼操作系統可能會佔據主流?
Amiga電腦傳奇(四)
一個進程能不能在多個核上跑?
中斷向量為什麼叫中斷向量?
計算機編程中經常提到的副作用,具體指的是什麼?有什麼定義嗎?

TAG:操作系統 | 編程 | 計算機 | C編程語言 | 編譯原理 |