Linux實驗四:編譯和調試工具的使用

文章目錄

  • 一、實驗目的:
  • 二、實驗要求
  • 三、實驗內容
  • 四、實驗操作
    • 1、用gcc編譯程序,寫出編譯過程,并給出運行結果。
    • 2、調試程序,要求用gdb進行調試并給出修改方案。
    • 3、make的使用


一、實驗目的:

1、練習并掌握Linux提供的vi編輯器來編譯C程序

2、學會利用gcc、gdb編譯、調試C程序

3、學會使用make工具


二、實驗要求

1、編寫C語言程序,用gcc編譯并觀察編譯后的結果,運行生成的可執行文件。

2、利用gdb調試程序。

3、學習編寫makefile,并進行編譯。


三、實驗內容

1、GNU C編譯器

(1)使用gcc

通常后跟一些選項和文件名來使用gcc編譯器。gcc命令的基本用法如下:
gcc [options] [filenames] 命令行選項指定的編譯過程中的具體操作

(2)gcc常用選項

當不用任何選項編譯一個程序時,gcc將建立(假定編譯成功)一個名為a.out的可執行文件。 選項含義:
-o FILE 指定輸出文件名,在編譯為目標代碼時,這一選項不是必須的。如果FILE 沒有指定,默認文件名是a.out. 也可用-o選項來為即將產生的可執行文件指定一個文件名來代替a.out。
-c GCC 僅把源代碼編譯為目標代碼。默認時GCC 建立的目標代碼文件有一個.o 的 擴展名。
-E 對文件進行預處理
-S 對文件進行編譯,生成匯編代碼。
-O 對源代碼進行基本優化。這些優化在大多數情況下都會使程序執行得更快。
-g 在可執行程序中包含標準調試信息。
-Wall 允許發出GCC 能提供的所有有用的警告,也可以用-W(warning)來標識指定的警告。
-l name 鏈接靜態庫
-L dir 庫文件的搜索路徑

(3)執行文件

格式: ./可執行文件名

2、gdb調試工具

(1)調試編譯代碼

為了使gdb正常工作,必須使你的程序在編譯時包含調試信息。調試信息里包含你程序里的每個變量的類型和在可執行文件里的地址映射以及源代碼的行號。gdb利用這些信息使源代碼和機器碼相關聯。
在編譯時用 –g 選項打開調試選項。

(2)gdb基本命令

命令描述
file裝入欲調試的可執行文件
kill終止正在調試的程序
list列出產生執行文件的源代碼部分
next執行一行源代碼但不進入函數內部
step執行一行源代碼并進入函數內部
run執行當前被調試的程序
quit終止gdb
watch監視一個變量的值而不管它何時被改變
break在代碼里設置斷點,使程序執行到這里時被掛起
make不退出gdb就可以重新產生可執行文件
shell不離開gdb就執行UNIX shell 命令

四、實驗操作

1、用gcc編譯程序,寫出編譯過程,并給出運行結果。

mypow.c:定義mypow()函數

unsigned long long mypow(unsigned int x, unsigned int y)
{unsigned long long res=1;if (y==0)res = 1;else if (y==1):res = x;elseres = x * mypow(x, y-1);return res;
}

powtest.c:調用mypow()函數

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{unsigned int x, y;unsigned long long res;if ((argc<3) || (sscanf(argv[1], "%u", &x)) != 1 || (sscanf(argv[2], "%u", &y)) != 1 ){printf("Usage:pow base exponent\n");exit(1);}res = mypow(x, y);printf("%u ^ %u = %u\n", x, y, res);return 0;
}

gcc -o命令編譯

在這里插入圖片描述

gcc命令編譯

在這里插入圖片描述
在這里插入圖片描述

要注意實驗中給出的powtest.c文件里沒有對mypow.c頭文件進行引用,因此做實驗的時候自己要加這個頭文件如下圖第四行

在這里插入圖片描述

2、調試程序,要求用gdb進行調試并給出修改方案。

(1)源程序的功能:按照正序和逆序輸出給定的字符串。要求用gdb進行調試,分析出錯的原因并給出修改方案。

#include <stdio.h>
#include <string.h>
#include <malloc.h>
void my_print (char *string);
void my_print2 (char *string);
int main()
{char my_string[] = "hello there";my_print (my_string);my_print2 (my_string);return 0;
}                                                                                        
void my_print (char *string)
{printf ("The string is %s\n", string);
}                                                                                        
void my_print2 (char *string)
{char *string2;int size, i;size = strlen (string);string2 = (char *) malloc (size + 1);for (i = 0; i < size; i++)string2[size - i] = string[i];string2[size + 2] = '\0';printf ("The string printed backward is %s\n", string2);
}

在這里插入圖片描述
在這里插入圖片描述
第一種調試方法:
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

上述調試方法中從26行跳出,然后查證string數組的值,會發現string[0]位置上的值未被替換,仍為正序輸入

第二種調試方法
在這里插入圖片描述

上述方法中可以看出來size的值是11,之后的語句size-i我們可知是從string2[11]開始賦值的,那這樣我們賦值到string2[1]時,“hello there"就復制結束了,但是string2[0]仍未被賦值,這就出現了錯誤。

Warning:string2[0]='\000' string2[1]='e' string2[2]='r' string2[size]='h'
也就是說沒有從string2[10]開始存儲值,而是從string2[11]開始存儲的,故string2[0]產生空置。
方案:賦值時應該size-1-i開始逆序賦值,而不是size-i
將 string2[size - i] = string[i]; 替換成 string2[size - i - 1] = string[i];
將string2[size + 2] = ‘\0’; 替換成 string2[size] = ‘\0’;

在這里插入圖片描述


3、make的使用

(1)用vi編輯以下程序,程序清單:

main.c

function1.h

function1.c

function2.h

function2.c

//main.c
#include "function1.h"
#include "function2.h" 
int main(int argc, char **argv)
{
function1_print("hello");
function2_print("world");return 0;
}
//function1.h 
void function1_print(char *str); 
//function1.c 
#include "function1.h"
void function1_print(char *str)
{
printf("This is function1 print %s\n", str);
}
//function2.h
void function2_print(char *str); 
//function2.c 
#include "function2.h"
void function2_print(char *str)
{
printf("This is function2 print %s\n", str);
}

(2)實驗要求:

a)畫出各個源程序、目標文件以及最終的目標文件之間的依賴關系圖。

在這里插入圖片描述

b)編輯makefile文件

在這里插入圖片描述
ps:上傳圖片的時候才發現自己把function2.o寫成function2.0了,我個鐵憨憨

c)利用make命令進行上述程序的編譯,生成可執行代碼并運行。

在這里插入圖片描述

d)修改其中一個源文件,重新make,察看編譯過程。

在這里插入圖片描述

e)通過使用makefile變量和隱含規則,對makefile文件進行簡化

在這里插入圖片描述

這里的 $(CFLAGS)可以不寫,其是c編譯器的選項,無默認值,這里我們也不需要選擇編譯器,但是養成良好的代碼習慣也是很必要滴 ~ 萬一以后需要選擇編譯器但沒寫(不大可能),找起bug來會非常頭疼滴 ~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443886.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443886.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443886.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux實驗五:Linux環境下的C語言編程

文章目錄一、實驗目的&#xff1a;二、實驗要求三、實驗內容1、編寫一段C語言程序使其完成&#xff1a;父進程創建兩個子進程&#xff0c;每個進程都在屏幕上顯示自己的進程ID號。2、上機調試下面的程序&#xff0c;觀察運行結果&#xff0c;分析原因。3、利用兩個管道進行雙向…

百戰c++(4)

1.求下面函數的返回值&#xff08;微軟&#xff09; int func(x) { int countx 0; while(x) { countx ; x x&(x-1); } return countx; } 假定x 9999。 答案&#xff1a;8 思路&#xff1a;將x轉化為2進制&#xff0c;看含有的1的個數。 2. 什么是“引用”&…

ndarray對象的建立

文章目錄ndarray&#xff08;別名array&#xff09;常用屬性創建NumPy數組使用array()函數使用zeros()函數使用ones()函數使用empty()函數使用arange()函數注意ndarray&#xff08;別名array&#xff09; 常用屬性 import numpy as np # Numpy工具包data np.arange(12).res…

百戰c++(5)

11. 已知strcpy的函數原型&#xff1a;char *strcpy(char *strDest, const char *strSrc)其中strDest 是目的字符串&#xff0c;strSrc 是源字符串。不調用C/C 的字符串庫函數&#xff0c;請編寫函數 strcpy。 答案&#xff1a; char *strcpy(char *strDest, const char *strS…

Numpy數組的廣播機制

文章目錄前言數組廣播廣播機制的使用條件前言 Numpy數組不需要循環遍歷&#xff0c;即可對每個元素執行批量的算術運算操作&#xff08;矢量化運算&#xff09;。當兩個數組大小&#xff08;Numpy.shape&#xff09;不同時&#xff0c;進行算術運算會出現廣播機制。 數組廣播…

百戰c++(6)

26. 描述內存分配方式以及它們的區別? 1&#xff09; 從靜態存儲區域分配。內存在程序編譯的時候就已經分配好&#xff0c;這塊內存在程序的整個運行期間都存在。例如全局變量&#xff0c;static 變量。 2&#xff09; 在棧上創建。在執行函數時&#xff0c;函數內局部變量的…

Spring3.1.0+Quartz1.8.6整合實現計劃任務

1.首先要加入任務計劃的相關的jar包&#xff0c;這里除了需要加Spring3.1.0的jar&#xff0c;還需要加quartz-all-1.8.6.jarslf4j-api-1.5.8.jar slf4j-log4j12.jar這三個包&#xff0c;如果你是SSH整合的項目&#xff0c;里面有下面的兩個包了&#xff0c;就可以不加&#xff…

百戰c++(7)

40. 鏈表題&#xff1a;一個鏈表的結點結構 struct Node { int data ; Node *next ; }; typedef struct Node Node ; (1)已知鏈表的頭結點head,寫一個函數把這個鏈表逆序 ( Intel) Node * ReverseList(Node *head) //鏈表逆序 { if ( head NULL || head->next NU…

數組的轉置和軸對稱

文章目錄T屬性transpose()方法swapaxes()方法T屬性 import numpy as np # Numpy工具包data np.arange(12).reshape(3, 4) # 創建一個3行4列的數組 print(data)# 數組的轉置和軸對稱 data1 data.T print(data1)print(data) [[ 0 1 2 3] [ 4 5 6 7] [ 8 9 10 11]] print(dat…

百戰c++(8)

43. 寫一個在一個字符串(n)中尋找一個子串(m)第一個位置的函數。 KMP算法效率最好&#xff0c;時間復雜度是&#xff2f;(nm)。 44. 多重繼承的內存分配問題&#xff1a; 比如有class A : public class B, public class C {} 那么A的內存結構大致是怎么樣的&#xff1f; 這…

管道實現父子進程的信息傳遞(一)【fork函數、pipe函數、write/read操作、wait函數】

文章目錄題目描述代碼實現關于pipe函數關于讀寫操作關于讀寫端口關于wait函數功能&#xff1a;注意&#xff1a;關于fork函數題目描述 編寫一個程序&#xff0c;利用管道實現父子進程的通信&#xff0c;父進程向子進程發送信息&#xff0c;由子進程輸出顯示。 代碼實現 #inclu…

基礎的shell編程問題(一)

文章目錄題目一題目描述代碼實現關于$#的有關內容實測本程序的作用題目二題目描述代碼實現注釋關于argc、argv關于read函數關于文件描述符關于write函數本程序的作用題目三題目描述代碼實現實測關于grep命令關于read命令題目四題目描述代碼實現關于test命令實測題目一 題目描述…

百戰c++(9)

12 . 下面的代碼輸出是什么&#xff0c;為什么&#xff1f; void foo(void) { unsigned int a 6; int b -20; (ab > 6) puts("> 6") : puts("< 6"); } 這個問題測試你是否懂得C語言中的整數自動轉換原則&#xff0c;我發現有些開發者懂得…

基礎的shell編程問題(二)

文章目錄題目一題目描述代碼實現結果驗證關于本題題目二題目描述代碼實現結果測試題目三題目描述代碼實現及結果測試題目四題目描述代碼實現及結果測試題目五題目描述代碼實現及結果測試題目一 題目描述 輸入的命令行參數必須是hello&#xff0c;才會正確顯示&#xff1b;否則…

百戰c++(10)

1.多態類中的虛函數表是Compile-Time&#xff0c;還是Run-Time時建立的? 2.將一個 1M -10M 的文件&#xff0c;逆序存儲到另一個文件&#xff0c;就是前一個文件的最后一個 字符存到新文件的第一個字符&#xff0c;以此類推。 3.main主函數執行完畢后&#xff0c;是否可能會…

Numpy實現酒鬼漫步問題【以及randint()、where()、cumsum()、argmax()的用法詳解】

文章目錄題目描述代碼實現關于本題涉及到的幾個函數randint()where()cumsum()題目拓展題目描述代碼實現題目拓展題目描述代碼實現argmax()題目描述 從前有一個酒鬼&#xff0c;喝醉了行走在一條直線上&#xff0c;每走一步方向是不確定的&#xff08;向前或者向后&#xff09;…

百戰c++(11)

31.找錯 Void test1() { char string[10]; char* str1"0123456789"; strcpy(string, str1); } Void test2() { char string[10], str1[10]; for(I0; I<10;I) { str1[i] a; } strcpy(string, str1); } Void test3(char* str1) { char string[10]; if(st…

搞清axis的含義,這一篇就夠了!

文章目錄axis的含義旁門左道式理解二維數組中的axis三維數組中的axis正規理解axis的含義 在自己分析之前先擺上官方關于多維數組中axis的值的定義&#xff1a; axis 0&#xff0c;表示第一個維度 axis 1&#xff0c;表示第二個維度 axis -1&#xff0c;表示最后一個維度…

百戰c++(12)

36. 定義 int **a[3][4], 則變量占有的內存空間為&#xff1a;_____ 37. 編寫一個函數&#xff0c;要求輸入年月日時分秒&#xff0c;輸出該年月日時分秒的下一秒。如輸入2004年12月31日23時59分59秒&#xff0c;則輸出2005年1月1日0時0分0秒。 38.寫一個函數&#xff0c;判…

Struts2.3.5+Hibernate3+Spring3.1基于注解實現的多文件上傳,下載

Struts2.3.5Hibernate3Spring3.1基于注解實現的的多文件上傳&#xff0c;下載,這里是上傳文件到數據庫中&#xff0c;上傳控件可以增加和刪除&#xff0c;有需要的朋友可以看看。 以下是源碼下載地址&#xff1a;http://www.zuidaima.com/share/1639672872438784.htm jar包的下…