歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> linux下c++編程環境搭建,運行過程以及調試,內含C++頭文件源文件編譯過程鏈接

linux下c++編程環境搭建,運行過程以及調試,內含C++頭文件源文件編譯過程鏈接

日期:2017/3/3 13:40:36   编辑:Linux技術


安裝g++環境

安裝兩個RPM包即可搞定
[root@localhost Desktop]# rpm -ivh /home/weiwei/Desktop/libstdc++-devel-4.4.5-6.el6.i686.rpm 
[root@localhost Desktop]# rpm -ivh /home/weiwei/Desktop/gcc-c++-4.4.5-6.el6.i686.rpm

查看g++是否安裝成功
[root@localhost Desktop]# g++ -v
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.5 20110214 (Red Hat 4.4.5-6) (GCC)

gcc與g++的區別
gcc可以用來編譯C或者C++,但他只能編譯c++源文件,不能自動和C++程序使用的庫連接,g++可以實現C++程序的編譯和鏈接,其實他也是調用gcc來編譯的,要編譯c++代碼生成可執行文件要用 g++
編寫一個簡單的c++程序
// myfirst.cpp--displays a message

#include <iostream>      // make definitions visible
using namespace std;                      
int main()                                    // function header
{                                             // start of function body
    cout << "Come up and C++ me some time.";  // message
    cout << endl;                             // start a new line
    cout << "You won't regret it!" << endl;   // more output
    return 10;                                 // terminate main() 返回值為0代表成功,非0返回值的含義由系統自定義
}                                             // end of function body

打開命令窗口進行編譯
[root@localhost Desktop]# g++ -o test1 test.cpp

-o test1 test.cpp 從test.cpp編譯生成test1文件,test1為可執行文件,沒有後綴
如果不寫-o test1 會默認生成一個a.out可執行文件



執行可執行文件
[root@localhost Desktop]# ./a.out
Come up and C++ me some time.
You won't regret it!

獲取main函數返回值
[root@localhost Desktop]# echo $?
10


c/c++運行流程分解


預處理階段

對c源文件預處理生成中間文件e.i
[root@localhost c]# g++ -E funcuse.c -o e.i


編譯階段

對預處理文件進行處理生成匯編語言文件e.s
[root@localhost c]# g++ -S e.i -o e.s

上述兩部可以直接合並為
[root@localhost c]# g++ -s e.i -o e.s


匯編階段

生成目標文件,目標文件是機器代碼,但不能執行,必須將目標文件與其他目標文件或庫文件連接生成可執行的二進制文件才能執行
[root@localhost c]# g++ -c e.s -o e.o


生成執行文件

[root@localhost c]# g++ e.o -o result


運行result

[root@localhost c]# ./result

在linux操作系統中運行程序必須指定程序所在的目錄,除非程序的目錄已經列在PATH環境變量中,所以程序前必須加./
注:echo $? 顯示main函數的返回值(int型)
如果想讓編譯和運行同時進行可以采用如下命令:
gcc funcuse.c -o result && ./result
&&表示如果成功就。。。如果編譯成功,會直接運行程序
可以將上述所有步驟合並寫為
g++ funcuse.c -o result


g++  -o result funcuse.c

直接生成可執行文件


頭文件與源文件

程序如果復雜的話,程序的各個部分會分別存儲在不同的文件中,按照邏輯進行劃分。
來自:/content/3514841.html
頭文件的作用就是被其他的.cpp包含,本身並不參與編譯,但實際上它們的內容卻在多個.cpp文件中得到了 編譯.
頭文件中應該只放變量和函數的聲明,而不能放它們的定義
這個規則是有三個例外的
頭文件中可以寫const對象的定義
頭文件中可 以寫內聯函數(inline)的定義
頭文件中可以寫類 (class)的定義


分離式編譯

如果將程序分成若干子程序,怎樣在linux下進行編譯呢?
下面以求圓的面積為例來說明
Circle.h
#ifndef CIRCLE_H

#define CIRCLE_H

class Circle

{

    private:

        double r;

    public:

        Circle();

        Circle(double R);

        double Area();

};

#endif

Circle.cpp
#include "Circle.h"

#include <iostream>

using namespace std;

Circle::Circle()
{
    this->r=5.0;
}

Circle::Circle(double R)
{
    this->r=R;
}

double Circle:: Area()
{
    return 3.14*r*r;
}

main.cpp
#include "Circle.h"
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
   Circle c(3);
   cout<<"Area="<<c.Area()<<endl;

   return 0;
}

編譯
[root@localhost cpp]# g++ -c Circle.cpp -o Circle.o
[root@localhost cpp]# g++ -c main.cpp -o main.o
[root@localhost cpp]# g++ main.o Circle.o -o main
[root@localhost cpp]# ./main
Area=28.26

-c命令表示編譯,頭文件不許顯式編譯,但實際已經編譯。如果只修改了一個源文件,只需要編譯改動的文件


makefile

但如果我們的程序有幾百個源程序的時候,怎麼辦?難道也要編譯器重新一個一個的編譯?
makefile關系到了整個工程的編譯規則。一個工程中的源文件不計數,其按類型、功能、模塊分別放在若干個目錄中,makefile定義了一系列的規則來指定,哪些文件需要先編譯,哪些文件需要後編譯,哪些文件需要重新編譯,甚至於進行更復雜的功能操作,因為makefile就像一個Shell腳本一樣,其中也可以執行操作系統的命令。
makefile帶來的好處就是——“自動化編譯”,一旦寫好,只需要一個make命令,整個工程完全自動編譯,極大的提高了軟件開發的效率
#此行為注釋
main: main.o Circle.o
	g++ main.o Circle.o -o main
Circle.o:Circle.cpp
	g++ -c Circle.cpp -o Circle.o
main.o:main.cpp
	g++ -c main.cpp -o main.o

注意:g++命令開頭的行前面必須有tab空格,不然會報錯: *** missing separator. Stop
如果將名字命名為Makefile或makefile,只需要在命令行下敲入make就可以進行自動化編譯
[root@localhost cpp]# make
g++ -c main.cpp -o main.o
g++ -c Circle.cpp -o Circle.o
g++ main.o Circle.o -o main
[root@localhost cpp]# ./main
Area=28.26

參考:
http://blog.163.com/dong_box/blog/static/2625977820103310933870/
[精華] 跟我一起寫 Makefile - ChinaUnix.net
編寫Makefile - 學習,思考,記錄,分享。 - 博客頻道 - CSDN.NET


GDB調試

啟動gdb
[root@localhost c]# gdb
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-48.el6)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.

調試前要先進性編譯連接
[root@localhost c]# g++ -g funcuse.c -o dbug

進行調試
[root@localhost c]# gdb dbug
Reading symbols from /home/weiwei/Desktop/c/dbug...done.

列出代碼
(gdb) list
1	#include<stdio.h>
2	
3	int main(){
4		for(int i=0 ; i<5; i++){
5			printf("this is %d\n",i);
6		}
7		return 0;
8	}

(gdb) list 3,5
3	int main(){
4		for(int i=0 ; i<5; i++){
5			printf("this is %d\n",i);

執行程序
(gdb) run
Starting program: /home/weiwei/Desktop/c/dbug 
this is 0
this is 1
this is 2
this is 3
this is 4

設置斷點
(gdb) break 5
Breakpoint 1 at 0x8048487: file funcuse.c, line 5.

運行
(gdb) r
Starting program: /home/weiwei/Desktop/c/dbug 

Breakpoint 1, main () at funcuse.c:5
5			printf("this is %d\n",i);
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.25.el6.i686 libgcc-4.4.5-6.el6.i686 libstdc++-4.4.5-6.el6.i686

到斷點處程序停止,繼續運行輸入continue
(gdb) c
Continuing.
this is 0

Breakpoint 1, main () at funcuse.c:5
5			printf("this is %d\n",i);
(gdb) c
Continuing.
this is 1

Breakpoint 1, main () at funcuse.c:5
5			printf("this is %d\n",i);
(gdb) c
Continuing.
this is 2

監測某一個值
(gdb) watch i
Hardware watchpoint 2: i

(gdb) c
Continuing.
this is 3
Hardware watchpoint 2: i

Old value = 3
New value = 4
0x080484a0 in main () at funcuse.c:4
4		for(int i=0 ; i<5; i++){

查看某一個特定的變量
(gdb) print i

自動顯示變量的值,每次運行到斷點處都會自動顯示
(gdb) display i

查看當前自動顯示的所有變量
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1:   y  i

查看變量類型
(gdb) whatis i
type = int

單步執行,step進入函數內部( 使用return命令跳出來 ,跳出前可以使用finish執行完函數體),next把函數當成一條語句不進入函數內部
(gdb) step  
(gdb) next

刪除編號為1的斷點
(gdb) delete 1
Copyright © Linux教程網 All Rights Reserved