C語言中的分支語句(if語句)

if…else語句

程序在執行的時候都是一行一行執行的,例如下面這行代碼:

#include <stdio.h>			//頭文件
#include <windows.h>

void main()					//程序入口
{
	int x = 10;				//賦值
	int y = 20;
	printf("x>y \n");		//輸出結果

	return;					//程序結束
}

如果我們想要讓程序按照我們的意思來執行,就要使用兩個語句:一個是分支語句(if),一個是循環語句(while),這篇文章主要說一下if語句。

if語句格式:

if(表達式)
	語句;
else
	語句;

或者

if(表達式)
{
	語句1;
	語句2;
}
else
{
	語句1;
	語句2;
}

例子:

#include <stdio.h>			//頭文件
#include <windows.h>

void main()					//程序入口
{
	int x = 10;				//賦值
	int y = 20;
	
	if(x>y)					//進行判斷
	printf("x>y \n");		//輸出判斷結果
	else					//若不符合上面的判斷條件輸出下面的結果
	printf("x<y \n");

	return;					//程序結束
}

運行結果:
在這裏插入圖片描述
或者:

#include <stdio.h>					//頭文件
#include <windows.h>

void main()							//程序入口
{
	int x = 10;						//賦值
	int y = 20;
	
	if(x>y)							//進行判斷
	{		
		printf("*****計算結果爲*****\n");		//輸出判斷結果
		printf("x>y \n");		
	}
	else							//若不符合上面的判斷條件輸出下面的結果
	{
		printf("*****計算結果爲*****\n");
		printf("x<y \n");
	}


	printf("程序結束!\n");			//輸出結束語
	return;							//程序結束
}

if…else if…else if…else

這個就比較複雜了,如果第一次判斷不成立,那麼就會進行第二次判斷、第三次判斷等等,如果都不成立,那麼就會輸出else的語句。

格式

if(表達式)
{
	語句1;
}
else if(表達式)
{
	語句2;
}
else if(表達式)
{
	語句3;
}
else
{
	語句4;
}

例子:

#include <stdio.h>			//頭文件
#include <windows.h>

void main()					//程序入口
{
	int x = 10;				//變量賦值

	if(x>11)				//第一次判斷
	{
		printf("A \n");		//若成立輸出語句
	}
	else if(x<10)			//第二次判斷
	{
		printf("B \n");		//若成立輸出語句
	}
	else if(x=10)			//第三次判斷
	{
		printf("C \n");		//若成立輸出語句
	}
	else					//若前三次判斷都不成立,輸出else語句
	{
		printf("D \n");
	}


	printf("程序結束! \n");	//輸出結束語
	return;					//程序結束
}

運行結果:
在這裏插入圖片描述

if語句嵌套

格式

if(表達式)
{
	if...
}
else
{
	if..
}

這裏舉一個例子,要求實現輸出三個數中的最大數:

#include <stdio.h>				//頭文件
#include <windows.h>

int Max(int x,int y,int z)		//定義函數Max
{
	 int r = 0;					//定義一個可以儲存返回值的變量r

	if(x>y)						//判斷若成立執行下面的if語句
	{
		if(x>z)					//若成立把值賦給r
		{
			r = x;
		}
		else					//否則執行else語句
		{
			r = z;				//把值賦給r
		}
	}
	else						//若上面的都不成立則執行else語句
	{
		if(y>z)					//同上
		{
			r = y;
		}
		else
		{
			r = z;
		}
	}

	return r;					//把值返回到r裏
}

void main()						//程序入口
{
	int	key = Max(1,2,3);		//往函數裏傳參數
	
	printf("最大數爲:%d\n",key);		//輸出最終結果				
	
	return;						//程序結束
}

運行效果:
在這裏插入圖片描述

從底層分析if語句

我們看一下if語句在彙編裏究竟是怎麼實現的,先上一段代碼:

#include <stdio.h>				//頭文件
#include <windows.h>

void main()						//程序入口
{
	int x = 10;					//賦值
	int y = 20;

	if(x>y)						//執行判斷
	{
		printf("x>y");			//輸出結果
	}
	else						//判斷不成立執行else語句
	{
		printf("x<y");			//輸出結果
	}
					
	return;						//程序結束
}

這是它的彙編代碼:
在這裏插入圖片描述
先分析if語句

if(x>y)
{
	printf("x>y");
}

彙編指令:

mov         eax,dword ptr [ebp-4]	//把10傳到eax裏
cmp         eax,dword ptr [ebp-8]	//10與20進行比較
jle         main+3Dh (0040d73d)		//若結果小於等於則跳轉
push        offset string "x>y" (0042201c) //壓入字符串
call        printf (00401070)		//調用printf()函數
add         esp,4					//外平棧進行堆棧平衡

這裏明顯會跳,10小於20,這裏如果跳的話,就跳到這段else代碼了:

else
{
	printf("x<y");
}

彙編指令:

jmp         main+4Ah (0040d74a)		//無條件跳轉,這裏不會跳,因爲上面的jie跳過它了
push        offset string "%d\n" (00422fb4)	//壓入字符串
call        printf (00401070)		//調用printf()函數
add         esp,4					//外平棧進行堆棧平衡

程序運行到else就會輸出結果到控制檯了,這裏主要是體會jie與jmp的邏輯關係,jie實現了跳轉,程序就會輸出x<y,如果沒有執行跳轉,那麼就會輸出x<y,然後跳過else語句,假如這是一個註冊機制的話,那這裏就是一個突破口。

逆一下自己的程序

還是以這段代碼爲例,這裏明明10小於20,我們讓它輸出x>y,也就是10>20。

#include <stdio.h>				//頭文件
#include <windows.h>

void main()						//程序入口
{
	int x = 10;					//賦值
	int y = 20;

	if(x>y)						//執行判斷
	{
		printf("x>y");			//輸出結果
	}
	else						//判斷不成立執行else語句
	{
		printf("x<y");			//輸出結果
	}
					
	return;						//程序結束
}

我們先在斷尾下斷,不然程序閃一下就沒了,然後搜一下關鍵字來到程序判斷的地方。

在這裏插入圖片描述
我們把這裏的jle改爲je,也就是相等時則跳轉,這裏明顯不相等,所以不會挑。

在這裏插入圖片描述
然後單步往下走,看下結果:
在這裏插入圖片描述
這樣就成功的讓10>20了,下面的else語句也在程序執行到jmp指令的時候跳過了。如果這段代碼是實現充值或者註冊的話,結果就可想而知了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章