1. 程式人生 > >【C語言】第二章-分支和迴圈語句-2

【C語言】第二章-分支和迴圈語句-2

第2節

  在本節中,我會用程式碼實現幾個例子,來供大家深入瞭解和學習分支以及迴圈語句。

查詢

  查詢的含義就是在一個表中找出關鍵字與所給值相同的元素,如果找到了則返回下標,找不到則返回-1。   這裡先演示最為普通的查詢,逐個查詢,這是最為普通的演算法思想。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//新增標頭檔案
#include <stdlib.h>
int main()//主函式,函式入口
{
	int index = -1;
	int num = 5;//假設我們要查詢的元素是5
	int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
	for (int i = 0; i < 10; i++)//通過迴圈遍歷陣列
	{
		if (arr[i] == num)
		{
			index = i;//找到目標元素將下標賦值給index
		}
	}
	printf("%d\n", index);
	system("pause");
}

  但是往往這種普通的遍歷查詢過為複雜,因此在有序的陣列中,我們給出第二種更為簡單的查詢方式,叫做**折半查詢,**這種查詢只適用於在有序的素組中,利用減而制之的思想,每次只將目標區域最中心的元素與目標元素(mid)進行對比,如果目標元素大於mid,則將下界更為mid + 1,如果小於mid則將上界改為mid - 1.每一次迴圈之後都將目標查詢區域縮小一半,直到找到目標元素,或是退出迴圈。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//新增標頭檔案
#include <stdlib.h>
/*
二分查詢
引數:陣列,目標區間,目標值
返回值:找到則返回元素下標,未找到返回-1
*/
int binFind(int* arr, int low, int high, int num)
{
	int mid = 0;
	int index = -1;
	while (low <= high)
	{
		mid = (low + high) >> 1;
		if (num > arr[mid])
		{
			low = low + 1;
		}
		else if (arr[mid] > num)
		{
			high = high - 1;
		}
		else
		{
			index = mid;
			break;
		}
	}
	return index;
}
int main()//主函式,函式入口
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	printf("5在陣列中的下表為:%d\n", binFind(arr, 0, 10, 5));
	system("pause");
}

  很顯然這是極為聰明的一種查詢方法,極大的縮短了我們查詢的時間,如果學過資料結構的同學自然可以明白其在演算法分析上的美妙。這兩個查詢的示例也同時讓我們感受到,一樣的目標不一樣的程式編寫方法,會給我們的程式帶來更快的便捷。除此之外,我們還有歸併查詢,抽樣查詢等等,對演算法感興趣的同學可以深入瞭解。

猜數字遊戲

  我相信很多同學小時候可能都會玩過一個遊戲,規則是由系統隨機給出一個數,而我們則在目標區間內進行猜測,知道猜中系統給定的數字為止,那麼今天我們就來實現這麼一個小遊戲。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//新增標頭檔案
#include <stdlib.h>
#include <windows.h>
#include <time.h>
int menu()//開始選單
{
	int choice;//選擇
	printf("1、開始遊戲\n");
	printf("0、退出\n");
	printf("請選擇:");
	scanf_s("%d", &choice);
	return choice;
}
void game()//遊戲主邏輯
{
	srand(time(0));//設定隨機數種子(需要time.h標頭檔案)
	int riddle = 0;//使用者猜的數字
	int num = rand() % 101;//設定隨機數,範圍0 - 100(需要windows.h標頭檔案)
	while (1)
	{
		printf("請輸出你猜的數字:");
		scanf_s("%d", &riddle);
		if (riddle < num)
		{
			printf("低了!\n");
		}
		else if (riddle > num)
		{
			printf("高了!\n");
		}
		else
		{
			break;
		}
	}
	printf("恭喜你猜中了!\n");
}
void gameNumRiddle()//遊戲總邏輯
{
	while (1)
	{
		if (menu() == 1)//呼叫選單函式
		{
			game();//遊戲開始
		}
		else
			return;//退出遊戲
	}
}
int main()//主函式,函式入口
{
	gameNumRiddle();
	system("pause");
}

  在這個遊戲的實現中,我們引入了隨機數rand()的使用方法,rand()是隨機生成一個隨機數列,範圍是0~至少是65535,也就是說如果我們想讓他生成某個範圍內的數,我們就用這個隨機數列%範圍的上界,比如說我們此時需要0 ~ 100的數,我則使用給他% 101,那麼問題來了,rand() % 100 + 1的範圍是多少呢?我相信很多同學或許猜的出來,就是1 ~ 100。是的關於rand()還有很多靈活的用法,大家可以自行琢磨,但是在使用之前都千萬不要忘記加上srand(time(NULL)),那麼這句話又有什麼含義呢?其實很簡單,我們用rand()每次生成的隨機數列都是固定的,就是說如果rand()的引數不變那麼產生的隨機數也不會變,大家在這個程式裡可以試一下,我們如果去掉srand()我們每次執行程式所猜的第一個數字永遠都只會是一個唯一值。並不會改變。為了改變隨機數,我們就要不停地改變引數,但是有什麼引數是會一直改變的?時間。因此我們srand()的引數給的正是時間這個參量。但是time()函式準確的來說並不是返回當前的時間。大家可以去參考這個函式的官方文件。   The value returned generally represents the number of seconds since 00:00 hours, Jan 1, 1970 UTC (i.e., the current unix timestamp). Although libraries may use a different representation of time: Portable programs should not use the value returned by this function directly, but always rely on calls to other elements of the standard library to translate them to portable types (such as localtime, gmtime or difftime).(摘自官方文件)   總的來說我們用srand()和rand()兩個函式創造了隨機數,並且賦值利用迴圈和分支語句讓使用者進行猜數字,整個程式的演算法邏輯還是很簡單的。

ATM系統

  最後是一個ATM的密碼驗證系統,密碼輸入正確則通過,三次錯誤退出系統。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>//新增標頭檔案
#include <stdlib.h>
#include <string.h>
void atmPassword()//ATM登陸系統
{
	char password[7] = "123456";//預設密碼是“123456”
	int turn = 0;
	char enter[7];
	while (turn < 3)//通過迴圈控制三次輸入密碼的機會
	{
		printf("請輸入密碼:");
		scanf("%s", enter);
		if (strcmp(enter, password) == 0)//字串對比函式,如果前後相同返回0
		{
			break;
		}
		turn++;
		printf("密碼輸入錯誤,還有%d次機會!\n", 3 - turn);
	}
	if (turn < 3)
	{
		printf("密碼正確!\n");
	}
	else
	{
		printf("登陸失敗!\n");
	}
}
int main()//主函式,函式入口
{
	atmPassword();
	system("pause");
}

  這個程式的邏輯也十分簡單,其中借用了一個string.h的庫函式字串對比函式int strcmp ( const char * str1, const char * str2 );,這個函式裡有兩個引數,分別是指向兩個字串的指標,如果兩個字串相同返回0,如果前面的字串大於後面的返回大於0的數,反之返回小於0的數,具體比較方法大家也可以去看官方說明文件。   今天舉得幾個例子一是為了熟悉分支與迴圈語句的使用,二是說明一個道理,只憑我們自己手寫是無法快捷的寫出程式碼的,因此我們有時需要藉助C語言貧瘠的庫函式,而使用庫函式的具體方法大家一定要多去官方文件檢視,看得久了對英文有幫助,同時也可以是我們對庫函式的使用有更深的理解。