【C語言】調試技巧

目錄

一、什么是bug?

二、調試

1.一般調試的步驟

2.Debug 和 Release

三、調試環境準備

?四、調試時要查看的信息

1.查看臨時變量的值

2.查看內存信息?

?3.查看調用堆棧

?4.查看反匯編信息

5.查看寄存器?

五、練習

六、常見的coding技巧

七、const的作用?

八、編程常見的錯誤


一、什么是bug?

我們平時會口頭說 bug ,報錯,waring(報警)等,bug 英文的意思是蟲子,然而在計算機發展史上的第一只 Bug ,真的是因為一只飛蛾意外走入一電腦而引致故障,因此Bug從原意為臭蟲引申為程序錯誤。

當我們

?

?這個時候就需要我們的調試 來開啟新大陸

關于程序錯誤的?參考資料

二、調試

平時敲代碼,總會遇到與一些問題導致程序執行不過去,你可能在那一直盯著剛寫完的代碼看(心里想這到底哪里出錯了,但是就是沒有找打錯誤的原因),這時就需要我們平時了解到的調試來解決問題(起先使用可能不熟練,慢慢來)

調試(英語:Debugging / Debug),又稱除錯,是發現和減少計算機程序或電子儀器設備中程序錯誤的一個過程

1.一般調試的步驟

  • 發現程序錯誤的存在
  • 以隔離、消除等方式對錯誤進行定位
  • 確定錯誤產生的原因
  • 提出糾正錯誤的解決辦法
  • 對程序錯誤予以改正,重新測試

2.Debug 和 Release

Debug 通常稱為調試版本,它包含調試信息,并且不作任何優化,便于程序員調試程序。

Release 稱為發布版本,它往往是進行了各種優化,使得程序在代碼大小和運行速度上都是最優的,以便用戶很好地使用。

接下來調試下方代碼

#include<stdio.h>
int main() 
{char* p = "hello word!";printf("%s\n",p);return 0;
}

在debug版本下 (執行程序)文件名.exe? 是幾十KB

而在release版本下? 是 幾 KB(原因是代碼大小和運行速度上都是最優的)

再看下方代碼

#include<stdio.h>
int main() 
{int i = 0;int arr[10] = { 0 };for (i = 0; i <= 12;i++){arr[i] = 0;printf("haha\n");}return 0;
}

在 vs2022 x86 debug 的環境下?

該程序的【執行結果】 無限循環打印 haha

而在release版本下?

?

沒有死循環 打印了13行的haha

二者區別是因為:變量在內存中開辟的順序發生了變化,影響到了程序執行的結果

三、調試環境準備

?如果要對代碼進行調試首先要準備好調試的環境

就是要在debug版本下,才能使代碼正常調試

(點擊開始調試)或者按F5

在這里介紹一些調試的快捷鍵

  • F5? 啟動調試,經常用來直接跳到下一個斷點處?
  • F9??創建斷點和取消斷點。?斷點的重要作用,可以在程序的任意位置設置斷點。
    這樣就可以使得程序在想要的位置隨意停止執行,繼而一步步執行下去
  • F11? 逐語句,就是每次都執行一條語句,但是這個快捷鍵可以使我們的執行邏輯進入函數內部(這是最長用的)
  • F10??逐過程,通常用來處理一個過程,一個過程可以是一次函數調用,或者是一條語句
  • Ctrl + F5?開始執行不調試,如果你想讓程序直接運行起來而不調試就可以直接使用

其他快捷鍵

?四、調試時要查看的信息

1.查看臨時變量的值

在按調試后,觀察變量的值

例如 輸入 i

?

一直按F11當 i 的值變為 11時? i值的變化(0-11)

2.查看內存信息?

?

在內存窗口 輸入 &i(找到i 的內存地址)

?3.查看調用堆棧

反映的是調用邏輯

?4.查看反匯編信息

?

5.查看寄存器?

五、練習

【例 1】

//實現代碼:求 1!+2!+3! ...+ n! ;不考慮溢出
int main()
{int i = 0;int sum = 0;//保存最終結果int n = 0;int ret = 1;//保存n的階乘scanf("%d", &n);for (i = 1; i <= n; i++){int j = 0;for (j = 1; j <= i; j++){ret *= j;}sum += ret;}printf("%d\n", sum);return 0;
}

?輸入 1,輸入2 和我們預想的結果一樣,但當我們輸入 3 的時候結果應該是 9 實際輸出結果為:

?打印的結果出錯了

接著進行調試,當調試到 i= 2是 正常的

?調試到 j = 3 是 ret 應該是 6 ,但是發現 ret由4 變到 12

?經果分析我們發現 原來是ret 每次進入內層的for循環 ret 的值接著上次的執行結果繼續算

這時 我們在內層for循環上方加上? ret? =1;

//實現代碼:求 1!+2!+3! ...+ n! ;不考慮溢出
#include<stdio.h>
int main()
{int i = 0;int sum = 0;//保存最終結果int n = 0;int ret = 1;//保存n的階乘scanf("%d", &n);for (i = 1; i <= n; i++){int j = 0;ret = 1;//添加的代碼for (j = 1; j <= i; j++){ret *= j;}sum += ret;}printf("%d\n", sum);return 0;
}

?【例 2 】死循環的原因

#include<stdio.h>
int main() 
{int i = 0;int arr[10] = { 0 };for (i = 0; i <= 12;i++){arr[i] = 0;printf("haha\n");}return 0;
}

調試后發現?

?

六、常見的coding技巧

  • 使用assert(斷言,是一個宏,在release版本中會自動優化掉)
  • 盡量使用const(下面會講到用法)
  • ?養成良好的編碼風格
  • 添加必要的注釋
  • 避免編碼的陷阱

【例】模擬實現庫函數strcpy、

庫函數strcpy?

//模擬實現strcpy
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char *des,const char *src)
{assert(des != NULL);assert(src != NULL);//避免字符串為空char* temp = des;while (*des){*des = *src;des++;src++;}return (temp);
}
int main()
{char* str = "ab";char arr[20] = "xxxxxxxxxx";printf("%s\n",my_strcpy(arr,str));return 0;
}

優化

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* des,const char *src) 
{assert(des != NULL);assert(src != NULL);char* temp = des;//用于返回首元素地址while (*temp++ = *src++);return des;
}
int main() 
{char *arr1 = "abcdef";char* arr2[20] = {0};printf("%s\n",my_strcpy(arr2,arr1));return 0;
}

七、const的作用?

const 在 * 左邊

int num =0;
int n = 0;
const int *p =&num; 
p = &n;  //ok
*p = 20; //error

const 在 * 右邊

int n = 1000;
int num = 0;
int * const p = &num; //限制了指針變量本身
p = &n; //error
*p = 20;//ok 

?【小總結】

const 修飾指針變量的時候:

  1. const放在 * 左邊,修飾的是指針指向的內容,保證指針指向的內容不被修改。但是指針變量可以修改
  2. const 放在* 右邊,修飾的是指針變量本身,保證指針變量本身不被修改。但是可以修改指針指向的內容

練習:模擬實現strlen

//模擬實現strlen
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str) 
{assert(str != NULL);int count = 0;while (*str) {count++;str++;}return count;
}
int main() 
{char* str = "abcdefg";printf("%d\n",my_strlen(str));return 0;
}

八、編程常見的錯誤

  • 編譯型錯誤

直接看錯誤提示信息(雙擊),解決問題。或者憑借經驗就可以搞定

  • 鏈接型錯誤

看錯誤提示信息,主要在代碼中找到錯誤信息中的標識符,然后定位問題所在。一般是標識符名不
存在或者拼寫錯誤

  • 運行時錯誤

借助調試,逐步定位問題。

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

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

相關文章

Linux - MongoDB 數據庫自動退出服務問題/閃退

問題&#xff1a;MongoDB 自動退出服務問題 原因&#xff1a; 由于 Mongodb 服務&#xff0c;使用過多系統內存&#xff0c;導致系統強制停止 Mongodb 服務。 解決方法&#xff1a; 在 mongodb.conf 配置文件內&#xff0c;添加新配置內容&#xff1a; wiredTigerCacheSi…

POI與EasyExcel--寫Excel

簡單寫入 03和07版的簡單寫入注意事項&#xff1a; 1. 對象不同&#xff1a;03對應HSSFWorkbook&#xff0c;07對應XSSFWorkbook 2. 文件后綴不同&#xff1a;03對應xls&#xff0c;07對應xlsx package com.zrf;import org.apache.poi.hssf.usermodel.HSSFWorkbook; import …

如何應用項目管理軟件進行敏捷開發管理

敏捷開發&#xff08;Agile Development&#xff09;是一種軟件開發方法論&#xff0c;強調在不斷變化的需求和環境下&#xff0c;通過迭代、協作和自適應的方式來開發軟件。敏捷方法的目標是提供更快、更靈活、更高質量的軟件交付&#xff0c;以滿足客戶需求并實現項目成功。 …

服務器數據恢復-EqualLogic存儲RAID5數據恢復案例

服務器數據恢復環境&#xff1a; 一臺DELL EqualLogic存儲中有一組由16塊SAS硬盤組建的RAID5陣列。存儲存放虛擬機文件&#xff0c;采用VMFS文件系統&#xff0c;劃分了4個lun。 服務器故障&檢測&分析&#xff1a; 存儲設備上有兩個硬盤指示燈顯示黃色&#xff0c;存儲…

【Windows 常用工具系列 6 -- CSDN字體格式(字體、顏色、大小)、背景色設置】

文章目錄 背景字體大小設置字體顏色設置字體類型背景色 上篇文章&#xff1a;Windows 常用工具系列 5 – Selenium IDE的使用方法 下篇文章&#xff1a;Windows 常用工具系列 7 – 禁用win10自帶的微軟輸入法 背景 Markdown是一種輕量級標記語言&#xff0c;它的目標是實現“…

1022.從根到葉的二進制之和

目錄 一、題目 二、代碼 一、題目 二、代碼 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nu…

基于java計算機類考研交流平臺設計與實現

摘要 高校的大學生考研是繼高校的高等教育更上一層的表現形式&#xff0c;教育的發展是我們社會的根本&#xff0c;那么信息技術的發展又是改變我們生活的重要因素&#xff0c;生活當中各種各樣的場景都存在著信息技術的發展。信息技術發展WEB信息化的到來讓人們的生活感受到了…

vue項目的實用性總結

1、mockjs 基本使用 ★ 安裝&#xff1a;npm i mockjs。 在src/mock/index.js內容如下&#xff1a; import Mock from mockjs //制訂攔截規則 Mock.mock(http://www.0313.com,get,你好啊)記得在main.js中引入一下&#xff0c;讓其參與整個項目的運行。 只要發出去的是get類型…

家紡行業小程序商城搭建指南

家紡行業作為一個不可或缺的消費領域&#xff0c;近年來備受關注。隨著互聯網的發展&#xff0c;小程序商城成為家紡行業拓展市場的新利器。搭建一個家紡行業小程序商城并不是一件困難的事情&#xff0c;只需要按照以下幾個步驟進行操作&#xff0c;就能輕松上手。 首先&#x…

Java后端框架模塊整合

提示&#xff1a;使用Java后端開發框架能夠提高開發效率、代碼質量&#xff0c;提升可擴展性&#xff0c;降低開發成本和易于維護。 文章目錄 前言MyBatis 框架知識Spring 框架知識SpringMVC 框架知識SpringBoot 框架知識 前言 提示&#xff1a;這里可以添加本文要記錄的大概內…

2023-08-15 LeetCode每日一題(字符串中的查找與替換)

2023-08-15每日一題 一、題目編號 833. 字符串中的查找與替換二、題目鏈接 點擊跳轉到題目位置 三、題目描述 你會得到一個字符串 s (索引從 0 開始)&#xff0c;你必須對它執行 k 個替換操作。替換操作以三個長度均為 k 的并行數組給出&#xff1a;indices, sources, tar…

UI設計師個人工作總結范文

UI設計師個人工作總結范文篇一 感受到了領導們“海納百川”的胸襟&#xff0c;感受到了作為廣告人“不經歷風雨&#xff0c;怎能見彩虹”的豪氣&#xff0c;也體會到了重慶廣告從業人員作為拓荒者的艱難和堅定(就目前國內廣告業而言&#xff0c;我認為重慶廣告業尚在發展階段并…

FreeRTOS(獨立看門狗監測任務執行與低功耗Tickless模式)

資料來源于硬件家園&#xff1a;資料匯總 - FreeRTOS實時操作系統課程(多任務管理) 目錄 一、獨立看門狗介紹 二、看門狗監測多任務執行思路 1、監測目標 2、監測方案 3、應用注意事項 三、看門狗監測多任務編程 1、STM32cubeMX配置 2、代碼編寫 四、低功耗Tickless模…

LeetCode 熱題 100 JavaScript--739. 每日溫度

給定一個整數數組 temperatures &#xff0c;表示每天的溫度&#xff0c;返回一個數組 answer &#xff0c;其中 answer[i] 是指對于第 i 天&#xff0c;下一個更高溫度出現在幾天后。如果氣溫在這之后都不會升高&#xff0c;請在該位置用 0 來代替。 示例 1: 輸入: temperat…

基于HTML+CSS+Echarts大屏數據可視化集合共99套

基于HTMLCSSEcharts大屏數據可視化集合共99套 一、介紹二、展示1.大數據展示系統2.物流訂單系統3.物流信息系統4.辦稅渠道監控平臺5.車輛綜合管控平臺 三、其他系統實現四、獲取源碼 一、介紹 基于HTML/CSS/Echarts的會議展覽、業務監控、風險預警、數據分析展示等多種展示需求…

c++--異常

1.什么是異常 對于C語言來說&#xff0c;處理錯誤的機制有&#xff1a; 1.終止程序&#xff1a;如assert&#xff0c;缺陷&#xff0c;如發生內存錯誤&#xff0c;除0之外發生程序終止&#xff0c;用戶無法接受。 2.返回錯誤碼&#xff1a;對于大型程序來說&#xff0c;需要…

docker搭建lnmp(nginx+mysql57+php7.4)

docker搭建lnmp(nginxmysql57php7.4) 1. 準備工作 docker安裝 $ sudo yum update $ sudo sudo yum install -y yum-utils device-mapper-persistent-data lvm2 $ sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo $ sudo…

React 全棧體系(一)

第一章 React入門 一、React簡介 1. 是什么&#xff1f; 是一個將數據渲染為HTML視圖的開源JavaScript庫。 2. 誰開發的&#xff1f; 由Facebook開源 3. 為什么要學&#xff1f; 原生JavaScript操作DOM繁瑣&#xff0c;效率低&#xff08;DOM-API 操作 UI&#xff09; 使…

前端css進階

day04-CSS進階 目標&#xff1a;掌握復合選擇器作用和寫法&#xff1b;使用background屬性添加背景效果 01-復合選擇器 定義&#xff1a;由兩個或多個基礎選擇器&#xff0c;通過不同的方式組合而成。 作用&#xff1a;更準確、更高效的選擇目標元素&#xff08;標簽&#xf…

論文閱讀——Adversarial Eigen Attack on Black-Box Models

Adversarial Eigen Attack on Black-Box Models 作者&#xff1a;Linjun Zhou&#xff0c; Linjun Zhou 攻擊類別&#xff1a;黑盒&#xff08;基于梯度信息&#xff09;&#xff0c;白盒模型的預訓練模型可獲得&#xff0c;但訓練數據和微調預訓練模型的數據不可得&#xff…