您好,登錄后才能下訂單哦!
這篇文章主要介紹“Linux常用的C語言開發工具是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Linux常用的C語言開發工具是什么”文章能幫助大家解決問題。
linux下的C語言開發(makefile編寫) 對于程序設計員來說,makefile是我們繞不過去的一個坎。可能對于習慣Visual C++的用戶來說,是否會編寫makefile無所謂。畢竟工具本身已經幫我們做好了全部的編譯流程。但是在Linux上面,一切變得不一樣了,沒有人會為你做這一切。編代碼要靠你,測試要靠你,最后自動化編譯設計也要靠你自己。想想看,如果你下載了一個開源軟件,卻因為自動化編譯失敗,那將會在很大程度上打擊你學習代碼的自信心了。所以,我的理解是這樣的。我們要學會編寫makefile,至少會編寫最簡單的makefile。
首先編寫add.c文件,
#include "test.h" #include int add(int a, int b) { return a + b; } int main() { printf(" 2 + 3 = %d\n", add(2, 3)); printf(" 2 - 3 = %d\n", sub(2, 3)); return 1; }
再編寫sub.c文件,
#include "test.h" int sub(int a, int b) { return a - b; }
最后編寫test.h文件,
#ifndef _TEST_H #define _TEST_H int add(int a, int b); int sub(int a, int b); #endif
那么,就是這三個簡單的文件,應該怎么編寫makefile呢?
test: add.o sub.o gcc -o test add.o sub.o add.o: add.c test.h gcc -c add.c sub.o: sub.c test.h gcc -c sub.c clean: rm -rf test rm -rf *.o
linux下的C語言開發(gdb調試) 編寫代碼過程中少不了調試。在windows下面,我們有visual studio工具。在linux下面呢,實際上除了gdb工具之外,你沒有別的選擇。那么,怎么用gdb進行調試呢?我們可以一步一步來試試看。
#include
既然需要調試,那么生成的可執行文件就需要包含調試的信息,這里應該怎么做呢?很簡單,輸入 gcc test.c -g -o test。輸入命令之后,如果沒有編譯和鏈接方面的錯誤,你就可以看到 可執行文件test了。
調試的步驟基本如下所示, (01) 首先,輸入gdb test (02) 進入到gdb的調試界面之后,輸入list,即可看到test.c源文件 (03) 設置斷點,輸入 b main (04) 啟動test程序,輸入run (05) 程序在main開始的地方設置了斷點,所以程序在printf處斷住 (06) 這時候,可以單步跟蹤。s單步可以進入到函數,而n單步則越過函數 (07) 如果希望從斷點處繼續運行程序,輸入c (08) 希望程序運行到函數結束,輸入finish (09) 查看斷點信息,輸入 info break (10) 如果希望查看堆棧信息,輸入bt (11) 希望查看內存,輸入 x/64xh + 內存地址 (12) 刪除斷點,則輸入delete break + 斷點序號 (13) 希望查看函數局部變量的數值,可以輸入print + 變量名 (14)希望修改內存值,直接輸入 print + *地址 = 數值 (15) 希望實時打印變量的數值,可以輸入display + 變量名 (16) 查看函數的匯編代碼,輸入 disassemble + 函數名 (17) 退出調試輸入quit即可
linux下的C語言開發(AT&T 匯編語言) 同樣是x86的cpu,但是卻可以用不同形式的匯編語言來表示。 在window上面我們使用的更多是intel格式的匯編語言,而在Linux系統上面使用的更多的常常是AT&T格式的匯編語言。那什么是AT&T格式的匯編代碼呢?我們可以寫一個試試看。
.data message: .string "hello!\n" length = . - message .text .global _start _start: movl $length, %edx movl $message, %ecx movl $1, %ebx movl $4, %eax int $0x80 movl $0, %ebx movl $1, %eax int $0x80 08048074 : .text .global _start _start: movl $length, %edx 8048074: ba 08 00 00 00 mov $0x8,%edx movl $message, %ecx 8048079: b9 9c 90 04 08 mov $0x804909c,%ecx movl $1, %ebx 804807e: bb 01 00 00 00 mov $0x1,%ebx movl $4, %eax 8048083: b8 04 00 00 00 mov $0x4,%eax int $0x80 8048088: cd 80 int $0x80 movl $0, %ebx 804808a: bb 00 00 00 00 mov $0x0,%ebx movl $1, %eax 804808f: b8 01 00 00 00 mov $0x1,%eax int $0x80 8048094: cd 80 int $0x80 ret 8048096: c3 ret
這是一個簡單的匯編文件,我們可以分兩步進行編譯。首先,輸入 as -gstabs -o hello.o hello.s, 接著輸入ld -o hello hello.o即可。為了驗證執行文件是否正確,可以輸入./hello驗證一下。 在as命令當中,由于我們使用了-gstabs選項,因此在hello執行文件中是包含調試信息的。所以,如果想單步調試的朋友可以輸入gdb hello進行調試。 那么,hello執行文件反匯編的代碼又是什么樣的呢?我們可以輸入objdump -S -d hello查看一下。
linux下的C語言開發(靜態庫) 在我們編寫軟件的過程當中,少不了需要使用別人的庫函數。因為大家知道,軟件是一個協作的工程。作為個人來講,你不可能一個人完成所有的工作。另外,網絡上一些優秀的開源庫已經被業內廣泛接受,我們也沒有必要把時間浪費在這些重復的工作上面。 既然說到了庫函數,那么一般來說庫函數分為兩種方式:靜態庫和動態庫。兩者的區別其實很小,靜態庫是必須要鏈接到執行文件中去的,而動態庫是不需要鏈接到最后的執行文件中的。怎么理解呢?也就是說,對于最后的執行文件而言,你是否刪除靜態庫無所謂。但是,一旦你刪除了動態庫,最后的執行文件就玩不轉了。 今天我們討論的問題是靜態庫。為了顯示windows和linux創建靜態庫之間的差別,我們首先在windows上面利用Visual C++6.0創建一個靜態庫。源文件的代碼很簡單,
#include "test.h" int add(int a, int b) { return a + b; }
頭文件代碼也不難,
#ifndef _TEST_H #define _TEST_H int add(int a, int b); #endif
如果你需要在windows上面創建一個靜態庫,那么你需要進行下面的操作, (1)打開visual C++ 6.0工具,單擊【File】-> 【New】->【Projects】 (2)選擇【Win32 Static Library】,同時在【Project Name】寫上項目名稱,在【Location】選擇項目保存地址 (3)單擊【Ok】,繼續單擊【Finish】,再單擊【Ok】,這樣一個靜態庫工程就創建好了 (4)重新單擊【File】->【New】->【Files】,選擇【C++ Source Files】, (5)選中【Add to pproject】,將源文件加入到剛才創建的工程中去,在File中輸入文件名+.c后綴 (6)重復4、5的操作,加入一個文件名+.h頭文件 (7)分別在頭文件和源文件中輸入上面的代碼,單擊F7按鈕,即可在Debug目錄中生成*.lib靜態庫文件
那么,在linux下面應該怎么運行呢?其實很簡單,兩條命令解決, (1)首先生成*.o文件,輸入gcc -c test.c -o test.o (2)利用ar命令生成靜態庫,輸入ar rc libtest.a test.o
此時如果還有一個hello.c文件使用到了這個靜態庫,比如說 ,
#include #include "test.h" int main() { printf("%d\n", add(2, 3)); return 1; }
其實也很簡單,輸入一個簡單的命令就可以生成執行文件了, (1)首先輸入gcc hello.c -o hello ./libtest.a (2)輸入./hello,驗證生成的執行文件是否正確 (3)朋友們可以刪除libtest.a文件,重新輸入./hello,驗證執行文件是否可以正常運行
linux下的C語言開發(動態庫) 動態鏈接庫不是linux獨有的特性,在windows下面也存在這樣的特性。一般來說,windows下面的動態連接庫是以.dll作為結尾的,而linux下面的動態連接庫是以.so結尾的。和靜態鏈接庫相比,動態連接庫可以共享內存資源,這樣可以減少內存消耗。另外,動態連接是需要經過操作系統加載器的幫助才能被普通執行文件發現的,所以動態連接庫可以減少鏈接的次數。有了這個特點,我們就不難發現為什么很多軟件的補丁其實都是以動態庫發布的。
那么,在Linux上動態庫是怎么生成的呢?
#include "test.h" int add(int a, int b) { return a + b; }
頭文件格式,
#ifndef _TEST_H #define _TEST_H int add(int a, int b); #endif
此時如果我們想要生成動態庫,要做的工作其實非常簡單,輸入gcc -shared -fPIC -o libtest.so test.c即可。回車后輸入ls,我們就可以發現當前目錄下面出現了libtest.so文件。
#include #include "test.h" int main() { printf("%d\n", add(2, 3)); return 1; }
在上面的代碼當中,我們發現使用到了add函數,那么此時如何才能生成一個執行文件呢?也很簡單,輸入gcc hello.c -o hello ./libtest.so。然后輸入./hello,此時可以驗證一下執行文件運行是否正確。在編寫靜態庫的時候,我說過靜態庫是匯編鏈接到執行文件當中的,而動態庫不會。朋友們可以做個小實驗,刪除libtest.so,然后輸入./hello。此時大家可以看看系統有沒有錯誤返回? 這個時候,有的朋友就會問了,那在windows下面dll應該怎么編寫呢?其實也不難,只要在test.h上面稍作改變即可。其他的步驟和靜態庫的操作是基本類似的。
#ifndef _TEST_H #define _TEST_H #ifdef USR_DLL #define DLL_API _declspec(dllexport) #else #define DLL_API _declspec(dllimport) #endif DLL_API int add(int a, int b); #endif
linux下的C語言開發(定時器) 定時器是我們需要經常處理的一種資源。那linux下面的定時器又是怎么一回事呢?其實,在linux里面有一種進程中信息傳遞的方法,那就是信號。這里的定時器就相當于系統每隔一段時間給進程發一個定時信號,我們所要做的就是定義一個信號處理函數。
#include #include #include #include #include static int count = 0; static struct itimerval oldtv; void set_timer() { struct itimerval itv; itv.it_interval.tv_sec = 1; itv.it_interval.tv_usec = 0; itv.it_value.tv_sec = 1; itv.it_value.tv_usec = 0; setitimer(ITIMER_REAL, &itv, &oldtv); } void signal_handler(int m) { count ++; printf("%d\n", count); } int main() { signal(SIGALRM, signal_handler); set_timer(); while(count linux下的C語言開發(自動編譯工具) 在Linux下面,編寫makefile是一件辛苦的事情。因此,為了減輕程序員編寫makefile的負擔,人們發明了autoconf和automake這兩個工具,可以很好地幫我們解決這個問題。 我們可以通過一個簡單的示例來說明如何使用配置工具。(1)首先,編寫源文件hello.c。 #include int main(int argc, char** argv[]) { printf("hello, world!\n"); return 1; }(2)接下來,我們需要創建一個Makefile.am,同時編寫上腳本。 SUBDIRS= bin_PROGRAMS=hello hello_SOURCES=hello.c(3)直接輸入autoscan,生成文件configure.scan,再改名為configure.in。修改腳本AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)為AC_INIT(hello, 1.0, feixiaoxing@163.com)同時,在AC_CONFIG_HEADER([config.h])后面添加AM_INIT_AUTOMAKE(hello, 0.1) (4)依次輸入aclocal命令、autoheader命令 (5)創建4個文件,分別為README、NEWS、AUTHORS和ChangeLog (6)依次輸入automake -a、autoconf命令 (7)輸入./configure,生成最終的Makefile (8)如果需要編譯,輸入make;如果需要安裝, 輸入make install;如果需要發布軟件包,輸入make distlinux下的C語言開發(進程創建) 在Linux下面,創建進程是一件十分有意思的事情。我們都知道,進程是操作系統下面享有資源的基本單位。那么,在Linux下面應該怎么創建進程呢?其實非常簡單,一個fork函數就可以搞定了。但是,我們需要清楚的是子進程與父進程之間除了代碼是共享的之外,堆棧數據和全局數據均是獨立的。 #include #include #include #include #include #include #include int main() { pid_t pid; if(-1 == (pid = fork())) { printf("Error happened in fork function!\n"); return 0; } if(0 == pid) { printf("This is child process: %d\n", getpid()); } else { printf("This is parent process: %d\n", getpid()); } return 0; }linux下的C語言開發(進程等待) 所謂進程等待,其實很簡單。前面我們說過可以用fork創建子進程,那么這里我們就可以使用wait函數讓父進程等待子進程運行結束后才開始運行。注意,為了證明父進程確實是等待子進程運行結束后才繼續運行的,我們使用了sleep函數。但是,在linux下面,sleep函數的參數是秒,而windows下面sleep的函數參數是毫秒。 #include #include #include int main(int argc, char* argv[]) { pid_t pid; pid = fork(); if(0 == pid) { printf("This is child process, %d\n", getpid()); sleep(5); } else { wait(NULL); printf("This is parent process, %d\n", getpid()); } return 1; }下面,我們需要做的就是兩步,首先輸入gcc fork.c -o fork, 然后輸入./fork,就會在console下面獲得這樣的結果。 [root@localhost fork]# ./fork This is child process, 2135 This is parent process, 2134linux下的C語言開發(信號處理) 信號處理是linux程序的一個特色。用信號處理來模擬操作系統的中斷功能,對于我們這些系統程序員來說是最好的一個選擇了。要想使用信號處理功能,你要做的就是填寫一個信號處理函數即可。一旦進程有待處理的信號處理,那么進程就會立即進行處理。 #include #include #include int value = 0; void func(int sig) { printf("I get a signal!\n"); value = 1; } int main() { signal(SIGINT, func); while(0 == value) sleep(1); return 0; }為了顯示linux對signal的處理流程,我們需要進行兩個步驟。 第一,輸入gcc sig.c -o sig, 然后輸入./sig即可; 第二則重啟一個console窗口,輸入ps -aux | grep sig, 在獲取sig的pid之后然后輸入kill -INT 2082, 我們即可得到如下的輸出。 [root@localhost fork]#./sig I get a signal! [root@localhost fork]#linux下的C語言開發(管道通信) Linux系統本身為進程間通信提供了很多的方式,比如說管道、共享內存、socket通信等。管道的使用十分簡單,在創建了匿名管道之后,我們只需要從一個管道發送數據,再從另外一個管道接受數據即可。 #include #include #include #include int pipe_default[2]; int main() { pid_t pid; char buffer[32]; memset(buffer, 0, 32); if(pipe(pipe_default) 0) { printf("Receive data from server, %s!\n", buffer); } close(pipe_default[0]); } else { close(pipe_default[0]); if(-1 != write(pipe_default[1], "hello", strlen("hello"))) { printf("Send data to client, hello!\n"); } close(pipe_default[1]); waitpid(pid, NULL, 0); } return 1; }下面我們就可以開始編譯運行了,老規矩分成兩步驟進行: (1)輸入gcc pipe.c -o pipe; (2)然后輸入./pipe,過一會兒你就可以看到下面的打印了。 [test@localhost pipe]$ ./pipe Send data to client, hello! Receive data from server, hello!linux下的C語言開發(多線程編程) 多線程和多進程還是有很多區別的。其中之一就是,多進程是linux內核本身所支持的,而多線程則需要相應的動態庫進行支持。對于進程而言,數據之間都是相互隔離的,而多線程則不同,不同的線程除了堆棧空間之外所有的數據都是共享的。說了這么多,我們還是自己編寫一個多線程程序看看結果究竟是怎么樣的。 #include #include #include #include void func_1(void* args) { while(1) { sleep(1); printf("this is func_1!\n"); } } void func_2(void* args) { while(1) { sleep(2); printf("this is func_2!\n"); } } int main() { pthread_t pid1, pid2; if(pthread_create(&pid1, NULL, func_1, NULL)) { return -1; } if(pthread_create(&pid2, NULL, func_2, NULL)) { return -1; } while(1) { sleep(3); } return 0; }和我們以前編寫的程序有所不同,多線程代碼需要這樣編譯,輸入gcc thread.c -o thread -lpthread,編譯之后你就可以看到thread可執行文件,輸入./thread即可。 [test@localhost Desktop]$ ./thread this is func_1! this is func_2! this is func_1! this is func_1! this is func_2! this is func_1! this is func_1! this is func_2! this is func_1! this is func_1!linux下的C語言開發(線程等待) 和多進程一樣,多線程也有自己的等待函數。這個等待函數就是pthread_join函數。那么這個函數有什么用呢?我們其實可以用它來等待線程運行結束。 #include #include #include #include void func(void* args) { sleep(2); printf("this is func!\n"); } int main() { pthread_t pid; if(pthread_create(&pid, NULL, func, NULL)) { return -1; } pthread_join(pid, NULL); printf("this is end of main!\n"); return 0; }編寫wait.c文件結束之后,我們就可以開始編譯了。首先你需要輸入gcc wait.c -o wait -lpthread,編譯之后你就可以看到wait可執行文件,輸入./wait即可。 [test@localhost thread]$ ./thread this is func! this is end of main!linux下的C語言開發(線程互斥) 對于編寫多線程的朋友來說,線程互斥是少不了的。在linux下面,編寫多線程常用的工具其實是pthread_mutex_t。本質上來說,它和Windows下面的mutex其實是一樣的,差別幾乎是沒有。希望對線程互斥進行詳細了解的朋友可以看這里。 #include #include #include #include static int value = 0; pthread_mutex_t mutex; void func(void* args) { while(1) { pthread_mutex_lock(&mutex); sleep(1); value ++; printf("value = %d!\n", value); pthread_mutex_unlock(&mutex); } } int main() { pthread_t pid1, pid2; pthread_mutex_init(&mutex, NULL); if(pthread_create(&pid1, NULL, func, NULL)) { return -1; } if(pthread_create(&pid2, NULL, func, NULL)) { return -1; } while(1) sleep(0); return 0; }編寫mutex.c文件結束之后,我們就可以開始編譯了。首先你需要輸入gcc mutex.c -o mutex -lpthread,編譯之后你就可以看到mutex可執行文件,輸入./mutex即可。 [test@localhost thread]$ ./mutex value = 1! value = 2! value = 3! value = 4! value = 5! value = 6!
關于“Linux常用的C語言開發工具是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。