日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux vim配置c,Linux入门学习教程:GNU C及将Vim打造成C/C++的半自动化IDE

發(fā)布時(shí)間:2024/7/5 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux vim配置c,Linux入门学习教程:GNU C及将Vim打造成C/C++的半自动化IDE 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

Linux系統(tǒng)中普遍使用的是GNU-C,這里有一份Gnu-C語言手冊.pdf,下載地址:。

------------------------------------------分割線------------------------------------------

具體下載目錄在 /2015年資料/3月/2日/Linux入門學(xué)習(xí)教程:GNU C及將Vim打造成C&C++的半自動(dòng)化IDE/

------------------------------------------分割線------------------------------------------

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

感悟一:C語言標(biāo)準(zhǔn)干不過GNU擴(kuò)展

最近為了研究X Window的底層協(xié)議,開始嘗試使用XCB編程。當(dāng)我打開XCB的頭文件的時(shí)候,我被大量的__restrict__關(guān)鍵字驚呆了,好在有GNU C語言手冊為我答疑解惑。__restrict__又是一個(gè)GNU擴(kuò)展的關(guān)鍵字,后面我會(huì)詳細(xì)講解該關(guān)鍵字的用途。其實(shí)C語言的C99標(biāo)準(zhǔn)中已經(jīng)引入了restrict關(guān)鍵字,沒有前后的下劃線,但是在大量的開源代碼中,使用最普遍的還是GNU的擴(kuò)展,而不是C語言標(biāo)準(zhǔn)。

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

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

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

有了__restrict__,C語言的該問題將不復(fù)存在。用__restrict__修飾一個(gè)指針后,①該指針只能在定義的時(shí)候被初始化;②不會(huì)再有別的指針指向該指針指向的內(nèi)存,因此編譯器可以對算法進(jìn)行優(yōu)化。如下代碼:

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

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

int arr[100];int*pArr;

pArr= arr;

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

比如我們定義一個(gè)函數(shù)對兩塊數(shù)據(jù)進(jìn)行操作,結(jié)果放入第3塊內(nèi)存,如下:

void func1(void* p1, void* p2, void* p3, intsize){for(int i=0; i

p3[i]= p1[i] +p2[i];

}

}

很顯然,由于編譯器沒辦法判斷指針p1、p2、p3指向的內(nèi)存是否重疊,所以無法進(jìn)行優(yōu)化,加上__restrict__關(guān)鍵字后,如下:

void func1(void* __restrict__ p1, void* __restrict__ p2, void* __restrict__ p3, intsize){for(int i=0; i

p3[i]= p1[i] +p2[i];

}

}

相當(dāng)于明確告訴編譯器這幾塊內(nèi)存不會(huì)重疊,所以編譯器就可以放心大膽對程序進(jìn)行優(yōu)化。

另一個(gè)關(guān)鍵字是_Complex,C99才引入,而且需要包含頭文件。其實(shí)在GNU C中,早就有__complex__、__real__、__imag__等擴(kuò)展關(guān)鍵字。如下代碼:

1 #include

2 #include

3

4 intmain(){5 __complex__ a = 3 +4i;6 __complex__ b = 5 +6i;7 __complex__ c = a +b;8 __complex__ d = a *b;9 __complex__ e = a /b;10 printf("a + b = %f + %fi\n", __real__ c, __imag__ c);11 printf("a * b = %f + %fi\n", __real__ d, __imag__ d);12 printf("a / b = %f + %fi\n", __real__ e, __imag__ e);13 return 0;14 }

可以看到,在C語言中也可以直接對復(fù)數(shù)進(jìn)行計(jì)算。數(shù)值計(jì)算再也不是Fortran的專利。

感悟二:指針和數(shù)組還真是不一樣

從學(xué)C語言開始,老師就教導(dǎo)我們說指針和數(shù)組是一樣的,它們可以用同樣的方式進(jìn)行操作。而事實(shí)上,指針和數(shù)組還是有差別的。直到多年后讀《C專家編程》,才直到所謂指針和數(shù)組一樣是一個(gè)美麗的錯(cuò)誤,只是因?yàn)樵凇禩he C Programming Language》這本書里,把“作為函數(shù)參數(shù)時(shí),指針和數(shù)組一樣”這樣一句話前后分開分別印到了兩頁而已。

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

1 #include

2 #include

3

4 intmain(){5 int* p = (int*)malloc(100*sizeof(int));6 int arr[100] = {0};7 printf("The size of p: %d\n", sizeof(p));8 printf("The size of arr: %d\n", sizeof(arr));9 return 0;10 }

這段代碼的運(yùn)行結(jié)果為:

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

我們經(jīng)??梢允褂萌缦碌拇a片段來獲得一個(gè)數(shù)組中有多少個(gè)元素,如下:

int arr[100];

size_t length= sizeof(arr)/sizeof(int);

但是,當(dāng)使用數(shù)組作為函數(shù)的參數(shù)的時(shí)候,數(shù)組會(huì)退化成指針。如下代碼:

1 #include

2 #include

3

4 void test_array(intarr[]){5 printf("The size of arr in function: %d\n", sizeof(arr));6 return;7 }8

9 intmain(){10 int arr[100] = {0};11 printf("The size of arr in main: %d\n", sizeof(arr));12 test_array(arr);13 return 0;14 }

這段代碼的運(yùn)行結(jié)果為:

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

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

在GNU C中可以定義不完全類型,不完全類型主要有兩種,一種是空的結(jié)構(gòu),一種是空的數(shù)組,比如:

structpoint;char name[0];

空的結(jié)構(gòu)不能定義變量,只能使用空結(jié)構(gòu)的指針??战Y(jié)構(gòu)可以在后面再將它補(bǔ)充完整,如下:

structpoint{intx,y;

};

空結(jié)構(gòu)在定義鏈表的時(shí)候經(jīng)常用到,如下:

structlinked_list{struct linked_list*next;intx;/*other elements here perhaps*/}struct linked_list* head;

還有一種不完全類型就是將一個(gè)結(jié)構(gòu)的最后一項(xiàng)定義為一個(gè)空的數(shù)組,這樣可以用來表示一個(gè)可變長度的結(jié)構(gòu)或數(shù)組,演示該技術(shù)的代碼如下:

1 #include

2 #include

3

4 typedef struct{5 intlength;6 int arr[0];7 } incomplete_type;8

9 intmain(){10 char hello[] = "Hello, world!";11 int length = sizeof(hello) / sizeof(char);12 incomplete_type* p = (incomplete_type*)malloc(sizeof(int) + length*sizeof(char));13 p->length =length;14 for(int i=0; ilength; i++){15 p->arr[i] =hello[i];16 }17 printf("p->length=%d\n", p->length);18 printf("p->arr=%s\n", p->arr);19 }

打造C/C++的IDE

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

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

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

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

第二,生成tags數(shù)據(jù)庫,并將其加入到Vim中。

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

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

然后,在使用Vim寫C程序的時(shí)候,如果輸入了.、->這樣的元素,則其成員會(huì)自動(dòng)補(bǔ)全。如果輸入的是一個(gè)字符串(比如函數(shù)名),可以按Ctrl-X Ctrl-O調(diào)用自動(dòng)補(bǔ)全,如下圖:

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

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

相比網(wǎng)上其它的將Vim打造成IDE的文章,我的配置比較簡單,基本上只安裝了幾個(gè)插件,而沒有做過多的設(shè)置。當(dāng)我需要某個(gè)功能的時(shí)候,我會(huì)使用命令顯式地調(diào)用它,所以,稱它為半自動(dòng)化IDE吧。

--------------------------------------分割線 --------------------------------------

--------------------------------------分割線 --------------------------------------

總結(jié)

以上是生活随笔為你收集整理的linux vim配置c,Linux入门学习教程:GNU C及将Vim打造成C/C++的半自动化IDE的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。