c程序設計第五版譚浩強習題答案
第四章 選擇結構程序設計
1. 什麼是算術運算?什麼是關係運算?什麼是邏輯運算?
【答案解析】
算熟運算:
算術運算即“四則運算”,是加法、減法、乘法、除法、乘方、開方等幾種運算的統稱。
其中加減爲一級運算,乘除爲二級運算,乘方、開方爲三級運算。在一道算式中,如果有多級運算存在,則應先進行高級運算,再進行低一級的運算。
C語言中的算熟運算符包括:+
、-
、*
、/
、++
、--
、%
等種類。
如果只存在同級運算;則從左至右的順序進行;如果算式中有括號,則應先算括號裏邊,再按上述規則進行計算。
示例:$ (1 + 1)^{2} * 4+5 * 3$
解析:
- 先進行括號內運算
1+1
,然後進行乘方運算得到結果4. - 接下來與4相乘,得到結果16
- 因爲乘法優先級大於加法,因此先進行5*3,得到結果15
- 最終相加得到結果31
結果:31
關係運算:
關係的基本運算有兩類:一類是傳統的集合運算(並、差、交等),另一類是專門的關係運算(選擇、投影、連接、除法、外連接等),而在C語言中,關係運算通常被認爲是比較運算,將兩個數值進行比較,判斷比較結果是否符合給定的條件。
常見的關係運算符包括:<
、<=
、>
、>=
、==
、!=
等種類。
其中,前4種關係運算符(<、<=、>、>= )的優先級別相同,後2種(==、!=)也相同。而前4種高於後2種。
例如, >
優先於 ==
。而 >
與 <
優先級相同。
並且,關係運算符的優先級低於算術運算符,關係運算符的優先級高於賦值運算符(=)。
邏輯運算:
在邏輯代數中,有與、或、非三種基本邏輯運算。表示邏輯運算的方法有多種,如語句描述、邏輯代數式、真值表、卡諾圖等。而在C語言中,邏輯運算通常用於使用邏輯運算符將關係表達式或其它邏輯量連接起來組成邏輯表達式用來測試真假值。
常見的邏輯運算符包括:&&
、||
、!
等種類
&&
: 與是雙目運算符,要求有兩個運算對象,表示兩個運算對象都成立,則結果爲真,否則結果爲假。
例如:(a<b) && (x>y),表示(a<b)和(x>y)同時成立則爲真。
**||
:**是雙目運算符,要求有兩個運算對象,表示兩個運算對象只要任意一個成立,則結果爲真,否則結果爲假。
例如:(a<b) && (x>y),表示(a<b)和(x>y)兩個對象中任意一個成立則結果爲真。
**!
:**是單目運算符,只要求有一個運算對象,表示取運算對象反義,運算對象爲真則結果爲假,運算對象結果爲假則結果爲真。
例如:!(a>b),表示(a>b)成立時結果爲假,不成立時結果爲真。
若在一個邏輯表達式中包含多個邏輯運算符,則優先次序爲: !
> &&
> ||
。當然若一個邏輯表達式中包含括號括起來的子邏輯,則優先括號內的子邏輯判斷。
示例:
(1>2)||(2>3)&&(4>3) 結果爲0
!(1>2)||(2>3)&&(4>3)結果爲1
注:&&
優先級大於||
,((2>3)&&(4>3))無法同時成立,則結果爲假,然後與(1>2)結果進行邏輯或運算,兩者都爲假因此第一次結果爲假。 而第二次!
優先級最高,先對(1>2)的結果取邏輯非,得到結果爲真,因此結果爲真。
2. C語言中如何表示“真”和“假”?系統如何判斷一個量的“真”和“假”?
答案:
在C語言中邏輯常量只有兩個,即0和1,用來表示兩個對立的邏輯狀態,其中0
表示假,1
表示真。
邏輯變量與普通代數一樣,也可以用字母、符號、數字及其組合成爲的邏輯表達式表示。
對於系統來說,判斷一個邏輯量的值時,系統會以0
作爲假,以非0
作爲真。例如3&&5
的值爲真,系統給出3&&5
的值爲1
。
3. 寫出下面各邏輯表達式的值。設a=3,b=4,c=5。
(1)a + b > c && b == c
(2)a || b + c && b - c
(3)!(a > b) && !c || 1
(4)!(x = a) && (y = b) && 0
(5)!(a + b) + c - 1 && b + c / 2
解題思路:
- 關係運算符的優先級高於賦值運算符,但是低於算術運算符;
- &&表示兩邊條件同爲真則成立,||表示兩邊條件任意一個爲真則成立,!取條件反義。
- 邏輯運算符優先級: ! > && > ||
- 有括號優先括號。
3.1 題目:a + b > c && b == c -> 3+4>5&&4==5
解析: 3+4>5 優先3+4得到結果7,因此7>5結果爲真; 4==5爲假,一真一假邏輯與最終結果爲假。
答案: 0
#include <stdio.h>
int main()
{
int a = 3, b = 4, c = 5;
printf("%d\n", a || b + c && b - c);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
3.2 題目:a || b + c && b - c -> 3||4 + 5 && 4-5
解析: 優先算術運算4+5得到7,非0則爲真,4-5得到-1,非0則爲真,接下來邏輯與判斷,最終邏輯或判斷
答案: 1
#include <stdio.h>
int main()
{
int a = 3, b = 4, c = 5;
printf("%d\n", a || b + c && b - c);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
3.3 題目:!(a > b) && !c || 1 -> !(3>4) && !5 || 1
**解析: ** !優先級最高,!(3>4)最終結果爲真,!5爲假; 其次 &&,真&&假得到假,最終||,1爲真,假或真爲真
答案: 1
#include <stdio.h>
int main()
{
int a = 3, b = 4, c = 5;
printf("%d\n", !(a > b) && !c || 1);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
3.4 題目:!(x = a) && (y = b) && 0 -> !(x=3) && (y=4)&&0
解析: 這裏&&優先級最低是最後一個邏輯運算,因此不管如何,最終&&0,則肯定爲假
答案: 假-0
#include <stdio.h>
int main()
{
int a = 3, b = 4, c = 5;
int x, y;
printf("%d\n", !(x = a) && (y = b) && 0);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
3.5 題目:!(a + b) + c - 1 && b + c / 2 -> !(3+4)+5-1 && 4+5/2
解析: 在vs中優先對(a+b)取非得到0,0+5-1結果爲4,因此最終爲真(此題涉及不同平臺結果不同的問題,因爲在有的平臺下編譯器會優先算術運算,則最終取非得到結果爲假)
**答案: ** 1
#include <stdio.h>
int main()
{
int a = 3, b = 4, c = 5;
printf("%d\n", !(a + b) + c - 1);
printf("%d\n", !(a + b) + c - 1 && b + c / 2);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
4. 有3個整數a, b, c,由鍵盤輸入,輸出其中最大的數。
解題思路: 每個數字兩兩與剩餘兩個數字進行比較,若比剩下的兩個數大則最大,例如:a>b && a>c則a是最大的
答案:
#include <stdio.h>
int main()
{
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
if (a == b && a == c) {
printf("Three numbers are equal\n");
}else if (a == b && a > c) {
printf("a and b are the largest number\n", a);
}else if (a == c && a > b) {
printf("a and c are the largest number\n", a);
}else if (b == c && b > a) {
printf("c and b are the largest number\n", a);
}else if (a > b && a > c) {
printf("a=%d is the largest number\n", a);
}else if (b > a && b > c) {
printf("b=%d is the largest number\n", b);
}else {
printf("c=%d is the largest number\n", c);
}
return 0;
}
5.從鍵盤輸入一個小於1000的正數,要求輸出它的平方根(如平方根不是整數,則輸出其整數部分)。要求在輸入數據後先對其進行檢查是否爲小於1000 的正數。若不是,則要求重新輸入。
解題思路: 首先判斷輸入的數字是否大於1000且是正數,然後使用sqrt函數對數據進行取平方根,最主要的是最終在輸出是調整輸出格式,小數部分爲0位,只需要正數部分,且整數部分不會超過4位,
答案:
#include <stdio.h>
#include <math.h>
int main()
{
float a, b;
scanf_s("%f", &a);
if (a >= 1000 || a < 0) {
printf("請輸入小於1000的正數\n");
scanf_s("%f", &a);
b = sqrt(a);
}
else {
b = sqrt(a);
}
printf("a=%4.0f, b=%4.0f\n", a, b);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
6. 有一個函數,編寫程序,輸入x的值,輸出y相應的值。
解題思路: 根據輸入的不同x值進行條件判斷,不同的條件採用不同的表達式進行計算即可
答案:
#include <stdio.h>
int main()
{
int x, y;
scanf_s("%d", &x);
if (x < 1) {
y = x;
}
else if (x >= 1 && x < 10) {
y = 2 * x - 1;
}
else {
y = 3 * x - 11;
}
printf("y = %d\n", y);
system("pause");//這一句是爲了讓控制檯不退出
return 0;
}
7. 有一個函數,
有人編寫了以下兩個程序,請分析它們是否能實現題目要求。不要急於上機運行程序,先分析兩個程序的邏輯,畫出它們的流程圖,分析它們的運行情況。然後,上機運行程序,觀察和分析結果。
#include <stdio.h>
int main()
{
int x, y;
printf("enter x:");
scanf("%d", &x);
y=-1;
if (x != 0)
if (x > 0)
y=1;
else
y=0;
printf("x=%d,y=%d\n", x, y);
return 0;
}
解題思路: if語句使用過程中,else總是匹配距離自己最近的且沒有配對的if,因此x!=0具有兩種情況x>0和x<0;因此x==0時y保持-1;x!=0&&x>0時y=1;x!=0&&x<0時y=0。
流程圖:
答案:
#include <stdio.h>
int main()
{
int x, y;
printf("enter x:");
scanf("%d", &x);
y=0;
if (x >= 0)
if (x > 0) y=1;
else y=-1;
printf("x=%d,y=%d\n", x, y);
return 0;
}
解題思路: if語句使用過程中,else總是匹配距離自己最近的且沒有配對的if,因此x>=0具有兩種情況x>0和x0;因此x<0時y保持0;x>=0&&x>0時y=1;x>=0&&x0時y=-1。
流程圖:
答案:
8. 給出一百分制成績,要求輸出成績等級’A’、‘B’、‘C’、‘D’、‘E’。 90分以上爲’A’,8089分爲’B’,7079分爲’C’ ,60~69分爲’D’ ,60分以下爲’E’。
解題思路: 根據不同的階段成績區間作爲成績的判斷條件,屬於哪個區間則輸出對應等級即可
答案:
#include <stdio.h>
int main()
{
int score;
printf("enter score:");
scanf_s("%d", &score);
if (score >= 90) {
printf("A\n");
}else if (score >= 80 && score < 90) {
printf("B\n");
}else if (score >= 70 && score < 80) {
printf("C\n");
}else if (score >= 60 && score < 70) {
printf("D\n");
}else {
printf("E\n");
}
system("pause");
return 0;
}
9. 給一個不多於5位的正整數,要求:①求出它是幾位數;②分別輸出每一位數字;③按逆序輸出各位數字,例如原數爲321,應輸出123。
①求出它是幾位數;
解題思路: 大於10000就是5位,否則大於1000就是四位,否則大於100是三位…
答案:
#include <stdio.h>
int main()
{
int num;
printf("enter num:");
scanf_s("%d", &num);
if (num > 99999 || num < 0) {
printf("請輸入0~99999之間的正數\n");
return -1;
}
if (num >= 10000) {
printf("5\n");
}else if (num >= 1000) {
printf("4\n");
}else if (num >= 100) {
printf("3\n");
}else if (num >= 10) {
printf("2\n");
}else {
printf("1\n");
}
system("pause");
return 0;
}
②分別輸出每一位數字;
解題思路: 99999除以10000則輸出9;9999除以1000則輸出9,…
答案:
#include <stdio.h>
int main()
{
int num;
printf("enter num:");
scanf_s("%d", &num);
if (num > 99999 || num < 0) {
printf("請輸入0~99999之間的數字\n");
return -1;
}
if (num / 10000 > 0) {//取出萬位數字
printf("%d ", num / 10000);
}
if (num%10000 >= 1000) {//取餘10000則可以取出低四位的數據,除以1000則得到千位的數字
printf("%d ", (num % 10000) / 1000);
}
if (num%1000 >= 100) {//取餘1000則可以取出低三位的數據,除以100則得到百位的數字
printf("%d ", (num % 1000) / 100);
}
if (num%100 >= 10) {//取餘100則可以取出低兩位的數據,除以10則得到十位的數字
printf("%d ", (num % 100) / 10);
}
if (num%10 >= 0) {//取餘10則取出個位數字
printf("%d ", num % 10);
}
printf("\n");
system("pause");
return 0;
}
③按逆序輸出各位數字,例如原數爲321,應輸出123。
解題思路: 思路與第二題相同,只不過將整個過程逆序即可
答案:
#include <stdio.h>
int main()
{
int num;
printf("enter num:");
scanf_s("%d", &num);
if (num > 99999 || num < 0) {
printf("請輸入0~99999之間的數字\n");
return -1;
}
if (num % 10 >= 0) {
printf("%d ", num % 10);
}
if (num % 100 >= 10) {
printf("%d ", (num % 100) / 10);
}
if (num % 1000 >= 100) {
printf("%d ", (num % 1000) / 100);
}
if (num % 10000 >= 1000) {
printf("%d ", (num % 10000) / 1000);
}
if (num / 10000 > 0) {
printf("%d ", num / 10000);
}
printf("\n");
system("pause");
return 0;
}
10.企業發放的獎金根據利潤提成。利潤I低於或等於100000元的,獎金可提成10%;利潤高於100000元,低於200000元(100000<I≤200000)時,低於100000元的部分按10%提成,高於100000元的部分,可提成7. 5%;200000<I≤400000時,低於200000元的部分仍按上述辦法提成(下同)。高於200000元的部分按5%提成;400000<<I≤600000元時,高於400000元的部分按3%提成;600000<1≤1000000時,高於600000元的部分按1.5%提成;I>1000000時,超過1000000元的部分按1%提成。從鍵盤輸入當月利潤I,求應發獎金總數。要求:(1) 使用if語句編寫程序。(2) 使用switch語句編寫程序。
(1) 使用if語句編寫程序。
解題思路: 先將每一檔的最大獎金算出來,在某一個區間時,則那小於這一檔的獎金加上多出部分的獎金即可,例如:
先列出100000檔的獎金是10000,則180000就是10000 + (180000-100000) * 0.075;
列出200000檔的獎金是第一檔加上多出100000部分的7.5%得到17500,則300000就是17500 + (300000-200000)*0.05;
答案:
#include <stdio.h>
int main()
{
double I, salary = 0;
printf("enter performance:");
scanf_s("%lf", &I);
if (I < 0) {
printf("請輸入一個正數\n");
system("pause");
return -1;
}
double salary1 = 100000 * 0.1;//10萬的獎金
double salary2 = (200000 - 100000) * 0.075 + salary1;//20萬的獎金
double salary3 = (400000 - 200000) * 0.05 + salary2;//40萬的獎金
double salary4 = (600000 - 400000) * 0.03 + salary3;//60萬的獎金
double salary5 = (1000000 - 600000) * 0.015 + salary4;//100萬的獎金
if (I <= 100000) {
salary = I * 0.1;//小於100000按10%提成
}else if (I > 100000 && I <= 200000) {
salary = salary1 + (I - 100000) * 0.075;//多出10萬的按比例計算,加上10w的獎金
}else if (I > 200000 && I <= 400000) {
salary = salary2 + (I - 200000) * 0.05;//多出20萬的按比例計算,加上20w的獎金
}else if (I > 400000 && I <= 600000) {
salary = salary3 + (I - 400000) * 0.03;//多出40萬的按比例計算,加上40w的獎金
}else if (I > 600000 && I <= 1000000) {
salary = salary4 + (I - 600000) * 0.015;//多出60萬的按比例計算,加上60w的獎金
}else if (I > 1000000){
salary = salary5 + (I - 1000000) * 0.01;//多出100萬的按比例計算,加上100w的獎金
}
printf("salary:%f\n", salary);
system("pause");
return 0;
}
(2) 使用switch語句編寫程序。
解題思路: 與第一題思路沒有太大差別,區別在於switch語句的case子句中需要是一個常量整數,並且switch中若子句中沒有break將循序向下執行,直到遇到break纔會跳出switch語句,如果這時候將利潤除以10w,則得到09的數字,其中0表示小於10w,1表示介於1020w,2、3表示介於2040w,4、5表示介於4060w,6、7、8、9表示介於60~100w,否則就是大於100w
答案:
#include <stdio.h>
int main()
{
double I, salary = 0;
printf("enter performance:");
scanf_s("%lf", &I);
if (I < 0) {
printf("請輸入一個正數\n");
system("pause");
return -1;
}
double salary1 = 100000 * 0.1;//大於100000時0~100000的獎金
double salary2 = (200000 - 100000) * 0.075 + salary1;//大於200000時0~20萬的獎金
double salary3 = (400000 - 200000) * 0.05 + salary2;//大於400000時0~40萬的獎金
double salary4 = (600000 - 400000) * 0.03 + salary3;//大於600000時0~60萬的獎金
double salary5 = (1000000 - 600000) * 0.015 + salary4;//大於1000000時0~100萬的獎金
int grade = I / 100000;
switch(grade) {
case 0:
salary = I * 0.1; break;
case 1:
salary = salary1 + (I - 100000) * 0.075; break;
case 2://會順序執行到下一個break處
case 3:
salary = salary2 + (I - 200000) * 0.05; break;
case 4:
case 5:
salary = salary3 + (I - 400000) * 0.03; break;
case 6:
case 7:
case 8:
case 9:
salary = salary4 + (I - 600000) * 0.015; break;
default:
salary = salary5 + (I - 1000000) * 0.01; break;
}
printf("salary:%f\n", salary);
system("pause");
return 0;
}
11. 輸入4個整數,要求按由小到大的順序輸出。
解題思路: 四個數中先找到最小的,剩下的三個數中找到第二小的,剩下的兩個數中找到第三小的。
答案:
#include <stdio.h>
int main()
{
int a, b, c, d;
int max_num;
scanf_s("%d %d %d %d", &a, &b, &c, &d);
int tmp;
//找到最小的數
if (a > b) {
tmp = a; a = b; b = tmp; // a>b兩個數據交換,則給a存儲小的b
}
if (a > c) {
tmp = a; a = c; c = tmp;
}
if (a > d) {
tmp = a; a = d; d = tmp;
}
//找到第二小的數,不需要和最小的數比較
if (b > c) {
tmp = b; b = c; c = tmp;
}
if (b > d) {
tmp = b; b = d; d = tmp;
}
//找到第三小的數據,不需要和第一和第二小比較
if (c > d) {
tmp = c; c = d; d = tmp;
}
printf("%d %d %d %d\n", a, b, c, d);
system("pause");
return 0;
}
12. 有4個圓塔,圓心分別爲(2,2)、(-2,2)、(-2,-2)、(2,-2),圓半徑爲1,見圖。這4個塔的高度爲10m,塔以外無建築物。今輸入任一點的座標,求該點的建築高度(塔外的高度爲零)。
解題思路: 塔的半徑爲1m,則x座標小於-3或者大於3,以及y座標大於3或者小於-3則都是0m的建築;其餘則判斷輸入的座標是否在各個圓塔的圓形範圍內。該點到各個圓心的距離是否大於1,小於則是10m建築,否則爲0m建築。
math.h中提供了fabs(double)求一個浮點數的絕對值,輸入x,y座標
fabs(fabs(x) - 2)得到輸入座標距離圓心的橫軸距離;
fabs(fabs(y) - 2)得到舒服座標距離圓心的縱軸距離;
三角形兩個直角邊長平方相加,然後開平方根得到第三邊長,若大於1,則不再圓塔範圍內。
答案:
#include <stdio.h>
#include <math.h>
void main()
{
int h;
double x, y, m, n, r;
printf("Please input a coordinate (x,y):");
scanf_s("%lf,%lf", &x, &y);
if (fabs(x) > 3 || fabs(y) > 3) {
h = 0;
printf("The height of the coordinate(%f,%f):h=%d\n", x, y, h);
return 0;
}
m = fabs(x) - 2; n = fabs(y) - 2;
r = sqrt(m * m + n * n);
if (r > 1)
h = 0;
else
h = 10;
printf("The height of the coordinate(%f,%f):h=%d\n", x, y, h);
system("pause");
return 0;
}
c語言程序設計第五版譚浩強習題答案更多:
c語言程序設計第五版譚浩強習題答案 第三章課後答案