[C]第二章--分支語句與迴圈語句(2)--實戰演練
阿新 • • 發佈:2018-12-22
分支語句與迴圈語句
只有在實際應用中才可以感受到分支與迴圈語句的微妙之處.
以下列舉幾個筆者練習過的比較經典的例題.
拉門簾
要求:
- 編寫程式碼,演示多個字元從兩端移動,向中間匯聚.達到拉門簾的效果.
#include<stdio.h> #include<stdlib.h> #include <Windows.h> #include <string.h> int main(){ char arr1[] = "I like C programming!";//被掀開的內容 char arr2[] = "#####################";//掀開前的內容 int left = 0; int right = strlen(arr1) - 1; printf("%s\n", arr2); //接下面程式碼
- while 實現
while (left <= right) {
//需要包含標頭檔案<windows.h>
Sleep(1000);//可有可無,不過加上會有動態效果
arr2[left] = arr1[left];
arr2[right] = arr1[right];
++left;
--right;
printf("%s\n", arr2);
}
system("pause");
return 0;
}
- for 實現
for(left = 0,right = strlen(arr1) - 1;left <= right;++left,++right){
Sleep(1000);
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n",arr2);
}
system("pause");
return 0;
}
ATM機登入介面
int main(){
char pas[1024] = "";//使用者輸入的密碼
char password[] = "123456";
int i = 0;
int j = 0;
for (i = 0; i < 3; ++i) {
printf("請輸入密碼:\n");
scanf("%s", pas);
if (strcmp(pas, password) == 0) {
break;
}
}
//迴圈結束的情況只有兩種
//1.輸錯三次,不滿足i < 3,登入失敗.
//2.輸入了正確的密碼,登陸成功.
if (i == 3) {
printf("輸入錯誤三次,退出\n");
}
else {
printf("登陸成功!\n");
}
system("pause");
return 0;
}
注:
- 字串比大小遵循的是字典序
若第一個引數等於第二個引數,返回0.
若第一個引數小於第二個引數,返回負數.
若第一個引數大於第二個引數,返回正數.
從第一個元素向後判斷. - 字串比較的是兩個字串首地址是否相同,之後詳解.
折半查詢(二分查詢)
先要明晰查詢該如何實現:
int main(){
int xiabiao;
int num = 7;//查詢的元素
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 ,10};
for (int i = 0; i < 10; i++){
if (num == arr[i]){
xiabiao = i;//找到目標元素將下標賦值給index
}
}
printf("%d\n", xiabiao);
system("pause");
}
這樣做太過於繁瑣,需要將索引值與 陣列中所有值進行比較,直到找到那個值或者全部判斷完沒有這個值才結束,時間複雜度很大,那麼就引入了簡化的折半查詢.
函式體中的折半查詢:
int main(){
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int left = 0;
int right = sizeof(arr) / sizeof(arr[0]) - 1;
int to_find = 7;
int mid = 0;
while (left <= right) {
mid = (left + right) / 2;
if (arr[mid] > to_find) {
right = mid - 1;
}
else if (arr[mid] < to_find) {
left = mid + 1;
}
else
break;
}
if (left <= right) {
printf("找到了,下邊是%d\n", mid);
}
else
printf("沒找到.\n");
system("pause");
return 0;
}
實現一個折半查詢的函式:(函式定義中實現)
int search(int arr[],int left,int right,int to_find){
int mid = 0;
while(left <= right){
mid = (left + right) >> 1;
//等價於mid = (left + right) / 2;
if(arr[mid] > to_find){
right = mid - 1;
}
else if(arr[mid] < to_find){
left = mid + 1;
}
else
return mid;
}
return -1;
//找不到的話返回-1;
}
其實折半查詢的思維很簡單,就是把兩側值(最大與最小值)的平均值作為中值和要找的值進行對比,
- 如果要找的值大於中值,說明需要找的值在這個中值右邊,左半邊就不需要查找了,所以重新規劃範圍,將最左值更新為mid + 1,重新進行下一次查詢.
- 如果要找的值小於中值,說明需要找的值在這個中值左邊,右半邊就不需要查找了,所以重新規劃範圍,將最右值更新為mid - 1,重新進行下一次查詢.
注:
- 整形陣列可以通過
sizeof(arr) / sizeof( arr[0] )
的方式確定陣列中有多少元素. - 這個查詢的陣列必為有序陣列,不然無法實現.
猜數字
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
void menu() {
printf("----------------\n");
printf("----歡迎遊戲----\n");
printf("----開始:1-----\n");
printf("----退出:2-----\n");
printf("----------------\n");
printf("----請選擇:----\n");
}
void game() {
int random_num = rand() % 100 + 1;//保證在1~100範圍之內
int input = 0;
while (1) {
printf("請輸入猜的數字:\n");
scanf("%d", &input);
if (input > random_num) {
printf("猜大了!\n");
}
else if (input < random_num) {
printf("猜小了!\n");
}
else {
printf("猜對了,恭喜你!\n");
break;
}
}
}
int main(){
int input = 0;
srand((unsigned)time(0));//設定隨機種子,需要包含標頭檔案<time.h>
do {
menu();
scanf("%d", &input);
switch (input) {
case 1:
game();//開始遊戲
break;
case 0://退出遊戲
break;
default:
printf("輸入錯誤,重新輸入!\n");
break;
}
} while (input);
system("pause");
return 0;
}
srand((unsigned)time(0));
這句設定隨機種子的語句需要詳細解讀一下
- srand() 函式是隨機數發生器的初始化函式,要想讓其產生隨機數,那麼裡面的引數就要是隨機值.
- time(0) 想想現實生活中什麼是隨機的?最常見的就是時間,所以在這裡引入時間戳的概念.
(簡單來說就是從格林威治時間1970年1月1日與現在時間的秒數之差)
所以這個time(0)就獲取了當前時間的時間戳,引入srand函式 - (unsigned)
因為time(0)時間戳返回的是一個time_t,也就是long int型別的資料(64位整數),而srand返回的是32位整數,轉換時會發生精度丟失,所以這裡用一句強制型別轉換的語句unsigned (int),保證精度對齊.
而 random_num = rand() % 100 + 1;
是如何保證取值範圍在1~100之間的呢?
rand()函式生成的隨機值與100取模就保證了資料範圍在0~99之間
再給資料集加上1,所以範圍約束在了1~100之間了
關機小程式
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(){
char input[10] = { 0 };
system("shutdown -s -t 60");
again:
printf("電腦將在1分鐘內關機,如果輸入:我是豬,就取消關機!\n請輸入:\n");
scanf("%s", input);
if (strcmp(input, "我是豬") == 0) {
system("shutdown -a");
}
else {
goto again;
}
system("pause");
return 0;
}
一個簡單的惡搞小程式,利用goto與標籤跳轉結合的方式實現.
需要注意的是:
- 因為這裡輸入的時候,輸入介面無法輸入漢字字元,所以只能通過複製貼上的方式實現輸入,而且不可以通過
ctrl + v
的方式進行貼上,只能右鍵點選 -> 貼上.
解決方案:可以通過讓使用者輸入i am a pig
等效替代 - 這裡運用了系統指令system( )語句,可以控制PC機開關機,是不是感覺打開了新世界的大門?其實你也可以把程式碼編輯器看做一個控制檯,這就和cmd指令控制是一樣的,其他的功能有需要的同學可以自行百度~~