目錄
分支循環語句
單分支
多分支
switch 分支語句
牛刀小試
判斷一個數是否是奇數
輸出 1-100之間?的奇數
計算 n 的階乘?
計算 1! + 2! + 3!?... + n!
在一個有序數組中查找具體的某一個數字?
打印 100-200 之間的素數
求兩個整數的最大公約數
getchar函數 和 putchar函數
getchar 函數
putchar 函數
代碼模擬實現用戶創建密碼場景
代碼模擬實現用戶登錄賬號場景,并且只能登錄三次?
猜數字游戲
實現要求
代碼實現
代碼解析
goto 語句
利用 goto語句 寫一個電腦關機程序
分支循環語句
單分支
單 if 語句:
int age = 0;
scanf("&d", &age);if (age >0 && age < 18)printf("未成年\n");
單 if else 語句:
int age = 0;
scanf("&d", &age);if (age >0 && age < 18)printf("未成年\n");
elseprintf("成年\n");
多分支
int age = 0;
scanf("&d", &age);if (age > 0 && age < 18)printf("青少年\n");
else if (age >= 18 && age < 30)printf("青年\n");
else if (age >= 30 && age < 50)printf("中年\n");
else if (age >= 50 && age < 70)printf("中老年\n");
else if (age >= 70 && age < 90)printf("老年\n");
elseprintf("老壽星\n");
注意:當條件判斷語句里是多條語句時,需要用大括號括起來
switch 分支語句
代碼演示:
int day = 0;
scanf("%d", &day);switch (day)
{
case 1:printf("星期一\n");break;
case 2:printf("星期二\n");break;
case 3:printf("星期三\n");break;
case 4:printf("星期四\n");break;
case 5:printf("星期五\n");break;
case 6:printf("星期六\n");break;
case 7:printf("星期七\n");break;
default:printf("輸入錯誤");break;
}return 0;
switch 的括號中只能是整型變量表達式,case 后面只能跟整型常量
每一個 case 下面的代碼執行完成后最好加上 break,否則就會一直往下執行
default 類比 if else 語句中的 else ,當所有 case 都不匹配的時候就會執行 default 下面的代碼
牛刀小試
判斷一個數是否是奇數
代碼演示:
int input = 0;
scanf("%d", &input);if (input % 2 == 1)printf("是奇數\n");
elseprintf("不是奇數\n");
任意一個奇數除以 2 之后的余數都是 1,所以利用 % 取模上 2 判斷余數是否為 1,是 1 就是奇數,否則就不是?
輸出 1-100之間?的奇數
代碼演示(方法1):
for (int i = 1; i <= 100; i++)
{if (i % 2 == 1)printf("%d ", i);
}
同樣是通過 % 取模關鍵字來判斷
代碼演示(方法2):?
for (int i = 1; i <= 100; i+=2)
{printf("%d ", i);
}
在 for 循環的條件中直接控制變量 i 只輸出奇數,這樣就不用 if 判斷?
計算 n 的階乘?
代碼演示:
int n = 0;
scanf("%d", &n);int factorial = 1;for (int i = 1; i <= n; i++)
{factorial = factorial * i;
}printf("%d! = %d\n",n, factorial);
通過循環列舉出 1-n 的值,并把它們的乘積累計到 factorial 變量中,最后?factorial 變量就是 n 的階乘
代碼驗證:
計算 1! + 2! + 3!?... + n!
代碼演示:
int n = 0;
scanf("%d", &n);int factorial = 1;
int sum = 0;for (int i = 1; i <= n; i++)
{factorial = factorial * i;sum = sum + factorial;
}printf("%d\n", sum);
把每個數的階乘累加在一起,就是?1! + 2! + 3!?... + n!
代碼驗證:
在一個有序數組中查找具體的某一個數字?
代碼演示:
int arr[] = { 1,3,4,6,8,9,11,24,33,54,66 };printf("請輸入要查找的數:");
int input = 0;
scanf("%d", &input);int right = sizeof(arr) / sizeof(arr[0]) - 1;
int left = 0;while (left <= right)
{int mid = (right + left) / 2;if (input > arr[mid]){left = mid + 1;}else if (input < arr[mid]){right = mid - 1;}else{printf("找到了,下標是:%d\n", mid);break;}
}if (left > right)
{printf("查找的數不存在\n");
}
此題利用的是二分查找算法,二分查找法的應用需以有序數組為前提,其核心步驟與流程如下:
- 初始化與定位:設定數組左右邊界下標
left
和right
,據此計算中間元素下標mid
,以獲取數組中間值。 - 比較與邊界調整:將待查找元素與中間值進行比較:
- 若待查找元素大于中間值,則將左邊界
left
更新為mid + 1
,縮小查找范圍至數組右半部分; - 若待查找元素小于中間值,則將右邊界
right
更新為mid - 1
,縮小查找范圍至數組左半部分。
- 若待查找元素大于中間值,則將左邊界
- 迭代與終止:在
left <= right
的循環條件下,持續更新mid
,并重復比較操作。當找到目標元素時,循環終止;若循環條件不再滿足,即left > right
,則表明數組中不存在目標元素,查找結束。
打印 100-200 之間的素數
代碼演示:
int main()
{for (int i = 101; i <= 200; i+=2){int flag = 1;for (int j = 2; j < sqrt(i); j++){if (i % j == 0){flag = 0;break;}}if (flag)printf("%d ", i);}return 0;
}
代碼解析:
素數又稱質數,它的特征是只能被 1 和它本身整除。例如 11,只能被 1 和 11 整除,2 到 10 都無法整除它。 由于偶數除了能被 1 和自身整除外,還能被 2 整除,所以偶數一定不是素數(2 除外,但本題范圍不涉及 2)
若要找出 100 到 200 之間的素數,可先排除偶數,使用 for 循環從 101 開始遍歷,每次遞增 2,以此避免對偶數進行判斷。 判斷一個數是否為素數時,可采用以下方法:在外部 for 循環遍歷每個待判斷的數,對每個數再用一個內部 for 循環來檢查它是否能被其他數整除
以判斷 102 為例,在內部 for 循環中,讓 102 依次對 2 到 100 之間的數取模。若存在一個數取模結果為 0,就表明 102 不是素數;若所有取模結果都不為 0,則 102 是素數。為方便判斷,可定義一個變量 flag 并初始化為 1,若取模結果為 0,就將 flag 賦值為 0 并跳出內部循環。當內部循環結束后,只需判斷 flag 的值,若為 1 則該數是素數,直接打印;若為 0 則不是素數
此外,內部 for 循環的范圍可優化。不需要從 2 遍歷到待判斷的數減 1,只需從 2 遍歷到該數平方根(sqrt 函數用于計算平方根)即可。因為若一個數 x 能寫成 x = m * n 的形式,那么 m 和 n 中至少有一個小于等于 sqrt(x)。這樣能減少不必要的計算,提高效率
求兩個整數的最大公約數
代碼演示:
int main()
{int m = 0;int n = 0;scanf("%d %d", &m, &n);int k = 0;while (k = m % n){m = n;n = k;}printf("%d\n", n);return 0;
}
代碼解析:
要求兩個整數的最大公約數,可以使用輾轉相除法,這種方法高效且原理巧妙。下面詳細解釋其計算過程
以兩個整數?m=24?和?n=18?為例,輾轉相除法的操作步驟如下:
- 計算?m?除以?n?的余數,將這個余數賦值給變量?k。在這個例子中,24%18=6,所以?k=6。
- 判斷?k?的值是否為?0。如果?k?不為?0,就把?n?的值賦給?m,把?k?的值賦給?n。在本例中,執行這一步后,m?變為?18,n?變為?6。
- 重復上述步驟,也就是持續進行?k=m%n?的計算,然后更新?m?和?n?的值(m=n;n=k),直到?k?的值為?0。
- 當?k?為?0?時,此時?n?的值就是?m?和?n?的最大公約數
輾轉相除法是一種非常實用的算法,它的核心在于巧妙地利用了余數的性質。每次用較大數除以較小數取余,再用除數和余數繼續這個過程,不斷縮小問題的規模。這樣一來,原本復雜的求最大公約數問題,就通過不斷迭代轉化為一個簡單的問題,避免了對大量可能的公約數進行逐一嘗試,從而顯著提高了計算效率。而且,這種算法邏輯清晰、代碼實現簡單,在實際應用中十分高效?
getchar函數 和 putchar函數
getchar 函數
getchar 函數的作用是從鍵盤上接收一個字符,當接收成功后的返回值是字符的 ASCLII 碼值,接收失敗就會返回 EOF
putchar 函數
putchar 函數的作用是把傳遞的參數打印在屏幕上,比如 putchar('w'); 那么屏幕上就會出現 w 字符
代碼模擬實現用戶創建密碼場景
char password[20] = { 0 };printf("請輸入密碼:");
scanf("%s", password);// 清空緩沖區
while (getchar() != '\n');char input = 0;
printf("請確認密碼(Y/N):");
scanf("%c", &input);if (input == 'Y')printf("確認成功\n");
else if (input == 'N')printf("退出確認\n");
elseprintf("確認失敗\n");return 0;
scanf 函數和 getchar 之類的接收數據函數,并不是從鍵盤上直接接收數據,而是從輸入緩沖區中拿數據,而從鍵盤上輸入的數據沒有被拿之前都是被存放在輸入緩沖區的
而 scanf 函數只會拿 '\n' 或者空格之前的字符,所以要利用 getchar 把緩沖區中多余的字符清理掉
代碼模擬實現用戶登錄賬號場景,并且只能登錄三次?
實現要求:
編寫代碼實現模擬用戶登錄賬號場景,并且只能登錄三次,只允許輸入三次密碼,如果密碼正確則提示登錄成功,如果三次均輸入錯誤,則退出程序
代碼演示:
char password[] = "123456";
char input_password[] = " ";int chance = 0;while (chance < 3)
{printf("請輸入密碼:");scanf("%s", input_password);if (strcmp(input_password, password) == 0){printf("登錄成功\n");break;}else{printf("密碼錯誤\n");chance++;}
}if (chance == 3)printf("登錄失敗,退出程序\n");return 0;
strcmp
?函數的作用是比較兩個字符串的大小關系,其返回值規則如下:
- 若返回?
0
:表示兩個字符串完全相等(每個對應位置的字符都相同) - 若返回正數:表示第一個字符串大于第二個字符串。比較邏輯是從左到右逐個字符對比,直到找到第一個不相同的字符,此時第一個字符串中該位置字符的 ASCII 碼值大于第二個字符串對應位置字符的 ASCII 碼值
- 若返回負數:表示第一個字符串小于第二個字符串,原理同上,即第一個不相同字符的 ASCII 碼值小于第二個字符串對應字符的 ASCII 碼值
簡言之,strcmp
?通過逐個字符比較 ASCII 碼值來判斷字符串的大小關系,返回值直接體現兩者的大小或相等關系
猜數字游戲
實現要求
編寫一個猜數字游戲程序,讓用戶猜測程序隨機生成的 1 - 100 之間的整數
-
開始與退出控制:程序啟動后,提示用戶輸入指令。輸入?
1
?開始新的一輪猜數字游戲;輸入?0
?則直接退出程序;若輸入其他非 0 非 1 的整數,提示用戶重新輸入 -
猜數字過程:當用戶輸入?
1
?開始游戲后,程序隨機生成一個 1 - 100 之間的整數作為目標數字。用戶輸入猜測的數字,程序根據用戶輸入給出相應提示:- 若猜測的數字大于目標數字,提示 “猜大了”。
- 若猜測的數字小于目標數字,提示 “猜小了”。
- 若猜測的數字等于目標數字,提示 “猜對了”,此輪游戲結束,再次回到開始界面等待用戶輸入指令(
1
?開始新游戲,0
?退出程序等)。
-
重復游戲:在一輪游戲結束后,用戶可根據自身意愿,通過輸入?
1
?繼續開啟新的一輪游戲,或輸入?0
?退出程序。
代碼實現
void menu()
{printf("**********************************************\n");printf("***** 1. play 0. nxit *****\n");printf("**********************************************\n");
}void game()
{printf("\n----------- 猜數字游戲開始 -----------\n");int input = 0;int Random_number = rand() % 100 + 1;while (1){printf("請輸入你猜的數字:");int ret = scanf("%d", &input);if (input > Random_number){printf("猜大了\n");}else if (input < Random_number){printf("猜小了\n");}else{printf("恭喜你,猜中了!!!\n");break;}}printf("----------- 猜數字游戲結束 -----------\n\n");}int main()
{int input = 0;srand((unsigned int)time(NULL));do{menu();printf("\n請輸入(1 or 0):");scanf("%d", &input);if (input == 1){game();}else if(input == 0){printf("退出游戲\n");}else{printf("輸入錯誤,請重新輸入\n");}} while (input);return 0;
}
代碼解析
代碼 1:srand((unsigned int)time(NULL));
srand
?函數用于初始化隨機數生成器的種子。在 C 語言里,若不設定種子,rand
?函數每次運行程序時產生的隨機數序列都是相同的
time(NULL)
?會返回當前的時間戳,即從特定起始時間到現在所經過的秒數。由于時間是持續變化的,將?time(NULL)
?的返回值強制轉換為?unsigned int
?類型后作為?srand
?函數的參數,就可以讓隨機數生成器的種子在每次運行程序時都不同
這樣,后續調用?rand
?函數就能生成不同的隨機數序列,實現真正意義上的 “隨機”
代碼 2:int Random_number = rand() % 100 + 1;
rand
?函數用于生成隨機整數。不過,它默認生成的是一個較大范圍的隨機數,且每次運行程序時的隨機數序列依賴于?srand
?函數設定的種子。若要生成 1 到 100 之間的隨機整數,可以通過取模運算和加法運算來實現
rand() % 100
?會對?rand
?函數生成的隨機數取模 100,得到的結果范圍是 0 到 99。在此基礎上再加 1,最終得到的隨機數范圍就是 1 到 100。代碼將這個 1 到 100 之間的隨機數賦值給整型變量?Random_number
goto 語句
goto 語句介紹:
在C語言里,`goto` 語句能讓程序執行流程跳轉到指定的標簽處。使用時,要先定義一個標簽,格式為“標簽名:”,接著就能用 `goto` 標簽名; 來跳轉。不過,濫用 `goto` 會使代碼邏輯混亂、可讀性變差。所以僅在處理深度嵌套跳出等特殊情況時使用
goto 語句可以使用的場景:?
int main()
{for (int i = 0; i < 10; i++){for (int j = 0; j < 10; j++){for (int k = 0; k < 10; k++){goto error;}}}error:return 0;
}
能直接跳出深度嵌套的情況
利用 goto語句 寫一個電腦關機程序
int main()
{char password[20] = { 0 };system("shutdown -s -t 60");printf("請注意,你的電腦將在1分鐘內關機,如果輸入“我是豬”三個字,就取消關機。\n請輸入:");again:scanf("%s", password);if (strcmp(password, "我是豬") == 0){system("shutdown -a");printf("正確輸入,已取消關機\n");}else{printf("輸入錯誤,請再次輸入:");goto again;}return 0;
}
system("shutdown -s -t 60"); 代碼解釋:
system
?是 C 語言標準庫?<stdlib.h>
?中的函數,它的作用是調用操作系統的命令行接口來執行特定的系統命令。"shutdown -s -t 60"
?是傳遞給?system
?函數的系統命令字符串。其中,shutdown
?是 Windows 操作系統中用于關機、重啟、注銷等操作的命令。-s
?表示關機操作,即讓計算機在指定時間后關閉。-t 60
?表示設置關機的倒計時時間,-t
?是指定時間的參數,60
?代表 60 秒。
綜合起來,system("shutdown -s -t 60");
?的作用是讓程序調用系統命令,使計算機在 60 秒后自動關機。
system("shutdown -a"); 代碼解釋:
- 同樣,
system
?函數調用系統命令行接口。 "shutdown -a"
?是傳遞給?system
?函數的命令字符串。其中,shutdown
?是 Windows 系統用于關機等操作的命令,-a
?是取消關機操作的參數。
所以,system("shutdown -a");
?的作用是調用系統命令來取消之前設置的關機計劃,無論之前設置的是多少時間后關機,執行這行代碼后,關機計劃都會被取消