国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

程序員必備技能之調(diào)試

這篇具有很好參考價值的文章主要介紹了程序員必備技能之調(diào)試。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

前言

本期內(nèi)容介紹

一、什么是Bug?

二、調(diào)試以及調(diào)試的重要性

2.1什么是調(diào)試?

2.2調(diào)試的基本步驟

?三、Debug和Release介紹

Debug和Release

四、windows環(huán)境下的調(diào)試介紹

4.1調(diào)試環(huán)境

4.2一些調(diào)試常用的快捷鍵

4.3調(diào)試時查看當前程序的信息

a、查看臨時變量的值

b、查看程序的內(nèi)存信息

c、查看程序的調(diào)用堆棧

d、查看程序的匯編信息

e、查看寄存器信息

五、一些調(diào)試實例

六、如何寫出“好”代碼?

6.1什么是好代碼?

6.2如何寫出好代碼?

assert介紹

const介紹

七、常見的錯誤解析

7.1編譯型錯誤

7.2鏈接型錯誤

7.3運行時錯誤


前言

我們平時在寫代碼的時候會出現(xiàn)各種錯誤,面對程序出現(xiàn)的錯誤我們之前好像沒有介紹過如何高效、科學、系統(tǒng)地處理這種錯誤!您平時一般是如何說處理的呢?走讀?猜?還是???無論哪種方式其實都是不是最高效且合理的!本期小編將介紹VS常用調(diào)試技巧!

本期內(nèi)容介紹

什么是Bug?

調(diào)試及調(diào)試的重要性

Debug和Release介紹

windows環(huán)境調(diào)試介紹

一些調(diào)試實例

如何寫出"好"代碼?

常見錯誤解析

一、什么是Bug?

Bug的意思是:飛蛾或昆蟲!在計算機中用Bug來代指一些未被發(fā)現(xiàn)的或隱藏的錯誤或缺陷!

下面是百度百科的介紹以及歷史上第一個Bug的圖片:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這是關(guān)于Bug的更詳細的鏈接程序錯誤_百度百科 (baidu.com)感興趣的可以看看!

二、調(diào)試以及調(diào)試的重要性

2.1什么是調(diào)試?

調(diào)試又稱除錯!是當程序或電子儀器出現(xiàn)了問題之后對程序或電子儀器進行科學排查、尋找問題以及解決問題的過程!

2.2調(diào)試的基本步驟

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

OK,我們來寫個有問題程序來走一遍上面步驟:(求n的階乘和)

int main()
{
	int n = 0;
	scanf("%d", &n);
	int sum = 0, ret = 1;//sum存儲n的階乘和 ret用于存儲每一個的階乘  
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			ret *= j;
		}
		sum += ret;
	}

	printf("sum  = %d",sum);
	return 0;
}

我們知道3!和為:1!+ 2! + 3! = 1 + 2*1 + 3* 2*1 = 9 我們來看結(jié)果:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

怎么是15???這和我們的預(yù)期不一樣,是不是就是出現(xiàn)了Bug了!我們就得想辦法來解決這個問題!第一步:發(fā)現(xiàn)問題,結(jié)果和預(yù)期不一樣,已經(jīng)發(fā)現(xiàn)問題!第二步:定位問題:我們這里對變量sum 和 ret分別監(jiān)視,一一比對每一次sum、ret的值是否與預(yù)期一樣!第三步:確定錯誤原因:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這里確定了問題的原因,怎么解決呢?我們發(fā)現(xiàn)這里應(yīng)該對每一個i的階乘都要單獨算,要就是說每一個ret都應(yīng)該獨立的,每一次的ret都應(yīng)該是沒有被用過的!那我們在每次計算每個i的時候?qū)et一開始先置 1即可!第四步:解決問題

int main()
{
	int n = 0;
	scanf("%d", &n);
	int sum = 0, ret = 1;//sum存儲n的階乘和 ret用于存儲每一個的階乘  
	for (int i = 1; i <= n; i++)
	{
		ret = 1;//防止后面的值重復(fù)疊加
		for (int j = 1; j <= i; j++)
		{
			ret *= j;
		}
		sum += ret;
	}

	printf("sum  = %d",sum);
	return 0;
}

OK,第五步:重新測試:

三、Debug和Release介紹

我們的VS編譯器上會經(jīng)??吹揭粋€東西是Debug!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

其實不止有Debug還有一個是Release!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

他們是什么呢?下面我們就來介紹一下Debug和Release:

Debug和Release

Debug:

Debug被稱為調(diào)試版本,它包含了調(diào)試信息,不做任何優(yōu)化,用于程序員調(diào)試解決問題!

Release:

Release被稱為發(fā)布版本,它往往是對程序進行了優(yōu)化,是的代碼在運行速度以及空間大小都是最優(yōu)的!用于用戶使用的!

無論是Debug還是Release只要編譯就會有相應(yīng)的文件包,(就和Java中的.class類似,一個類編譯一次有一個.class文件):

只在Debug編譯:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

再在Release下編譯:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

由于Release是用戶使用的所以不能用來調(diào)試,而Debug是對程序員的所以可以用來調(diào)試!

OK。我們來看一段代碼看看在兩個版本下的差異:

Debug:

int main()
{
	int i = 0; 
	int arr[10] = { 0 };
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("hehe\n");
	}
	return 0;
}

我們先不管結(jié)果為什么是這樣!我們先來看看兩者結(jié)果的差別?。?/p>

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這可不是結(jié)束了,這就是典型的死循環(huán)?。?!為什么死循環(huán)我們不管,待會分析!

再來看看Release版本下的結(jié)果:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這就很好的說明了release版本對程序的優(yōu)化!??!具體如何優(yōu)化的這個得問問微軟的開發(fā)工程師~

四、windows環(huán)境下的調(diào)試介紹

4.1調(diào)試環(huán)境

本期所有調(diào)試都是在VS2019的Debug下進行的?。。?/span>

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

4.2一些調(diào)試常用的快捷鍵

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這里應(yīng)該最清楚的一個就是:ctrl+F5了我們執(zhí)行代碼就是這個,他其實是開始執(zhí)行不調(diào)試?。?!除此之外還有很多快捷鍵!我們下面介紹幾個最常用的!

F5

啟動調(diào)試,常用于直接跳到下一個斷點處?。ㄟ@個斷點是邏輯斷點,非物理斷點)

F9

創(chuàng)建和取消斷點,然后F5直接跳過去到當前斷點位置,然后就可以一步一步調(diào)試觀察是否和預(yù)期一樣!

所以,F(xiàn)5和F9是一起配合使用的!

F10

逐過程,通常是用來處理一個過程例如一次函數(shù)調(diào)用或一條語句!

F11

逐語句,每一次只能執(zhí)行一條語句,可以進到函數(shù)內(nèi)部!

如果您在調(diào)試的時候,上面的鍵按一下不起作用的話,有可能是Fn打開了,關(guān)掉Fn即可或者是上面的鍵+Fn配合使用即可?。。?/strong>

下面是知乎的一篇VS2019的調(diào)試技巧快捷鍵介紹:VS2019調(diào)試快捷鍵大全

4.3調(diào)試時查看當前程序的信息

a、查看臨時變量的值

在開始調(diào)試之后如何查看臨時變量的值!其實我們上面已經(jīng)用到了,只不過剛剛沒有介紹!

我們按下F10之后,啟動調(diào)試后,點擊調(diào)試,進去選擇窗口找到監(jiān)視,有四個窗口隨便一個都可以!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

OK,我們在來一個看一個代碼順便調(diào)試看一下臨時變量!


void swap(int x, int y)
{
	int tmp = x; 
	x = y;
	y = tmp;
}

int main()
{
	int a = 3;
	int b = 5;
	printf("交換前:a = %d  b = %d\n", a, b);
	swap(a, b);
	printf("交換后:a = %d  b = %d\n", a, b);
	return 0;
}

這就是交換兩個數(shù)的代碼,我們先來看看結(jié)果!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

似乎沒有交換,其實原因我們都清楚--》形參是實參的一份臨時拷貝,改變形參不改變實參!

這里我們假裝不知道,我們此時程序的結(jié)果和我們的預(yù)期不符合出了問題!就需要調(diào)試,我們來練習一下剛剛學的!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這就是F9打的斷點,我們分析程序是在swap函數(shù)出問題的,所以F9直接跳過沒問題的.然后F5到當前斷點來!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

此時問題在函數(shù)里面,我們介紹過。F11是逐語句執(zhí)行,我們可以用它進入函數(shù)內(nèi)部,看看!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

注意此時監(jiān)視x = 3, y = 5, a = 3, b = 5, 我們待會觀察a,b,x,y的變化情況!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這是調(diào)試結(jié)束的結(jié)果,此時x = 5, y = 3確實交換了,但a = 3, b = 5好像一點也沒變!我們結(jié)束打印的是a 和 b:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

結(jié)果還是a = 3, b = 5;所以沒有交換成功!這里小編也就不廢話了,這里改變了形參形參是實參的一份拷貝,兩者的空間不同,改變形參實參不受影響!我們前面已經(jīng)不止一遍的介紹過這東西了,這里就不在嘮叨了!

b、查看程序的內(nèi)存信息
int main()
{
	int a = 0x11223344;

	return 0;
}

這段代碼的內(nèi)存布局以及a的值在內(nèi)存中是如何存的?我們一起來look一look:

還是先調(diào)試起來?。。?點調(diào)試--->窗口--->內(nèi)存-->4個窗口隨便一個!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這里輸入&a就可以看到,a的內(nèi)存布局以及a中的值在內(nèi)存中的存儲形式,我們前面介紹過倒著存是因為對當前平臺是小端存儲模式!

c、查看程序的調(diào)用堆棧

我們就用下面這個簡單的代碼演示一下:

void test2()
{
	printf("hahaha\n");
}

void test1()
{
	test2();
}

int main()
{
	test1();
	return 0;
}

這個代碼就是打印一個haha,但它是如何調(diào)用的?我們就可以來看看調(diào)用堆棧!

先調(diào)試起來?。?!再點擊調(diào)試-->窗口-->調(diào)用堆棧

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

一開始還沒有調(diào)用test1只有main函數(shù)的棧幀!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

F11調(diào)用test1在main函數(shù)的上面開辟了test1的棧幀:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

在調(diào)用test2就有在test1上面創(chuàng)建了test2的函數(shù)棧幀:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

然后接下來打印完haha后就會把test2的函數(shù)棧幀銷毀,我們在函數(shù)棧幀的那一期介紹過,在調(diào)用一個函數(shù)的時候會把當前語句的下一條語句提前存起來,等棧幀銷毀的時候就直接執(zhí)行下一條語句了!所以test2帶哦萬就銷毀了,只剩test1和main函數(shù)的棧幀了!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

然后會最后main函數(shù)的棧幀也會銷毀?。?!這里我又想起來了我在介紹函數(shù)棧幀的時候說過main函數(shù)是被其他函數(shù)調(diào)用的,但那時候操作不當在調(diào)用堆棧那里沒有找到!今天小編找到了!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

在VS上調(diào)用main函數(shù)的函數(shù)是用C++寫的!當然這個具體實現(xiàn)得看編譯器,各個編譯器可能不一樣!

d、查看程序的匯編信息

先調(diào)試起來?。?!再點擊調(diào)試-->窗口-->反匯編

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

int maxNum(int x, int y)
{
	return x > y ? x : y;
}

int main()
{

	int a = 3; 
	int b = 5;
	int ret = maxNum(a, b);
	printf("max = %d", ret);
	return 0;
}

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

紅色的框是在建立函數(shù)棧幀!這個我們函數(shù)棧幀介紹過!下面藍色的框是在創(chuàng)建變量!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這就是調(diào)用函數(shù)的指令!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這個就是maxNum的函數(shù)棧幀?。。?!的創(chuàng)建以及銷毀的反匯編!

e、查看寄存器信息

這個可能很多剛剛?cè)腴T的或者還沒入門的小伙伴都不知道!

寄存器(register)是cpu周圍的暫時放數(shù)據(jù)的地方,由于在cpu周圍所以訪問速度很快但空間不大!而且在寄存器上創(chuàng)建的變量是沒有地址的!?。?!

OK,我們來段代碼看看:

int main()
{
	int a = 3;
	register int b = 5;

	return 0;
}

b就是一個寄存器的變量!他是沒有地址的!我們先對a取地址:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

在對b 取地址:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

在cpu周圍不需要開辟內(nèi)存直接可以使用?。?!

五、一些調(diào)試實例

(一)、代碼實現(xiàn):1! + 2! + ...+n!

int main()
{
	int sum = 0;
	int ret = 1;
	int n = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= i; j++)
		{
			ret *= j;
		}

		sum += ret;
	}

	printf("%d", sum);
	return 0;
}

這段代碼我們其實一開始就介紹了,它的錯誤原因在于:每一次沒有對ret初始化為1,導致后面的ret把前面的結(jié)果疊加的乘了上去!??!我們上面也調(diào)試了,這里就不在調(diào)試了!正確代碼如下:

int main()
{
	int sum = 0;
	int ret = 1;
	int n = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		ret = 1;
		for (int j = 1; j <= i; j++)
		{
			ret *= j;
		}

		sum += ret;
	}

	printf("%d", sum);
	return 0;
}

(二)、下列程序打印機次haha?

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

如果你以前沒有見過這道題或了解過地層相關(guān)的知識的話,這道題你可能100%會回答錯!你可能只會說這道題的問題不就是越界嘛!打印13個haha然后報錯!但事實真的是這樣嗎?我們看結(jié)果:程序員必備技能之調(diào)試,C語言從入門到進階,c語言

死循環(huán)了!??!問什么呢?我們先來找原因,其實如果之前看過函數(shù)棧幀的那一期的伙伴應(yīng)該會反映過來,在VS上,創(chuàng)建的變量一個里一個差兩行0hcccccccccc:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這里我們就不在用這種方式往下解釋了,我們用調(diào)試:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

果然他也是差了兩行的ccccccccc,我們知道棧的使用規(guī)則是:先試用高地址,在使用低地址!而,數(shù)組的下標訪問是先用低地址,后用高地址!

所以數(shù)組訪問的地址路線如下:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

會不會是在越界的時候把i改了呢?我們來監(jiān)視看看:
剛剛創(chuàng)建好變量和數(shù)組:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

i==9是,馬上要越界了:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

i == 12:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

在i == 12,將arr[12] = 0;執(zhí)行完后i也變成了0,我們猜想會不是越界的時候到i=12時將i的值改為了0?換句話說i的地址和arr[12]是一樣的,他們是一塊空間?我們此時只需要看看他兩的地址即可:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

果然一模一樣!?。?!我們上面的分析是正確的??!我在畫個圖來解釋一下上面:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

那找到了問題,確定了原因,就得解決問題:

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

這樣寫的話他i的創(chuàng)建在i的后面,前面的那塊空間一單越界就會報錯!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

當然這種代碼在實踐中肯定是一般碰不到的!這個栗子僅僅是說明遇到問題了如何去解決!??!雖然在實踐中遇不到但不一定在筆試面試中碰不到:這道題曾經(jīng)就是一家叫Nice公司的筆試題:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這道提不就和剛剛這道題一樣嗎?只是換了數(shù)字而已!思路、問題、解決方法都是一樣的!?。?!

六、如何寫出“好”代碼?

6.1什么是好代碼?

我們經(jīng)常聽說好代碼,什么是好代碼呢?我們認為具備以下特征的代碼就是好代碼!

1、能正常運行

2、Bug很少

3、效率高

4、可維護性高

5、注釋清晰

6、可讀性高

7、文檔齊全

假設(shè)說你寫了個代碼,運行不了,或者即使運行起來了也全是Bug,你寫的代碼只有你自己你看的懂,不加注釋。你可能說只有自己看得懂那不就公司裁不了我了嗎?這樣想就太天真了!當代碼有幾十萬行時出了問題,你自己都控制不了的時候,,,你細品~。所以我們平時寫代碼要注重可讀性以及注釋!??!

6.2如何寫出好代碼?

這是一些寫好代碼的幾個tips:

1、使用assert

2、使用const

3、編碼風格規(guī)范

4、添加注釋

這里提到了assert和const,我們以前經(jīng)常用但沒有介紹過這兩個!下面我就先來介紹一下:

assert介紹

assert 中文意思就是斷言的意思。顧名思義就是判斷!他是一個宏!使用時要包含相應(yīng)的頭文件:#include <assert.h>

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這是官網(wǎng)對他的介紹,人家明確說了這是一個?。?!長得像函數(shù)的宏!作用是斷言!如果它的判斷的那個表達式判斷失敗就會調(diào)用:abort這個函數(shù)!并終止程序!這個宏所顯示的消息與具體的實現(xiàn)庫有關(guān),一個編譯器和一個編譯器不一樣!但他至少顯示:斷言失敗的源文件名和對應(yīng)的行數(shù)!如果你包含了頭文件還是不能用就得添加上面我畫出來的#definede 那個了!加上就OK了!!

這里還提到了一個函數(shù):abort:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這個函數(shù)的作用是終止當前進程,進程是網(wǎng)絡(luò)那部分的東西,這里就不多介紹了!這里就理解為終止當前程序(異常終止)!調(diào)用這個函數(shù)時這個函數(shù)會捕捉去一個信號,如果沒有捕捉到,就會導致程序終止,并向平臺返回一個錯誤碼!程序被終止是不會破壞任何對象??!

OK!我們來寫個代碼用一下:

typedef struct Stu
{
	char name[20];
	int age;
}S;

void print(S* ps)
{
	assert(ps);
	printf("%d", ps->age);
}

void Modif(S* ps, int age)
{
	assert(ps);
	ps->age = age;
}
int main()
{
	S s = { "張三",20 };
	Modif(&s, 19);
	print(&s);
	return 0;
}

這就是assert的作用, 當然你可以按自己的需要判斷值是否符合預(yù)期~!

const介紹

const這是一個關(guān)鍵字,我們前面開始介紹常量和變量的時候說過,被const 修飾的變量是常變量!具有常量屬性但本質(zhì)是個變量(只不過這個變量被初始化以后就不能在被修改了)!例如:

#define M 10//#define定義的常量

int main()
{
	int a = 3;//變量
	const int b = 5;//const修飾的常變量
	
	return 0;
}

因為b是被const修飾具有常量屬性不能被改,所以這里對他的值進行修改就會報錯:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

而且也不可以用它來定義數(shù)組!我們知道定義數(shù)組時[ ]里面的是一個常量(變長數(shù)組除外),變量就不行,b是常變量所以他也不行?。?!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

當然我們今天不是為了回憶以前學的,而是在此基礎(chǔ)上再進行拔高一層!比如const修飾指針的問題!先看如下代碼:

void test1()
{
	int m = 3;
	int n = 5;
	int* p = &n;
	*p = 20;
	p = &m;
}

void test2()
{
	int m = 3;
	int n = 5;
	const int* p = &n;
	*p = 20;
	p = &m;
}

void test3()
{
	int m = 3;
	int n = 5;
	int* const p = &n;
	*p = 20;
	p = &m;
}

void test4()
{
	int m = 3;
	int n = 5;
	const int* const p = &n;
	*p = 20;
	p = &m;
}

int main()
{
	test1();
	test2();
	test3();
	test4();
	return 0;
}

上面的4個代碼分是對指針p的 * 兩邊都不用const修飾,在*左邊修飾右邊不修飾,右邊修飾左邊不修飾,以及兩邊都修飾!具體會出什么結(jié)果過呢?我們一個一個看一看!

test1兩邊都不修飾:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

考慮此時的 m 和 n值是多少?

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這個不怎么難一看就知道但我想說的是!這里有一行很不起眼的代碼你可能沒有注意到!就是倒數(shù)第二行!p = &m;你可能會說這不就是一行很簡單的賦值嗎?這有啥可介紹的!你這么想就可使有點外行了!這可是指針?。。?!有了指針可以直接修改的?。。±纾?/p>

void test1()
{
	int m = 3;
	int n = 5;
	int* p = &n;
	*p = 20;
	p = &m;
	printf("m = %d  n = %d\n", m, n);
	*p = 200;
	printf("m = %d  n = %d\n", m, n);
}

看結(jié)果:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這里你還覺得他僅僅賦值那么簡單嗎?是不是感覺他很不安全呀!的確指針使用不當很危險!所以在使用指針前對他進行檢查以及作相應(yīng)的修飾限制,例如const,下面就來看看被const此時的各種情況吧!

const在*左邊:

void test2()
{
	int m = 3;
	int n = 5;
	const int* p = &n;
	*p = 20;
	p = &m;
}

這個就是const修飾*左邊的例子!如果被const修飾了左邊,會和不修飾有什么區(qū)別呢?我們想愛你編譯看看!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這貌似和const修飾一般的變量一樣!不能被修改,這個在左邊好像不能修改p指向那塊空間的值!那我們猜測:如果在右邊是不是不能改變p的值呢?我們來看看:

void test3()
{
	int m = 3;
	int n = 5;
	int* const p = &n;
	*p = 20;
	p = &m;
}

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

還真和我們猜的一樣!再回到上面的栗子test2:

void test2()
{
	int m = 3;
	int n = 5;
	const int* p = &n;
	//*p = 20;
	p = &m;
	p = NULL;
}

既然不讓修改p指向的值的話,那我改變p的值,的確可以!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

和這個類比一下,在右邊我不能改 p的值,那我可以改p指向的那塊空間的值吧!驗證一下:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

果然!那我們可以再猜測一下是不是在兩邊修飾就是既不能修改p的值也不能修改p只向空間的值呢?試一試:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

果然!這樣好像更安全了~的確是!我們現(xiàn)在就可以進行總結(jié)一下!

const 兩邊都不修飾

很不安全!??!只要拿到指針既可以修改指針也可以修改指針指向的空間的值!

const 修飾*左邊

不能對指針指向的那塊空間的值進行修改!但可以對指針的修改!

const 修飾*右邊

不能修改指針的值,但可以修改指針指向空間的值!

const 修飾兩邊

既不能修改指針的值,也不能修改指針指向空間的值!

OK,這三種修飾看具體情況使用?。。。?!我們剛剛上面的aeesrt的那個代碼是不是可以再來用優(yōu)化一下呢?

typedef struct Stu
{
	char name[20];
	int age;
}S;

void print(const S* const ps)
{
	assert(ps);
	printf("%d", ps->age);
}

void Modif(S* const ps, int age)
{
	assert(ps);
	assert(age);

	ps->age = age;
}
int main()
{
	S s = { "張三",20 };
	Modif(&s, 19);
	print(&s);
	return 0;
}

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

print函數(shù)只是打印信息不需要改變ps的值以及ps指向空間的值!下面的修改函數(shù)是需要修改ps指向空間的值但不需要改變自身的值~,加上assert和const的代碼是不是更加健壯了!以后能用就多用?。?!另外多加注釋?。?!OK,下面我們就來完整的寫一個好代碼!模擬實現(xiàn)strcpy!這個函數(shù)不必多介紹了吧,我們已經(jīng)前面模擬實現(xiàn)了兩遍了!它的作用就是拷貝字符串!~函數(shù)原型如下:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

兩個參數(shù),destination是目的地也即是要拷貝到的空間!另一個是,cosnt修飾的source是源頭,也就是要拷貝的數(shù)據(jù)!因為他只要求拷貝不讓修改,所以const修飾左邊!我們下面來實現(xiàn)一個:

char* MyStrcpy(char* dest, const char* src)
{
	//檢查空指針
	assert(dest);
	assert(src);

	//拷貝
	char* ret = dest;
	while (*dest++ = *src++)
		;

	return ret;
}

int main()
{
	char dest[20] = { 0 };
	char* src = "hello world!";
	strcpy(dest, src);//庫函數(shù)
	printf("%s\n", dest);
	printf("-----------------------\n");
	MyStrcpy(dest, src);//自己函數(shù)
	printf("%s\n", dest);
	return 0;
}

看結(jié)果:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

OK!模擬完成!

七、常見錯誤解析

7.1編譯型錯誤

一般可以直接看到錯誤信息,憑借經(jīng)驗就可以解決!一半多為語法錯誤~

例如:

int main()
{
	int a = 3
	return 0;
}

這里是少個封號,導致語法錯誤!看編譯錯誤信息:

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這種問題一般會很簡單,看看錯誤信息就可以解決!

7.2鏈接型錯誤

這種錯誤一般是由標識符錯誤火不存在導致的!看錯誤信息也很容易解決!

int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int a = 3;
	int b = 5;
	int ret = add(a, b);
	printf("%d", ret);
	return 0;
}

這里add和Add不是一個東西就會表連接時錯誤!

程序員必備技能之調(diào)試,C語言從入門到進階,c語言

這種找到改回來就好了!

7.3運行時錯誤

這是最麻煩的一種,語法沒有問題可是結(jié)果就是不符合預(yù)期,得一步一步調(diào)試~

調(diào)試也是程序員的內(nèi)功,非一日之功!~得多練習~,!

OK,好兄弟本期分享就到這里,我們下期再見~!文章來源地址http://www.zghlxwxcb.cn/news/detail-692372.html

到了這里,關(guān)于程序員必備技能之調(diào)試的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 程序員技能與成長:如何學習新的編程語言和代碼規(guī)范與單元測試

    程序員技能與成長:如何學習新的編程語言和代碼規(guī)范與單元測試

    一名軟件工程師的最大挑戰(zhàn)就是使自己的技術(shù)棧跟得上技術(shù)的發(fā)展,而在這個技術(shù)飛速發(fā)展的時代,保證自己不被淘汰的唯一方法就是不斷學習。 那么,程序員需要掌握多門編程語言嗎?很多初學者都被這個問題所困擾。Google研究總監(jiān) Peter Norvig曾就這個問題給出自己的觀點

    2024年04月10日
    瀏覽(27)
  • 程序員必備算法(詳細)

    程序員必備算法(詳細)

    算法的重要性和應(yīng)用場景: 算法是解決問題的步驟和規(guī)則,它們在計算機科學和軟件開發(fā)中至關(guān)重要。 算法可以提高程序的執(zhí)行效率、降低資源消耗,并改善用戶體驗。 算法應(yīng)用于各個領(lǐng)域,如數(shù)據(jù)處理、圖形圖像處理、網(wǎng)絡(luò)和安全、人工智能等。 程序員需要掌握算法的原

    2024年02月15日
    瀏覽(35)
  • 程序員必備APP

    程序員必備APP

    ? 我在IT界摸爬滾打的也挺長時間了,我看見了挺多的人都想要進入這個行業(yè),之前就有一個小姑娘來問我,如果想要成為程序員的話,需要使用什么軟件,學會什么技能,今天我就就著這個話題 給大家分享一下,程序員應(yīng)該知道的一些應(yīng)用 ,給各位一個小小的參考。 一款

    2023年04月08日
    瀏覽(34)
  • Linux必備基礎(chǔ)命令,JAVA程序員必備

    Linux必備基礎(chǔ)命令,JAVA程序員必備

    目錄 一、了解基本的左側(cè)欄什么意思?編輯 二、ls,ll(list,查找目錄內(nèi)容) 三、cd(change directory,切換目錄) 小技巧,我們在查找東西的時候,可以使用tab進行智能補全。 四、touch(建立文件) echo(打印到控制臺) 五、vim(對文件進行更細粒度的編輯) 六、mkdir(創(chuàng)建目錄

    2024年02月05日
    瀏覽(39)
  • 程序員必備的面試技巧

    “程序員必備的面試技巧,就像是編寫一段完美的代碼一樣重要。在面試戰(zhàn)場上,我們需要像忍者一樣靈活,像偵探一樣聰明,還要像無敵鐵金剛一樣堅定。只有掌握了這些技巧,我們才能在面試的舞臺上閃耀光芒,成為那個令HR們心動的程序猿!” 提醒:在發(fā)布作品前,請

    2024年01月21日
    瀏覽(27)
  • 程序員最重要的技能是啥?

    若論工作中最重要的能力,莫過于甩鍋了。我這么說并不是教人推卸責任,而是團隊協(xié)作中因果都是交織的,沒有孤立的過錯。所以實際很難切割清楚,出現(xiàn)問題,完全就看誰能占據(jù)說理的上風,把責任推給別人。畢竟背鍋的人有很大概率要丟工作的。所以,千萬要小心。吹

    2024年02月02日
    瀏覽(19)
  • 程序員必備的10張流程圖

    程序員必備的10張流程圖

    隨著互聯(lián)網(wǎng)的發(fā)展,現(xiàn)在有越來越多的人想成為程序員。 如果你想成為程序員你可以先問自己這幾個問題? ?你是一個邏輯和抽象思維能力比較強的人嗎? ?你是否愿意不斷地去學習那些新的東西,并且在大多數(shù)時間內(nèi)你都需要去自學。 ?當你遇到一些問題和困難的時候,

    2024年02月07日
    瀏覽(21)
  • C++程序員必備的面試技巧

    C++程序員必備的面試技巧

    ? “程序員必備的面試技巧,就像是編寫一段完美的代碼一樣重要。在面試戰(zhàn)場上,我們需要像忍者一樣靈活,像偵探一樣聰明,還要像無敵鐵金剛一樣堅定。只有掌握了這些技巧,我們才能在面試的舞臺上閃耀光芒,成為那個令HR們心動的程序猿!” 在準備C++程序員面試時

    2024年02月01日
    瀏覽(23)
  • 程序員必備之——代碼托管工具 git

    程序員必備之——代碼托管工具 git

    目錄 一、git的安裝及本地配置 1.1、git介紹 1.2、git本地安裝及配置 1.3、git遠程倉庫 二、git的命令及使用 2.1、基礎(chǔ)命令 三、git的分支 3.1、常用命令 3.2、執(zhí)行效果圖 3.3、合并時有沖突該怎么辦? 3.4、解決沖突 3.5、git分支圖解 四、連接遠程倉庫 4.1、在gitee新建遠程倉庫 4.2、

    2024年02月08日
    瀏覽(40)
  • 【必備】計算機行業(yè)、程序員必備的工具和軟件 拒絕標題黨

    博主并不是廣告推銷 只是分享自己接觸的好用的軟件和工具,所以一切從簡 不會用長篇大論去介紹優(yōu)點。 博主自己的筆記本是在用來辦公的,所以不會去下載一切亂七八糟的東西,這些軟件或工具 要么有自己的官方下載安裝渠道 要么是開源的。 火絨 一個輕量的殺毒軟件,

    2023年04月24日
    瀏覽(42)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包