亚洲综合原千岁中文字幕_国产精品99久久久久久久vr_无码人妻aⅴ一区二区三区浪潮_成人h动漫精品一区二区三

主頁 > 知識庫 > Linux折騰記(六):感悟GNU C及把Vim打造成C/C++的半自動化IDE

Linux折騰記(六):感悟GNU C及把Vim打造成C/C++的半自動化IDE

熱門標簽:優邁系統外呼顯示亂層 布谷電銷機器人價格 岑溪電銷機器人 大連企業電銷機器人線路 義烏市400電話辦理 怎么查看地圖標注的地點 上海電銷卡外呼系統供應商 電銷機器人錄音用什么軟件 營銷智能外呼系統口碑推薦

C語言在Linux系統中的重要性自然是無與倫比、不可替代,所以我寫Linux江湖系列不可能不提C語言。C語言是我的啟蒙語言,感謝C語言帶領我進入了程序世界。雖然現在不靠它吃飯,但是仍免不了經常和它打交道,特別是在Linux系統下。

  Linux系統中普遍使用的是GNU-C,這里有一份Gnu-C語言手冊.pdf。The GNU C Reference Manual的主頁在這里:http://www.gnu.org/software/gnu-c-manual/。C語言的內核極其緊湊,該手冊總共只有91頁,去掉目錄、附錄和索引后就只有70頁。我一般一個多小時就可以將其從頭至尾復習一遍。我曾有過將其翻譯成中文的想法,后來還是放棄了。翻譯這種字斟句酌的事情還是讓別人來干吧。我只寫寫我自己的感悟。

感悟一:C語言標準干不過GNU擴展

   最近為了研究X Window的底層協議,開始嘗試使用XCB編程。當我打開XCB的頭文件的時候,我被大量的__restrict__關鍵字驚呆了,好在有GNU C語言手冊為我答疑解惑。__restrict__又是一個GNU擴展的關鍵字,后面我會詳細講解該關鍵字的用途。其實C語言的C99標準中已經引入了restrict關鍵字,沒有前后的下劃線,但是在大量的開源代碼中,使用最普遍的還是GNU的擴展,而不是C語言標準。

  和restrict關鍵字有相同命運的還有inline、_Complex等,它們都是在C99標準中引入的關鍵字,但是其實在C99標準出來之前,GNU C中早就有了__inline__、__complex__等擴展關鍵字。還記得多年前我學習Linux 0.11版的源代碼時,看到大量的__inline__曾經疑惑不已,不知道為什么Linus在91年就能用上了如此先進的語言功能,后來才知道,這是GNU的擴展關鍵字。

  C語言的標準有C89和C99,使用GCC的時候甚至要顯示指定-std=c99才能全面支持C99標準,所以在開源界,大家還是喜歡首選GNU的擴展關鍵字。比如__inline__、__complex__和__restrict__??偠灾?,C語言標準干不過GNU擴展。

  下面來看看__restrict__的真正含義。還記得CSDN上曾經載過一篇文章《為什么有些語言會比別的快》,其中提到“很長一段時間,相同的兩個程序在Fortran和C(或者C++)中運行,Fortran會快一些,因為Fortran的優化做的更好。這是真的,就算C語言和Fortran的編譯器用了相同的代碼生成器也是一樣。這個不同不是因為Fortran的某種特性,事實上恰恰相反,是因為Fortran不具備的特性。”這是因為C語言中的指針給編譯器的優化帶來了困難,文章中繼續說道:“問題就來了。這些指針可以代替任何內存地址。更重要的是,他們可以重疊。輸出數組的內存地址也可以同時是輸入數組的。甚至可以部分重疊,輸出數組可以覆蓋一個輸入數組的一半。這對編譯器優化來說是個大問題,因為之前基于數組的優化不再適用。特別的,添加元素的順序也成問題,如果輸出重疊的數組,計算的結果會變得不確定,取決于輸出元素的動作是發生在元素被覆蓋之前還是之后。”

  有了__restrict__,C語言的該問題將不復存在。用__restrict__修飾一個指針后,①該指針只能在定義的時候被初始化;②不會再有別的指針指向該指針指向的內存,因此編譯器可以對算法進行優化。如下代碼:

復制代碼
代碼如下:

int * __restrict__ p = (int*)malloc(100*sizeof(int));

指針p有__restrict__關鍵字修飾,所以它只能在定義的時候被初始化,以后不能賦值,而沒有__restrict__修飾的指針,可以隨時賦值,如下:

復制代碼
代碼如下:

int arr[100];
int* pArr;
pArr = arr;

指針pArr沒有被__restrict__關鍵字修飾,所以可以將數組的首地址賦值給它。

比如我們定義一個函數對兩塊數據進行操作,結果放入第3塊內存,如下:

復制代碼
代碼如下:

void func1(void* p1, void* p2, void* p3, int size){
for(int i=0; isize; i++){
p3[i] = p1[i] + p2[i];
}
}

很顯然,由于編譯器沒辦法判斷指針p1、p2、p3指向的內存是否重疊,所以無法進行優化,加上__restrict__關鍵字后,如下:

復制代碼
代碼如下:

void func1(void* __restrict__ p1, void* __restrict__ p2, void* __restrict__ p3, int size){
for(int i=0; isize; i++){
p3[i] = p1[i] + p2[i];
}
}

相當于明確告訴編譯器這幾塊內存不會重疊,所以編譯器就可以放心大膽對程序進行優化。

   另一個關鍵字是_Complex,C99才引入,而且需要包含complex.h>頭文件。其實在GNU C中,早就有__complex__、__real__、__imag__等擴展關鍵字。如下代碼:
 

復制代碼
代碼如下:

#include stdlib.h>
#include stdio.h>/p> p>int main(){
__complex__ a = 3 + 4i;
__complex__ b = 5 + 6i;
__complex__ c = a + b;
__complex__ d = a * b;
__complex__ e = a / b;
printf("a + b = %f + %fi\n", __real__ c, __imag__ c);
printf("a * b = %f + %fi\n", __real__ d, __imag__ d);
printf("a / b = %f + %fi\n", __real__ e, __imag__ e);
return 0;
}

  可以看到,在C語言中也可以直接對復數進行計算。數值計算再也不是Fortran的專利。

 感悟二:指針和數組還真是不一樣

  從學C語言開始,老師就教導我們說指針和數組是一樣的,它們可以用同樣的方式進行操作。而事實上,指針和數組還是有差別的。直到多年后讀《C專家編程》,才直到所謂指針和數組一樣是一個美麗的錯誤,只是因為在《The C Programming Language》這本書里,把“作為函數參數時,指針和數組一樣”這樣一句話前后分開分別印到了兩頁而已。

  比如,指針不保存數據的長度信息,而數組有,如下代碼:

復制代碼
代碼如下:

#include stdlib.h>
#include stdio.h>/p> p>int main(){
int* p = (int*)malloc(100*sizeof(int));
int arr[100] = {0};
printf("The size of p: %d\n", sizeof(p));
printf("The size of arr: %d\n", sizeof(arr));
return 0;
}

這段代碼的運行結果為:

復制代碼
代碼如下:

The size of p: 8
The size of arr: 400

  我們經??梢允褂萌缦碌拇a片段來獲得一個數組中有多少個元素,如下:

復制代碼
代碼如下:

int arr[100];
size_t length = sizeof(arr)/sizeof(int);

  但是,當使用數組作為函數的參數的時候,數組會退化成指針。如下代碼:

復制代碼
代碼如下:

#include stdlib.h>
#include stdio.h>/p> p>void test_array(int arr[]){
printf("The size of arr in function: %d\n", sizeof(arr));
return;
}/p> p>int main(){
int arr[100] = {0};
printf("The size of arr in main: %d\n", sizeof(arr));
test_array(arr);
return 0;
}

這段代碼的運行結果為:

復制代碼
代碼如下:

The size of arr in main: 400
The size of arr in function: 8

感悟三:C語言中的不完全類型(Incomplete Types)

   在GNU C中可以定義不完全類型,不完全類型主要有兩種,一種是空的結構,一種是空的數組,比如:

復制代碼
代碼如下:

struct point;
char name[0];

空的結構不能定義變量,只能使用空結構的指針??战Y構可以在后面再將它補充完整,如下:

復制代碼
代碼如下:

struct point{
int x,y;
};

空結構在定義鏈表的時候經常用到,如下:

復制代碼
代碼如下:

struct linked_list{
struct linked_list* next;
int x;
/*other elements here perhaps */
}
struct linked_list* head;

  還有一種不完全類型就是將一個結構的最后一項定義為一個空的數組,這樣可以用來表示一個可變長度的結構或數組,演示該技術的代碼如下:


復制代碼
代碼如下:

#include stdlib.h>
#include stdio.h>/p> p>typedef struct {
int length;
int arr[0];
} incomplete_type;/p> p>int main(){
char hello[] = "Hello, world!";
int length = sizeof(hello) / sizeof(char);
incomplete_type* p = (incomplete_type*)malloc(sizeof(int) + length*sizeof(char));
p->length = length;
for(int i=0; ip->length; i++){
p->arr[i] = hello[i];
}
printf("p->length=%d\n", p->length);
printf("p->arr=%s\n", p->arr);
}

打造C/C++的IDE

  后面的內容展示如何將Vim打造成一個半自動的C/C++ IDE。讀過我的Java博客的朋友應該知道,其實我更喜歡用Eclipse。只有在需要寫非常簡單的程序(比如做習題)的情況下,我才會用Vim。這在我的《打造屬于自己的Vim》中有論述。在這篇文章中我展示了怎么使用Vundle管理插件以及怎么怎么閱讀幫助文檔,同時展示了taglist.vim的簡單用法。如果要用Vim來寫C/C++程序,還需要做少許擴展。

  第一,安裝以下幾個插件,由于使用Vundle管理插件,所以只需要把插件名寫入.vimrc配置文件,然后運行:BundleInstall即可,如下圖:

分別介紹一下這幾個插件。The-NERD-tree是一個瀏覽目錄和文件的插件,可以使用:help NERD_tree.txt查看它的幫助文檔。taglist.vim是瀏覽符號以及在符號之間跳轉的插件,使用:help taglist.txt查看它的幫助文檔。a.vim是在源代碼文件和頭文件之間跳轉的插件,不需要幫助文檔,它的命令就是:A。c.vim是提供IDE功能的主要插件,它提供的功能有自動注釋、反注釋、自動插入代碼塊及自動運行,如果安裝了splint,還可以對代碼進行靜態檢查,使用:help csupport.txt查看它的文檔。OmniCppComplete是一個提供自動補全功能的插件,使用:help omnicppcomplete.txt查看它的文檔。

  這些插件中,taglist.vim和OmniCppComplete需要ctags軟件的支持,所以需要安裝exuberant-ctags軟件包,在Fedora 20中,只需要使用yum install ctags即可自動安裝。

  第二,生成tags數據庫,并將其加入到Vim中。

  我們寫C程序的時候,使用到的文件主要存在于兩個地方,一個是我們工作的當前目錄,另外一個是/usr/include。所以要到/usr/include目錄下使用ctags命令生成tags數據庫文件。為了使tags數據庫中包含盡可能多的信息(結構、枚舉、類、函數、宏定義等等),需要指定ctags的參數,如下:

 然后將該tags文件的路徑加入到.vimrc配置文件中,同時設置一個鍵盤映射,使得按Ctrl+F12時,在工作目錄中調用ctags命令。如下配置文件的最后兩行:

  然后,在使用Vim寫C程序的時候,如果輸入了.、->這樣的元素,則其成員會自動補全。如果輸入的是一個字符串(比如函數名),可以按Ctrl-X Ctrl-O調用自動補全,如下圖:

不僅會彈出候選窗口,而且在最上面的窗口中會顯示函數的完整的簽名,及其所在的文件。這對于我們經常記不全函數名、記不清函數簽名的人來說,已經是莫大的福音了。

  taglist.vim和OmniCppComplete插件提供的功能用起來都只需要一個命令,而c.vim提供的命令就比較多了。而且在c.vim的幫助文檔中并沒有列出所有功能的命令,有一個辦法可以學習這些命令,那就是打開GVim,通過GVim菜單中的C/C++菜單來學習c.vim提供的功能和命令。

  相比網上其它的將Vim打造成IDE的文章,我的配置比較簡單,基本上只安裝了幾個插件,而沒有做過多的設置。當我需要某個功能的時候,我會使用命令顯式地調用它,所以,稱它為半自動化IDE吧。

 

標簽:楚雄 荊州 迪慶 遼陽 淄博 來賓 忻州 阜陽

巨人網絡通訊聲明:本文標題《Linux折騰記(六):感悟GNU C及把Vim打造成C/C++的半自動化IDE》,本文關鍵詞  Linux,折騰,記,六,感悟,GNU,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Linux折騰記(六):感悟GNU C及把Vim打造成C/C++的半自動化IDE》相關的同類信息!
  • 本頁收集關于Linux折騰記(六):感悟GNU C及把Vim打造成C/C++的半自動化IDE的相關信息資訊供網民參考!
  • 推薦文章
    深夜做爰性大片中文| 亚欧乱色一区二区三区| 天天色成人| 二级特黄绝大片免费视频大片| 色综合久久天天综合观看| 天天色色色| 免费国产在线观看不卡| 久久国产一久久高清| 日韩一级黄色大片| 日韩在线观看免费完整版视频| 超级乱淫黄漫画免费| 国产伦久视频免费观看 视频| 韩国毛片基地| 香蕉视频三级| 精品久久久久久免费影院| 九九精品在线| 精品久久久久久中文| 99久久网站| 欧美另类videosbestsex视频| 国产成人精品综合久久久| 久久精品店| 久久精品成人一区二区三区| 精品国产一区二区三区免费 | 国产高清在线精品一区a| 国产激情一区二区三区| 国产亚洲精品aaa大片| 久久99欧美| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 91麻豆精品国产高清在线| 国产不卡在线观看| 亚洲女人国产香蕉久久精品| 欧美激情一区二区三区在线 | 亚欧成人毛片一区二区三区四区 | 国产成人欧美一区二区三区的| 国产视频一区在线| 成人影院久久久久久影院| 夜夜操网| 亚洲 男人 天堂| 韩国妈妈的朋友在线播放 | 精品国产香蕉在线播出| 精品视频在线观看一区二区| 精品国产亚洲人成在线| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 午夜激情视频在线观看| 天堂网中文在线| 欧美夜夜骑 青草视频在线观看完整版 久久精品99无色码中文字幕 欧美日韩一区二区在线观看视频 欧美中文字幕在线视频 www.99精品 香蕉视频久久 | 国产一区精品| 亚洲 国产精品 日韩| 午夜激情视频在线观看| 国产一区精品| 日日夜人人澡人人澡人人看免| 色综合久久天天综线观看| 韩国三级视频在线观看| 久久精品店| 精品国产一区二区三区久久久蜜臀| 久久精品道一区二区三区| 成人免费高清视频| 精品久久久久久中文字幕2017| 欧美国产日韩在线| 国产国语在线播放视频| 精品国产亚洲一区二区三区| 久久久久久久免费视频| 可以免费在线看黄的网站| 国产成人欧美一区二区三区的| 亚洲精品中文一区不卡| 一本高清在线| 一本高清在线| 欧美日本韩国| 天天做日日干| 国产一区二区精品尤物| 91麻豆精品国产自产在线| 美女免费毛片| 亚洲天堂在线播放| 欧美激情一区二区三区中文字幕| 欧美日本韩国| 韩国妈妈的朋友在线播放 | 亚洲第一页乱| 午夜激情视频在线观看| 国产麻豆精品| 美国一区二区三区| 国产一区二区精品久久91| 韩国三级一区| 日本免费看视频| 国产一区国产二区国产三区| 精品视频在线观看一区二区| 亚欧乱色一区二区三区| 免费一级片在线| 国产一级生活片| 99色播| 好男人天堂网 久久精品国产这里是免费 国产精品成人一区二区 男人天堂网2021 男人的天堂在线观看 丁香六月综合激情 | 青草国产在线| 日韩一级黄色| 深夜做爰性大片中文| 韩国三级视频在线观看| 久久99中文字幕| 精品国产三级a| 亚洲精品影院| 尤物视频网站在线观看| 99久久精品国产高清一区二区| 亚欧乱色一区二区三区| 日韩在线观看视频网站| 成人高清护士在线播放| 久久久久久久久综合影视网| 人人干人人草| 久久国产精品自线拍免费| 国产网站免费| 精品国产亚洲一区二区三区| 久久久成人影院| 超级乱淫黄漫画免费| 青青久久网| 欧美日本免费| 999久久狠狠免费精品| 99久久视频| 久久久成人网| 欧美1区| 日本特黄特色aaa大片免费| 91麻豆tv| 成人影视在线播放| 99色视频| 毛片电影网| 久久福利影视| 国产91素人搭讪系列天堂| 韩国毛片免费大片| 午夜欧美成人香蕉剧场| 91麻豆精品国产自产在线观看一区| 日韩在线观看免费完整版视频| 成人免费观看的视频黄页| 香蕉视频久久| 免费毛片基地| a级黄色毛片免费播放视频| 久久国产精品永久免费网站| 91麻豆精品国产自产在线| 91麻豆国产级在线| 日韩中文字幕在线亚洲一区 | 久久久久久久男人的天堂| 日韩免费在线观看视频| 亚洲爆爽| 国产成人欧美一区二区三区的| 亚飞与亚基在线观看| 精品久久久久久免费影院| 可以在线看黄的网站| 日韩中文字幕在线播放| 99色视频| 精品视频一区二区三区| 成人影院久久久久久影院| 国产精品1024在线永久免费| 亚洲天堂免费| 美女免费黄网站| 亚欧成人毛片一区二区三区四区 | 成人影院久久久久久影院| 韩国毛片免费大片| 日本特黄一级| 国产福利免费视频| 国产精品自拍在线| 日韩中文字幕一区二区不卡| 国产91丝袜高跟系列| 四虎论坛| 国产一区国产二区国产三区| 免费一级片在线观看| 韩国三级视频网站| 成人a级高清视频在线观看| 国产成人欧美一区二区三区的| 亚飞与亚基在线观看| 日日夜夜婷婷| 亚洲 欧美 成人日韩| 久久99这里只有精品国产| 国产a视频| 精品国产亚一区二区三区| 国产高清在线精品一区二区| 成人免费网站视频ww| 欧美激情一区二区三区视频| 久久99这里只有精品国产| 成人高清视频在线观看| 国产不卡福利| 一 级 黄 中国色 片| 国产不卡福利| 国产成人啪精品| 日韩男人天堂| 国产不卡在线看| 日本久久久久久久 97久久精品一区二区三区 狠狠色噜噜狠狠狠狠97 日日干综合 五月天婷婷在线观看高清 九色福利视频 | 999久久狠狠免费精品| 日韩中文字幕一区| 91麻豆精品国产片在线观看| 青青久久国产成人免费网站| 日本免费乱人伦在线观看| 久久国产一区二区| 成人影视在线观看| 高清一级毛片一本到免费观看| 久草免费在线视频| 韩国毛片免费大片| 99色播| 久久久久久久久综合影视网| 日韩男人天堂| 麻豆午夜视频| 欧美a级片免费看| 日韩专区亚洲综合久久| 天堂网中文字幕| 精品久久久久久中文| 亚洲天堂免费观看| 黄视频网站免费|