宣告:由于作者水平有限,本文難免有錯誤和不準確之處,本人也很想知道這些錯誤,懇望讀者批評指正,
【聯系方式】1583598623@qq.com
【更新記錄】2021年4月11日(第一次更新 )
【勘誤記錄】暫無
1.看一個有趣的getchar程式段,還未輸入Y/N,回車鍵一敲立刻顯示確認失敗!why?
int main()
{
char password[20]= { 0 };
printf("請輸入密碼:>");
scanf("%s", password);
printf("確認密碼(Y/N:>");
int ch = getchar();
//字符運算式也算是整形運算式,因為字符存盤和運算的時候,都是ASCII碼值,
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;
}

因為scanf、getchar這類輸入函式,都是從輸入緩沖區當中讀取,不是直接從鍵盤讀取,在上例中,鍵盤敲入“123456\n”(這里\n對應回車鍵),123456被scanf拿走,\n很自然的被getchar拿走放到ch內,所以并沒有等待讓我們輸入Y/N,
所以,如何處理??? 加一個getchar把回車讀走即可,但是真的足夠嗎?
int main()
{
char password[20]= { 0 };
printf("請輸入密碼:>");
scanf("%s", password);
printf("確認密碼(Y/N:>");
//清理緩沖區
getchar();
int ch = getchar();
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;
}

輸入123456\n沒有問題,但是輸入123 456再次不行,why?

因為一個getchar()只能處理掉一個快取區字符,一個空格就消耗掉了,可以考慮加個回圈,
int main()
{
char password[20]= { 0 };
char tmp;
printf("請輸入密碼:>");
scanf("%s", password);
printf("確認密碼(Y/N:>");
//清理緩沖區
//getchar();
while ((tmp = getchar()) != '\n')
{
;
}
int ch = getchar();//注意是int
if (ch == 'Y')
{
printf("確認成功\n");
}
else
{
printf("確認失敗\n");
}
return 0;
}

2.對比for回圈中的break和continue,for回圈中的continue直接跳到調整部分,與while中的continue(可能死回圈)有所不同,
int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
break;
printf("%d", i);
}
}

int main()
{
int i = 0;
for (i = 1; i <= 10; i++)
{
if (i == 5)
//break;
continue;
printf("%d", i);
}
}

3.小心代碼的省略
程式段1
int main()//輸出9個hehe
{
int i = 0;
int j = 0;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("hehe\n");
}
}
return 0;
}
程式段2
int main()//只輸出3個hehe,因為內部for回圈里j第二次回圈就沒有被初始化
{
int i = 0;
int j = 0;
for (; i < 3; i++)
{
for (; j < 3; j++)
{
printf("hehe\n");
}
}
return 0;
}
4.請問如下回圈分別回圈幾次?
int main()
{
int i = 0;
int k = 0;
for (i = 0; k = 0; i++, k++)//回圈0次,k=0為假
{
k++;
printf("%d", k);
}
return 0;
}
int main()
{
int i = 1;
do
{
if (i == 5)
continue;//continue導致輸出前四個數后便死回圈
printf("%d", i);
i++;
} while (i <= 10);
return 0;
}
5.(二分法)在一個有序陣列中查找具體的某個數字n
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;//要查找的數字
int sz = sizeof(arr) / sizeof(arr[0]);//陣列的元素個數
int left = 0;
int right = sz - 1;//為什么減一,因為第一個從0開始,減一后才是最右邊元素下標
while (left<=right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;//加一減一畫下圖就明白
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("找到了%d", mid);
break;
}
}
if (left > right)
printf("找不到了\n");
return 0;
}
6.實作輸出逐漸顯示"welcome to China"
int main()
{
char arr1[] = "welcome to China!!!!";
char arr2[] = "####################";
int left = 0;
int right = strlen(arr1) - 1;
while (left <= right)
{
arr2[left] = arr1[left];
arr2[right] = arr1[right];
printf("%s\n", arr2);
Sleep(1000);
left++;
right--;
}
return 0;
}

7.假設正確密碼是字串"123456",驗證密碼的正確性
int main()
{
int i = 0;
char password[20] = { 0 };
for (i = 0; i < 3; i++)
{
printf("請輸入密碼:>");
scanf("%s", password);
//不需要特地加取地址符,因為作為陣列,陣列名就是地址
//if(password=="123456"); 錯誤,倆字串不能直接比較,參考strcmp
if (strcmp(password, "123456") == 0)
{
printf("登陸成功\n");
break;
}
}
if (i >= 3)
printf("密碼錯誤三次,已鎖定");
return 0;
}
8.猜數游戲實作:自動產生一個1-100的亂數,猜數字,會提示你猜大還是猜小,知道猜對了停止
void menu()
{
printf("*********************************\n");
printf("*************1. play ***********\n");
printf("*************0. exit ***********\n");
printf("*********************************\n");
}
void game()
{
//時間戳time()
int ret = rand()%100+1;//%100的余數是0-99,然后+1,范圍就是1-100
//printf("%d\n", ret);
//猜數字
int guess = 0;
while (1)
{
printf("請猜數字:>");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\b");
}
else
{
printf("恭喜你猜對了\n");
break;
}
}
}
int main()
{
int input = 0;
srand((unsigned int) time(NULL));
do
{
menu();
printf("請選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戲\n");
break;
default:
printf("選擇錯誤,重選\n");
break;
}
} while (input);
return 0;
}

9.撰寫程式數一下 1到 100 的所有整數中出現多少個數字9,需要注意有兩部分組成,個位數的9和十位數的9.
int main()
{
int i = 1;
int a = 0;
for (i = 1; i <= 100; i++)
{
if (i % 10 == 9)
a++;
if (i/10 == 9)
a++;
}
printf("一共有%d個數字九",a);
return 0;
}
10.計算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,列印出結果
int main()
{
float i = 1;
float ret = 1;
int x = 1;
float sum = 0;
for (i = 1; i <= 100; i++)
{
ret = x * i;
sum += 1 / ret;
x = -x;
}
printf("1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值為%lf", sum);
return 0;
}
11.求十個整數中最大值
int main()
{
int arr[10] = { 0 };
int i = 0;
int max = 0;
for (i = 0; i < 10; i++)
scanf("%d", &arr[i]);
max = arr[0];
for (i = 0; i < 10; i++)
if (arr[i] > max)
max = arr[i];
printf("最大值是%d", max);
return 0;
}
12.在螢屏上輸出9*9乘法口訣表
int main()
{
int i = 1;
int j = 1;
for (i = 1; i < 10; i++)
{
printf("\n");
for (j = 1; j <= i; j++)
printf("%d*%d=%2d ", i, j, i * j);//%2d用于對齊美觀
}
return 0;
}
13.(補充上面第5點二分查找內容)
撰寫代碼在一個整形有序陣列中查找具體的某個數
要求:找到了就列印數字所在的下標,找不到則輸出:找不到,
/*
二分查找:
在一個有序的序列中,找某個資料是否在該集合中,如果在列印該資料在集合中的下標,否則列印找不到
具體找的方式:
1. 找到陣列的中間位置
2. 檢測中間位置的資料是否與要查找的資料key相等
a: 相等,找到,列印下標,跳出回圈
b: key < arr[mid], 則key可能在arr[mid]的左半側,繼續到左半側進行二分查找
c: key > arr[mid], 則key可能在arr[mid]的右半側,繼續到右半側進行二分查找
如果找到回傳下標,否則繼續,直到區間中沒有元素時,說明key不在集合中,列印找不到
易錯點:
1. right的右半側區間取值,該值決定了后序的寫法
2. while回圈的條件是否有等號
3. 求中間位置的方法,直接相加除2容易造成溢位
4. 更改left和right的邊界時,不確定是否要+1和-1
*/
// 方法一,采用[left, right] 區間
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int key = 3;
int left = 0;
int right = sizeof(arr)/sizeof(arr[0])-1; // right位置的資料可以取到
while(left<=right) // right位置有資料,必須要添加=號
{
int mid = left+(right-left)/2;
if(arr[mid]>key) // key小于中間位置資料,說明key可能在左半側,需要改變右邊界
{
right = mid-1; // right位置的資料可以取到,因此right=mid-1
}
else if(arr[mid]<key)// key大于中間位置資料,說明key可能在右半側,需要改變左邊界
{
left = mid+1; // left位置的資料可以取到,因此left=mid+1
}
else
{
printf("找到了,下標是:%d\n", mid);
break;
}
}
if(left>right)
printf("找不到\n");
return 0;
}
// 方法二,采用[left, right) 區間
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int key = 3;
int left = 0;
int right = sizeof(arr)/sizeof(arr[0]); // right位置的資料取不到
while(left<right) // right位置沒有資料,此處不需要添加=
{
int mid = left+(right-left)/2;
if(arr[mid]>key) // key小于中間位置資料,說明key可能在左半側,需要改變右邊界
{
right = mid; // right位置的資料取不到,因此right=mid,不需要減1
}
else if(arr[mid]<key)// key大于中間位置資料,說明key可能在右半側,需要改變左邊界
{
left = mid+1; // left位置的資料可以取到,因此left=mid+1
}
else
{
printf("找到了,下標是:%d\n", mid);
break;
}
}
if(left>=right)
printf("找不到\n");
return 0;
}
int key = 3;
int left = 0;
int right = sizeof(arr)/sizeof(arr[0]); // right位置的資料取不到
while(left<right) // right位置沒有資料,此處不需要添加=
{
int mid = left+(right-left)/2;
if(arr[mid]>key) // key小于中間位置資料,說明key可能在左半側,需要改變右邊界
{
right = mid; // right位置的資料取不到,因此right=mid,不需要減1
}
else if(arr[mid]<key)// key大于中間位置資料,說明key可能在右半側,需要改變左邊界
{
left = mid+1; // left位置的資料可以取到,因此left=mid+1
}
else
{
printf("找到了,下標是:%d\n", mid);
break;
}
}
if(left>=right)
printf("找不到\n");
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/275081.html
標籤:其他
下一篇:線性查找
