浙大版《C語言程式設計》第四版(何欽銘顏暉) 第7章 陣列 課後習題答案
你也可以上程式咖(https://meta.chengxuka.com),開啟大學幕題板塊,不但有答案,講解,還可以線上答題。
一、選擇題
1.假定 int 型別變數佔用兩個位元組,則以下定義的陣列 a 在記憶體中所佔位元組數是( )。
int a[10]={10,2,4};
A. 20
B.10
C.6
D.3
答:A
解析:題目中,根據 int a[10] ,表示定義了陣列的長度是 10 ,每個變數佔用兩個位元組,一共就是 20 個位元組。
2.若有定義:int a[2][3]
;以下選項中對陣列元素正確引用的是( )。
A. a[2][0]
B. a[2][3]
C.
a[0][3]
D.
a[1>2][1]
答:D
解析:
題目中定義了二維陣列 a[2][3]
,那麼該陣列表示一個 2 行 3 列的矩陣,行的下標(第一個下標)的取值範圍就是 0,1,列的下標(第二個下標)的取值範圍就是 0,1,2。這裡是有選項 D,a[1>2][1]
,實際上是 a[0][1]
,下標的數值沒有越界。
3.以下程式段的輸出結果是( )。
int aa[4][4]={{1,2,3,4},{5,6,7,8},{3,9,10,2},{4,2,9,6}}; int i, s=0; for(i=0; i<4; i++) s+=aa[i][3]; printf("%d\n", s);
A.11
B.19
C.13
D.20
答:D
解析:
題目中定義的是二維陣列,4X4 的矩陣。
1 2 3 4
5 6 7 8
3 9 10 2
4 2 9 6
迴圈中 i 的值表示行,從 0 取到 3,而列的下標固定是 3,所以表示累加最後一列的值。4+8+2+6 = 20。
4.設有陣列定義:char array[]="China" ; 則陣列 array 所佔的空間為( )位元組。
A.4個
B.5個
C.6個
D.7個
答:C
解析:在題目的定義方式中,系統會自動在陣列最後加入一個'\0',表示字元陣列的結束,因此陣列的長度就是 6 個位元組。
5.下述對字元陣列的描述中錯誤的是( )。
A.字元陣列可以存放字串
B.字元陣列中的字串可以整體輸入、輸出
C.可以在賦值語句中通過賦值運算子"="對字元陣列整體賦值
D.不可以用關係運算符對字元陣列中的字串進行比較
答:C
解析:
選項 A 正確,在 C 語言中可以將字串作為一個特殊的一位字元陣列來處理。例如:char array[]="China" ;
選項 B 正確,因為字元陣列中直接使用陣列名稱時陣列會退化為指標而且字串結尾會有“\0”,指標遇到“\0”會結束輸入或者輸出。用到的程式碼是: char ch[100]; gets(ch); //整體輸入puts(ch);整體輸出。(同時這裡提個醒字元陣列可以進行整體的輸入輸出,但是整型輸出是不可以進行的整體輸入輸出)
選項 C 不正確。在賦值語句中通過賦值運算子"="對字元陣列整體賦值,則就需要用到字元陣列名,而對字元陣列名進行操作時其會退化為常量指標,而進行賦值時左值必須是可以修改的變數。所以錯誤。
選項 D 正確。陣列名會退化為指標,所以比較的其實就是指標所指向的記憶體地址的大小,這個跟比較字串的大小沒有關係。
6.對於以下定義,正確的敘述為( )。
char x[]="abcdefg", char y[]={'a','b','c','a','e','f','g'};
A.陣列 x 和陣列 y 等價
B.陣列 x 的長度大於陣列 y 的長度
C.陣列 x 和陣列 y 的長度相同
D.陣列 x 的長度小於陣列 y 的長度
答:B
解析:
char x[]="abcdefg",陣列 x 的長度是 8,7個字元,以及系統自動加的 '\0'。
char y[]={'a','b','c','a','e','f','g'},陣列 y 的長度是 7。
char x[]=”abcdefg”;
//等價於
char x[]={‘a’,'b’,'c’,'d’,'e’,'f’,'g’,'\0'};
二、填空題
1.寫出以下程式段的輸出結果:輸入4,則輸出( ),輸入5,則輸出( ),輸入12,則輸出( ),輸入-5,則輸出( )。
int i, n = 5, x, a[10] = {1, 3, 5, 7, 9};
scanf("%d", &x);
for (i = n - 1; i >= 0; i--)
if (x < a[i])
a[i + 1] = a[i];
else
break;
a[i + 1] = x;
n++;
printf("%d", i + 1);
答:2 3 5 0
解析:
迴圈中 i 的取值為 4,3,2,1,0。當取到 -1 時結束 for迴圈。迴圈裡就是在比較 x 和 a[i] 的大小。
第一個空,當 x 的值為 4 時, 下標 i 的值為 1,對應陣列中的 3,if 語句不成立,break 了迴圈,此時 i 的值為1 。最終列印 i+1的值就是 2。
第二個空,當 x 的值為 5 時,下標 i 的值為 2,對應陣列中的的 5,if 語句不成立,break 了迴圈,此時 i 的值為 2。最終列印 i+1 的值就是 3。
第三個空,當 x 的值為 12 時,下標 i 的值為 4,對應陣列中的 9,if 語句不成立,break 迴圈,此時 i 的值為 4。最終列印 i+1 的值就是 5。
第四個空,當 x 的值為 -5 時,整個陣列中的所有值都比 x 大,迴圈結束時 i 的值為 -1 。最終列印 i+1 的值就是 0。
2.求陣列中相鄰元素之和。將陣列 x 中相鄰兩個元素的和依次存放到 a 陣列中。請填空。
int i, a[9], x[10];
for (i = 0; 1 < 10; i++)
scanf("%d", &x[i]);
for (_______; i < 10; i++)
a[i - 1] = _______ + x[i];
答:i = 1 x[i - 1]
解析:因為要表示陣列中相鄰的元素,可以使用 x[i-1] 和 x[i],所以在第二個 for 迴圈中,i 的初始值為 1。
3.簡化的插入法排序。將一個給定的整數 x 插到已按升序排列的整型陣列 a 中,使 a 陣列仍然按升序排列。假定變數都已正確定義並賦值,請填空。
for (i = 0; i < n; i++)
{
if (________)
{
break;
}
}
for (________)
{
a[j + 1] = a[j];
}
________;
n++;
答:
x < a[i]
j = n - 1; j >= i; j--
a[i] = x
解析:
這裡的思路是:第一個 for 迴圈,比較 x 和 陣列中的元素,直到 x 大於陣列中的某一個元素。然後記錄該值的下標。
然後第二個迴圈將 i 後的每一個元素向後移動一個位置。
最後將 x 插入到 下表 i 的位置上。
4.輸入 8 ,以下程式段的輸出結果為( ),輸入 5 ,輸出結果為( )。
int i, max_sum, n, this_sum, a[] = {-1, 3, -2, 4, -6, 1, 6, -1};
scanf("%d", &n);
max_sum = this_sum = 0;
for (i = 0; i < n; i++)
{
this_sum += a[i];
if (this_sum > max_sum)
max_sum = this_sum;
else if (this_sum < 0)
this_sum = 0;
}
printf("%d\n", max_sum);
答:7 5
解析:
第一空,當 n = 8 時,for 迴圈遍歷了陣列中的所有的元素,下標從 0 到 7 。
i = 0 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[0] = -1 ,值為 -1,執行 else if 的內容,this_sum 的值被修改為 0。
i = 1 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[1] = 3,值為 3,執行 if 的內容,max_sum 的值為 3。
i = 2 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[2] = -2,值為 1,不執行 if 也不執行 else if,然後下一次迴圈。
i = 3 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[3] = 4,值為 5,執行 if 的內容,max_sum 的值為 5。
i = 4 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[4] = -6,值為 -1,執行 else if 的內容,this_sum 的值被修改為 0。
i = 5 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[5] =1,值為 1,不執行if 也不執行 else if,然後下一次迴圈。
i = 6 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[6]= 6,值為 7,執行 if 的內容,max_sum 的值修改為 7。
i = 7 時,迴圈條件成立,進入迴圈,this_sum 累加完 a[7] = -1,值為 6。不執行if 也不執行 else if。
i = 8 時,結束迴圈。
第二空,當 n = 5 時,for 迴圈遍歷了下標從 0 到 4。數值的遍歷從 -1 到 -6 。分析過程如上。
5.輸入 1 2 3 4 5 6 ,則程式段 A 的輸出結果是( ),程式段 B 的輸出結果是( )。
程式段 A
int i, j, table[3][2];
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
scanf("%d", &table[i][j]);
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
printf("%d#", table[i][j]);
程式段 B
int i, j, table[3][2];
for (j = 0; j < 2; j++)
for (i = 0; i < 3; i++)
scanf("%d", &table[i][j]);
for (i = 0; i < 3; i++)
for (j = 0; j < 2; j++)
printf("%d#", table[i][j]);
答:
1#2#3#4#5#6#
1#4#2#5#3#6#
分析:
6.判斷二維陣列是否對稱。檢查二維陣列 a 是否對稱,即對所有 i ,j 都滿足a[i][j]
和a[j][i]
的值相等。假定變數都已正確定義並賦值,請填空。
found = 1;
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (___________)
{
___________;
break;
}
}
if (___________)
break;
}
if (found != 0)
printf("該二維陣列對稱\n");
else
printf("該二維陣列不對稱\n");
答:
a[i][j] != a[j][i]
found = 0
found == 0
解析:
由列印輸出條件可以看的出來,found 的值為 1 時,是對稱陣列,found 為 0 時,是非對稱陣列。
所以第一個空,填入 a[i][j] != a[j][i]
,他倆的值不想等,那麼就把 found 修改為 0。所以第二個空為 found = 0,執行了 break,結束這個 j 這個迴圈。第三個空要判斷 found 的值是否為 0 ,如果是 0 就結束整個 i 的迴圈,因為一旦 found 被修改為 0,那麼這個陣列就不是對稱的了,後面的其他數值也不需要判斷了。
7.字串複製。將字串 str1 的內容複製到字串 str2 。 假定變數都已正確定義並賦值,請填空。
i = 0;
while (___________)
{
___________;
i++;
}
___________;
答:
str1[i] != '\0'
str2[i] = str1[i]
str2[i] = '\0'
解析:這裡迴圈複製就可以了。只不過使用 char[] 陣列操作字串,最後一個字元儲存 '\0'。
8.刪除字串中的空格。將字串 str 中的所有空格都刪除。假定變數都已正確定義並賦值,請填空。
i = j = 0;
while (__________)
{
if (__________)
{
str[j] = str[i];
__________
}
i++;
}
__________
答:
str[i] != '\0'
str[i] != ' '
j++;
str[j] = '\0';
解析:
迴圈遍歷字串,通過兩個下標 i 和 j 來操作。i 用於遍歷字串中的每個字元,j 用於儲存非空格的字元。如果這個字元不是空格,就複製到 j 對應的位置上。最後要記得末尾加 '\0'。
三、程式設計題
題目1:選擇法排序。輸入一個正整數 n (1<n≤10),再輸入 n 個整數,將它們從大到小排序後輸出。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int max(int a[], int len);
int main()
{
// 習題(7.3.1)
/*
選擇法排序。輸入一個正整數 n (1<n≤10),再輸入 n 個整數,將它們從大到小排序後輸出。
*/
//資料存入
int i, n;
printf("input n number:");
scanf("%d", &n);
int a[n];
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
int len = sizeof(a) / sizeof(a[0]);
//選擇排序
for (i = len - 1; i > 0; i--)
{
int maxid = max(a, i + 1);
int t = a[maxid];
a[maxid] = a[i];
a[i] = t;
}
for (i = len - 1; i >= 0; i--)
{
printf("%d ", a[i]);
}
printf("\n");
return 0;
}
int max(int a[], int len) //找出陣列中最大數
{
int i, maxid = 0;
for (i = 1; i < len; i++)
{
if (a[i] > a[maxid])
{
maxid = i;
}
}
return maxid;
}
執行結果:
題目2:求一批整數中出現最多的數字。輸入一個正整數 n(1<n≤1 000), 再輸入 n 個整數,分析每個整數的每一位數字,求出現次數最多的數字。例如輸入 3 個整數 1234、2345、3456, 其中出現次數最多的數字是 3 和 4 ,均出現了 3 次。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.2)
/*
求一批整數中出現最多的數字。輸入一個正整數 n(1<n≤1 000), 再輸入 n 個整數,分析每個整數的每一位數字,
求出現次數最多的數字。例如輸入 3 個整數 1234、2345、3456, 其中出現次數最多的數字是 3 和 4 ,均出現了 3 次。
*/
int n, i, max = 0, temp, time[10] = {0};
printf("input n:");
scanf("%d", &n);
printf("input %d integers:", n);
for (i = 0; i < n; i++)
{
scanf("%d", &temp);
while (temp != 0)
{
time[temp % 10]++;
temp /= 10;
}
}
for (i = 0; i < 10; i++)
{
if (max < time[i])
max = time[i];
}
printf("出現最多次數 %d 次的數字是:", max);
for (i = 0; i < 10; i++)
if (time[i] == max)
printf("%d ", i);
printf("\n");
return 0;
}
執行結果:
再輸入一組:
題目3:判斷上三角矩陣。輸入一個正整數 n(1≤n≤6)和 n 階方陣 a 中的元素,如果 a 是上三角矩陣,輸出 “YES", 否則,輸出 “NO"。 上三角矩陣指主對角線以下的元素都為 0 的矩陣,主對角線為從矩陣的左上角至右下角的連線。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.3)
/*
判斷上三角矩陣。輸入一個正整數 n(1≤n≤6)和 n 階方陣 a 中的元素,如果 a 是上三角矩陣,輸出 “YES", 否則,輸出 “NO"。
上三角矩陣指主對角線以下的元素都為 0 的矩陣,主對角線為從矩陣的左上角至右下角的連線。
*/
int a[6][6], flag, i, j, n;
printf("input n: ");
scanf("%d", &n);
printf("input array: \n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
flag = 1;
for (i = 0; i < n; i++)
for (j = 0; j < i; j++)
if (a[i][j] != 0)
flag = 0;
if (flag)
printf("YES\n");
else
printf("NO\n");
return 0;
}
執行結果:
題目4:求矩陣各行元素之和。輸入 2 個正整數 m 和 n (1≤m≤6,1≤n≤6) ,然後輸入矩陣 a ( m 行 n 列 ) 中的元素,分別求出各行元素之和,並輸出。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.4)
/*
求矩陣各行元素之和。輸入 2 個正整數 m 和 n (1≤m≤6,1≤n≤6) ,然後輸入矩陣 a ( m 行 n 列 ) 中的元素,
分別求出各行元素之和,並輸出。
*/
int a[6][6], i, j, m, n, sum;
printf("input m,n : ");
scanf("%d%d", &m, &n);
printf("input array:\n");
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (i = 0; i < m; i++)
{
sum = 0;
for (j = 0; j < n; j++)
sum = sum + a[i][j];
printf("sum of row %d is %d\n", i, sum);
}
return 0;
}
執行結果:
題目5:找鞍點。輸入 1 個正整數 n ( 1≤n≤6) 和 n 階方陣 a 中的元素,假設方陣 a 最多有 1 個鞍點,如果找到 a 的鞍點,就輸出其下標,否則,輸出“NO"。 鞍點的元素值在該行上最大,在該列上最小。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.5)
/*
找鞍點。輸入 1 個正整數 n ( 1≤n≤6) 和 n 階方陣 a 中的元素,假設方陣 a 最多有 1 個鞍點,
如果找到 a 的鞍點,就輸出其下標,否則,輸出“NO"。 鞍點的元素值在該行上最大,在該列上最小。
*/
int flag, i, j, k, row, col, n, a[6][6];
printf("input n: ");
scanf("%d", &n);
printf("input array:\n");
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
scanf("%d", &a[i][j]);
for (i = 0; i < n; i++)
{
flag = 1;
col = 0;
for (j = 0; j < n; j++)
if (a[i][col] < a[i][j])
col = j;
for (k = 0; k < n; k++)
if (a[i][col] > a[k][col])
{
flag = 0;
break;
}
if (flag)
{
row = i;
break;
}
}
if (flag)
printf("a[%d][%d]=%d\n", row, col, a[row][col]);
else
printf("NO\n");
return 0;
}
執行結果:
再輸入一組:
題目6:統計大寫子音字母。輸入一個以回車結束的字串(少於 80 個字元),統計並輸出其中大寫子音字母的個數。大寫子音字母是指除 'A','E' ,'I','O', 'U' 以外的大寫字母。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.6)
/*
統計大寫子音字母。輸入一個以回車結束的字串(少於 80 個字元),統計並輸出其中大寫子音字母的個數。
大寫子音字母是指除 'A','E' ,'T','O', 'U' 以外的大寫字母。
*/
int count, i;
char ch, str[80];
printf("input a string:");
i = 0;
while ((ch = getchar()) != '\n')
{
str[i++] = ch;
}
str[i] = '\0';
count = 0;
for (i = 0; str[i] != '\0'; i++)
if (str[i] <= 'Z' && str[i] > 'A' && str[i] != 'E' && str[i] != 'I' && str[i] != 'O' && str[i] != 'U')
count++;
printf("count = %d\n", count);
return 0;
}
執行結果:
題目7:字串替換。輸入一個以回車結束的字串(少於 80 個字元),將其中的大寫字母用下面列出的對應大寫字母替換,其餘字元不變,輸出替換後的字串。試編寫相應程式。
原字母對應字母
A→Z
B→Y
C→X
D→W
...
X→C
Y→B
Z→A
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.7)
/*
字串替換。輸入一個以回車結束的字串(少於 80 個字元),將其中的大寫字母用下面列出的對應大寫字母替換,其餘字元不變,輸出替換後的字串。試編寫相應程式。
原字母對應字母
A→Z
B→Y
C→X
D→W
...
X→C
Y→B
Z→A
*/
int i;
char ch, str[80];
printf("input a string:");
i = 0;
while ((ch = getchar()) != '\n')
{
str[i++] = ch;
}
str[i] = '\0';
for (i = 0; str[i] != '\0'; i++)
if (str[i] <= 'Z' && str[i] >= 'A')
str[i] = 'A' + 'Z' - str[i];
printf("After replaced:");
for (i = 0; str[i] != '\0'; i++)
putchar(str[i]);
putchar('\n');
return 0;
}
執行結果:
題目8:字串轉換成十進位制整數。輸入一個以字元 “#” 結束的字串,濾去所有的非十六進位制字元(不分太小寫),組成一個新的表示十六進位制數字的字存串,然後將其轉換為十進位制數後輸出。如果過濾後字串的首字元為 “-“ 代表該數是負數。試編寫相應程式。
答案程式碼:
#include <stdio.h>
int main()
{
// 習題(7.3.2)
/*
求一批整數中出現最多的數字。輸入一個正整數 n(1<n≤1 000), 再輸入 n 個整數,分析每個整數的每一位數字,
求出現次數最多的數字。例如輸入 3 個整數 1234、2345、3456, 其中出現次數最多的數字是 3 和 4 ,均出現了 3 次。
*/
char str_old[81], str_new[81];
int i = 0, j, flag = 0, temp; // flag用來表示是否有負號存在,0表示負數,1表示正數
long sum = 0;
printf("input s string:");
while ((str_old[i] = getchar()) != '#')
i++; //輸入一個以'#'結束的非空字串
str_old[i] = '\0';
for (i = 0; str_old[i] != '\0'; i++)
if (str_old[i] == '-')
{
temp = i;
break;
} //找到第一個'-'出現的位置,用temp儲存
for (i = 0; i < temp; i++)
{
if ((str_old[i] >= '0' && str_old[i] <= '9') || (str_old[i] >= 'a' && str_old[i] <= 'f') || (str_old[i] >= 'A' && str_old[i] <= 'F'))
{
flag = 1;
break;
}
} //遍歷字串至temp,如果第一個'-'之前存在十六進位制數字,那麼'-'無效,該數為正
for (i = 0, j = 0; str_old[i] != '\0'; i++)
{
if ((str_old[i] >= '0' && str_old[i] <= '9') || (str_old[i] >= 'a' && str_old[i] <= 'f') || (str_old[i] >= 'A' && str_old[i] <= 'F'))
{
str_new[j] = str_old[i];
j++;
}
} //濾去所有與十六進位制數無關的字元
str_new[j] = '\0';
for (j = 0; str_new[j] != '\0'; j++)
{
if (str_new[j] >= '0' && str_new[j] <= '9')
sum = 16 * sum + str_new[j] - '0';
else if (str_new[j] >= 'a' && str_new[j] <= 'f')
sum = 16 * sum + str_new[j] - 'a' + 10;
else if (str_new[j] >= 'A' && str_new[j] <= 'F')
sum = 16 * sum + str_new[j] - 'A' + 10;
} //十六進位制轉化為十進位制數
if (flag == 0)
sum = -sum;
printf("%ld\n", sum);
return 0;
}
執行結果: