linux下c++編程環境搭建,運行過程以及調試

安裝g++環境

安裝兩個RPM包便可搞定html

[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++是否安裝成功java

[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++的區別
linux

gcc能夠用來編譯C或者C++,但他只能編譯c++源文件,不能自動和C++程序使用的庫鏈接,g++能夠實現C++程序的編譯和連接,其實他也是調用gcc來編譯的,要編譯c++代碼生成可執行文件要用 g++ios

編寫一個簡單的c++程序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

打開命令窗口進行編譯redis

[root@localhost Desktop]# g++ -o test1 test.cpp

-o test1 test.cpp 從test.cpp編譯生成test1文件,test1爲可執行文件,沒有後綴shell

若是不寫-o test1 會默認生成一個a.out可執行文件express

執行可執行文件bootstrap

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

獲取main函數返回值
eclipse

[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

直接生成可執行文件


頭文件與源文件    

程序若是複雜的話,程序的各個部分會分別存儲在不一樣的文件中,按照邏輯進行劃分。

來自:http://www.cnblogs.com/lidabo/archive/2012/04/17/2454568.html

頭文件的做用就是被其餘的.cpp包含,自己並不參與編譯,但實際上它們的內容卻在多個.cpp文件中獲得了 編譯.

頭文件中應該只放變量和函數的聲明,而不能放它們的定義

這個規則是有三個例外的

  1. 頭文件中能夠寫const對象的定義

  2. 頭文件中可 以寫內聯函數(inline)的定義

  3. 頭文件中能夠寫類 (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
相關文章
相關標籤/搜索