【計算機二級C語言】卷003


選擇題

公共知識

【1】設線性表的長度為12。最壞情況下冒泡排序需要的比較次數為()。
〖A〗66
〖B〗78
〖C〗144
〖D〗60
最壞情況下冒泡排序需要的比較次數為n(n - 1) / 2, 本題中n = 12, 故需要比較66次。
【2】設棧與隊列初始狀態為空。將元素A, B, C, D, E, F, G, H依次輪流入棧和入隊, 然后依次輪流退隊和出棧, 則輸出序列為()。
〖A〗G, B, E, D, C, F, A, H
〖B〗B, G, D, E, F, C, H, A
〖C〗D, C, B, A, E, F, G, H
〖D〗A, B, C, D, H, G, F, E
棧是先進后出的線性表, 隊列是先進先出的線性表。
將元素A, B, C, D, E, F, G, H依次輪流入棧和入隊, 這時棧中的元素為ACEG, 隊列中的元素為BDFH; 然后依次輪流退隊和出棧, 即隊列中B元素退隊, 然后棧中G元素出棧, 隊列中D元素退隊, 棧中E元素出棧, 以此順序, 完成所有元素退隊和出棧, 則輸出序列為B, G, D, E, F, C, H, A。
【3】樹的度為3, 共有29個結點, 但沒有度為1和2的結點。則該樹中葉子結點數為()。
〖A〗0
〖B〗9
〖C〗18
〖D〗不可能有這樣的樹
樹的度為3, 即樹中只存在度為0、1、2、3的結點, 假設葉子結點數為n, 由於沒有度為1和2的結點, 則度為3的結點數為29 - n, 根據樹中的結點數=樹中所有結點的度之和+1, 得3×(29 - n) + 0×1 + 0×2 + n×0 + 1 = 29, 得出的n不為整數, 因此不存在這樣的樹。
【4】循環隊列的存儲空間為Q(0 : 59), 初始狀態為空。經過一系列正常的入隊與退隊操作后, front = 25, rear = 24。循環隊列中的元素個數為()。
〖A〗1
〖B〗2
〖C〗59
〖D〗60
設循環隊列的存儲空間為Q(1 : m), 初始狀態為空。
在循環隊列運轉起來后, 如果rear - front > 0, 則隊列中的元素個數為rear - front個; 如果rear - front < 0, 則隊列中的元素個數為rear - front + m。
本題中front = 25, rear = 24, rear - front < 0, 則元素個數為24 - 25 + 60 = 59。
【5】下面描述正確的是()。
〖A〗軟件是程序、數據與相關文檔的集合
〖B〗程序就是軟件
〖C〗軟件既是邏輯實體又是物理實體
〖D〗軟件的運行不一定對計算機系統具有依賴性
計算機軟件是由程序、數據及相關文檔構成的完整集合, 它與計算機硬件一起組成計算機系統。
【6】單元測試不應涉及的內容是()。
〖A〗模塊的接口
〖B〗模塊的執行路徑
〖C〗模塊的局部數據結構
〖D〗模塊的出錯處理功能
單元測試主要針對模塊的5個基本特征進行:模塊接口測試, 局部數據結構測試, 重要的執行路徑的檢查, 檢查模塊的錯誤處理能力, 影響以上各點及其他相關點的邊界條件測試。
【7】面向對象方法中, 將數據和操作置於對象的統一體中的實現方式是()。
〖A〗結合
〖B〗抽象
〖C〗封裝
〖D〗隱藏
封裝是指從外面看只能看到對象的外部特性, 對象的內部對外是不可見的, 即將數據和操作置於對象的統一體中。
【8】在數據庫設計中, 將ER圖轉換成關系數據模型的過程屬於()。
〖A〗物理設計階段
〖B〗需求分析階段
〖C〗概念設計階段
〖D〗邏輯設計階段
數據庫的邏輯設計主要工作是將ER圖轉換成指定RDBMS中的關系模式。
【9】學校的每個社團都有一名團長, 且一個同學可同時擔任多個社團的團長, 則實體團長和實體社團間的聯系是()。
〖A〗一對多
〖B〗多對多
〖C〗多對一
〖D〗一對一
每個社團都有一名團長, 一個同學可同時擔任多個社團的團長, 則實體團長和實體社團間的聯系是一對多。
【10】定義學生選修課程的關系模式如下:
SC(S#, Sn, C#, Cn, G, Cr)(其屬性分別為學號、姓名、課程號、課程名、成績、學分)
該關系可進一步歸范化為()。
〖A〗S(S#, Sn, C#, Cn, Cr), SC(S#, C#, G)
〖B〗S(S#, Sn), C(C#, Cn, Cr), SC(S#, C#, G)
〖C〗C(C#, Cn, Cr), SC(S#, Sn, C#, G)
〖D〗S(S#, Sn), C(C#, Cn), SC(S#, C#, Cr, G)
關系SC的主鍵為復合鍵(學號, 課程號), 但明顯存在課程號→課程名, 課程號→學分等, 存在非主屬性對主屬性的部分依賴。
對關系SC進行如下的分解, 就可以消除對非主屬性的部分依賴, 滿足第二范式:S(S#, Sn), C(C#, Cn, Cr), SC(S#, C#, G)。

專業知識

【11】以下敘述中錯誤的是()。
〖A〗用C語言編寫的是機器語言程序
〖B〗用高級語言編寫的程序稱為"源程序"
〖C〗由編譯器編譯生成的二進制代碼稱為"目標程序"
〖D〗由三種基本結構構成的程序是結構化程序
計算機只能接受和處理由0和1的代碼構成的二進制指令或數據, 這種形式的指令是面向機器的, 稱為機器語言, 而C語言屬於高級語言, 用高級語言編寫的程序稱為源程序, 選項A錯誤, B正確; 源程序通過編譯器編譯生成二進制代碼, 由二進制代碼表示的程序稱為目標程序, 選項C正確; 由順序結構、選擇結構、循環結構這三種基本結構構成的程序是結構化程序, 選項D正確; 本題答案A
【12】以下合法的用戶標識符是()。
〖A〗m$
〖B〗2x
〖C〗_12315_
〖D〗I-max
C語言中, 標識符的命名規則是:由字母、數字和下划線組成, 並且第一個字符必須是字母或下划線, 選項A中, $符號不合法; 選項B中以數字開頭, 不合法; 選項D中, -符號不合法; 選項C正確; 本題答案C
【13】以下定義變量i、j、k並賦初值的語句, 正確的是()。
〖A〗int i = 0, j = 0, k = 0;
〖B〗int i = 0; j = 0; k = 0;
〖C〗int i = j = k = 0;
〖D〗int i = 0; j = i; k = j;
C語言中一條語句必須以分號結尾, 在使用變量前必須要給出變量的定義, 定義時必須指明變量的類型, 選項A中使用關鍵字int定義三個變量i, j, k, 並初始化, 中間使用逗號分隔, 屬於同一條語句, 可以只使用同一種類型, 正確; 選項B、C、D中, 變量j和k未定義就使用, 錯誤; 本題答案A
【14】以下敘述中錯誤的是()。
〖A〗整型變量不能存放實數
〖B〗實型變量可以精確存放整數
〖C〗無符號整數不可以是負數
〖D〗負整數在內存中以"補碼"形式存放
整型變量可以存放實數, 但是由於整型數值的數值范圍比實數小, 所以在存放較大實數時, 會有誤差, 選項A錯誤; 實型數的數值范圍比整數大, 所以實型可以精確存放一個整數, 選項B正確; 無符號整數最高位不用來存放整數符號, 所以無符號數不可能是負數, 選項C正確; 負整數在內存中是以"補碼"形式存放的, 選項D正確; 本題答案A。
【15】若有定義語句:int a = 2;, 則以下表達式值不等於3的是()。
〖A〗a = ++a
〖B〗a = a + 1
〖C〗a += 1
〖D〗a = a++
題意中a的初值為2, 表達式++a的值為3, 將表達式的值重新賦值給a, a的值是3, 所以整個表達式的值是3, 選項A正確; a = a + 1是將a自增1, a的值為3, 所以整個表達式的值是3, 選項B正確; a += 1等價於a = a + 1, 也是將a自增1, a的值為3, 所以整個表達式的值是3, 選項C正確; a = a++首先將a的值重新賦給a, 此時a的值是2, 整個表達式的值是2, 執行完了之后, a的值自增1, 變成3, 所以整個表達式的值是2, 選項D錯誤; 本題答案D
【16】設有定義:double x = 5.1012;, 若要求只輸出x的整數部分, 以下不能實現此要求的語句是()。
〖A〗printf("x=%2d\n", x);
〖B〗printf("x=%2.0f\n", x);
〖C〗printf("x=%.0f\n", x);
〖D〗printf("x=%1.0lf\n", x);
x是double類型數據, 輸出格式符要使用%f或%lf, 而不是%d, 選項A錯誤, 輸出實數時, 可以指定輸出寬度:n1.n2, 其中n1指定輸出數據的寬度, 包括小數點; n2指定小數點后小數位的位數, 所以選項B、C、D都是輸出整數部分, 正確; 本題答案A
【17】設有定義:int a = 0, b = 1;, 則執行以下表達式后, 不能使變量a和b的值都增1的是()。
〖A〗a++ && b++
〖B〗a++ || b++
〖C〗++a && ++b
〖D〗a++ || ++b
a的初值為0, b的初值為1, 表達式a++ && b++首先執行a++, 由於是后綴自增運算符, 所以a++的值是0, 整個表達式的值確定是假, 由於邏輯與運算符的短路原則, 后續b++不再執行, 所以b沒有自增1, 選項A不能使a和b都自增1, 其他選項都可以, 本題答案A
【18】有以下程序
#include <stdio.h>
void main() {
    int s, m = 10;
    scanf("%d", &s);
    if (s < 30)
        m--;
    if (s < 40)
        m--;
    else if (s < 50)
        m--;
    else
        m++;
    printf("m=%d\n", m);
}
程序運行時輸入:25<回車>, 則輸出結果是()。
〖A〗m=9
〖B〗m=7
〖C〗m=8
〖D〗m=10
程序首先定義整型變量s和m, m初值為10, 接着通過scanf函數輸入25賦給s, if語句判斷s < 30成立, 所以執行m--, 此時m的值是9; 接着if語句判斷s < 40成立, 再次執行m--, 此時m的值是8; 由於第二個if語句執行了, 所以else語句不再執行, 輸出m的值是8, 本題答案C
【19】有以下程序
#include <stdio.h>
void main() {
    int m = 10247, a = 0, b = 0, c = 0;
    do {
        switch (m % 10) {
            case 0:
                m /= 10;
                a++;
            case 1:
            case 3:
            case 5:
            case 7:
            case 9:
                m /= 10;
                b++;
            case 2:
            case 4:
            case 6:
            case 8:
                m /= 10;
                c++;
        }
    } while (m != 0);
    printf("%d,%d,%d\n", a, b, c);
}
程序運行后的輸出結果是()。
〖A〗1,2,2
〖B〗1,2,3
〖C〗1,3,5
〖D〗1,3,4
程序定義整型變量m初值10247, a, b, c初值為0, 接着執行do...while循環, 使用switch語句從個位開始判斷m的數值位

第1輪循環:m = 10247, 個位數字是7, 執行case 7, case9, m除以10等於1024, b自增1后值為1;
接着執行case 2, case 4, case 6, case 8, m再除以10等於102, c自增1后值為1;
第2輪循環:m = 102, 個位數字是2, 執行case 2, case 4, case 6, case 8, m除以10等於10, c自增1后值為2;
第3輪循環:m = 10, 個位數字是0, 執行case 0, m除以10等於1, a自增1后值為1;
繼續執行case 1, case 3, case 5, case 7, case 9, m除以10等於0, b自增1后值為2;
繼續執行case 2, case 4, case 6, case 8, m除以10等於0, c自增1后值為3

循環結束;
綜上, a的值為1, b的值為2, c的值為3

本題答案:B

【20】有以下程序
#include <stdio.h>
void main() {
    int m = 128, n = 256, k = 100;
    while (n / k > m / k) {
        n %= k;
        m %= k;
        k /= 10;
    }
    printf("n=%d\n", n);
}
程序運行后的輸出結果是()。
〖A〗n=256
〖B〗n=0
〖C〗n=56
〖D〗n=6
程序定義整型變量m初值為128, n初值為256, k初值為100, while循環的循環條件:n / k > m / k, n / k為2, m / k為1, 2 > 1為真, 執行循環體

第1次循環:n %= k, n的值為56, m %= k, m的值為28, k /= 10, k的值為10, 此時n / k值為5, m / k的值為2, 循環條件滿足, 執行循環體;
第2次循環, n %= k, n的值是6, m %= k, m的值是8, k /= 10, k的值是1, n / k > m / k, n / k = 6, m / k = 8, 6 < 8為假, 循環結束, 輸出n的值為6, 本題答案D。

【21】以下合法的字符常量是()。
〖A〗'\x6D'
〖B〗'\0x41'
〖C〗'\X51'
〖D〗'\068'
題意中的字符都以\開頭, 都屬於轉義字符, 選項A以\x開頭, 表示十六進制數6D代表的ASCII碼字符, 合法; 不允許大寫字母X也不能使用0x開頭, 選項B和C不合法; 選項D中\068表示八進制068代表的ASCII字符, 但是068是不合法的八進制數, 選項D不合法; 本題答案:A
【22】有以下程序
#include <stdio.h>
#include <ctype.h>
void main() {
    char ch;
    do {
        ch = getchar();
        if (islower(ch))
            ch -= 32;
        else
            continue;
        printf("%c", ch);
    } while (ch != '!');
}
程序運行時輸入:1aB2cD !<回車>, 則輸出結果是()。
〖A〗AC
〖B〗bd
〖C〗ac
〖D〗1B2D
程序定義字符變量ch, do...while()循環中每次讀入一個字符, 使用islower函數判斷該字符是否是小寫字母, 如果是, 則將該字符的ASCII碼值減去32(由於英文字母的ASCII碼按照字母表順序連續遞增, 且小寫字母的ASCII碼值比對應的大寫字母的ASCII碼值大32, 所以小寫字母減去32, 可以得到對應的大寫字母), 得到對應的大寫字母, 然后輸出, 如果不是大寫字母, 執行continue, 跳過剩余循環體, 執行下一次循環; 直到輸入的字符為 !, 表示循環結束; 本題對於輸入1aB2cD !, 僅有兩個小寫字母ac被轉換成大寫字母輸出AC, 本題答案A。
【23】有以下程序
#include <stdio.h>
double fun(double s, double a, double b) {
    a = (int) (s);
    b = s - a;
    return a + b;
}
void main() {
    double s = 12.654, a = 11, b = 22;
    printf("%5.2lf,", fun(s, a, b));
    printf("%5.2lf,%5.2lf\n", a, b);
}
程序運行后的輸出結果是()。
〖A〗12.65,12.00,0.65
〖B〗33.00,11.00,22.00
〖C〗12.65,11.00,22.00
〖D〗12.00,12.00,0.65
(1) 函數fun的功能是將參數s的整數部分賦給形參a, 小數部分賦給形參b, 然后返回a + b, 所以可知fun函數返回值等於s; (2)C語言的參數是按值傳遞, 所以對形參值的修改不會影響實參(3)格式控制符%lf輸出double類型的值, 5.2表述輸出寬度為5(包含小數點), 輸出2位小數

綜上, main函數調用函數fun, 傳入s, a, b時, 返回值是s, 輸出12.65, 輸出a, b的值為:11.00, 22.00

本題答案:C

【24】有以下程序
#include <stdio.h>
int fun(int x) {
    return (x / 10);
}
void main() {
    int t = 96195;
    printf("%d\n", fun(fun(fun(t))));
}
程序運行后的輸出結果是()。
〖A〗961
〖B〗95
〖C〗96
〖D〗195
fun函數的功能是將形參值除以10后返回, 由於參數和返回值都是int類型, 所以舍去小數部分; main函數連續三次調用函數fun, 將整數t連續除以三次10, 每次調用返回值分別為:9619, 961, 96, 最終程序輸出96, 本題答案C。
【25】設有定義:int a[3][2] = { { 1 }, { 2 }, { 3 } };, 則數組元素a[2][1]的值是()。
〖A〗2
〖B〗不確定
〖C〗0
〖D〗3
int a[3][2] = { { 1 }, { 2 }, { 3 } } 是將數組a的三個元素分別賦值:a[0] = { 1 }, a[1] = { 2 }, a[2] = { 3 }, 即對三個數組的第一個元素賦值為a[0][0] = 1, a[1][0] = 2, a[2][0] = 3, 其他元素全部初始化為0, 所以a[2][1]的值為0, 本題答案C。
【26】有以下程序
#include <stdio.h>
void main() {
    int a[3][3] = { { 1 }, { 2 }, { 3 } }, *p[3], i;
    for (i = 0; i < 3; i++) {
        p[i] = a[i];
        a[i][i] = *p[i] + 2;
    }
    for (i = 2; i >= 0; i--)
        printf("%d,", a[i][i]);
}
程序運行后的輸出結果是()。
〖A〗5,4,3,
〖B〗3,2,1,
〖C〗3,3,3,
〖D〗3,4,5,
程序首先定義一個二維數組a, 並對其初始化, 初始化后, 數組a的各個元素值分別為:a[0][0] = 1, a[0][1] = 0, a[0][2] = 0, a[1][0] = 2, a[1][1] = 0, a[1][2] = 0, a[2][0] = 3, a[2][1] = 0, a[2][2] = 0, 另外還定義整型指針數組p, 通過第一個for循環, 將a的三個數組元素的地址賦給p的對應元素, 此時p[0]指向a[0], p[1]指向a[1], p[2]指向a[2], 接着將p所指向的數組的第一個元素值+2, 賦值給數組a的對應主對角線上的元素, 通過第一個for循環, a[0][0] = a[0][0] + 2 = 3, a[1][1] = a[1][0] + 2 = 4, a[2][2] = a[2][0] + 2 = 5, 第二個for循環將a的主對角線上的元素逆序輸出為5, 4, 3, 本題答案:A
【27】設有以下定義:int a[6], *p = a, i;, 下面循環語句中, 不能從終端讀入數據依次放入數組a的是()。
〖A〗for (i = 0; i < 6; i++) scanf("%d", a++);
〖B〗for (i = 0; i < 6; i++) scanf("%d", p++);
〖C〗for (; p - a < 6; p++) scanf("%d", p);
〖D〗for (i = 0; i < 6; i++) scanf("%d", a + i);
題意定義整型數組a和整型指針p, 並將a的地址賦給p, 使用scanf函數時, 輸入項必須是地址, 由於a是一個常量, 表示數組a的地址, 它不能被修改, 所以a++這種語法是錯誤的, 其他選項都是正確的, 本題答案A。
【28】有以下程序
#include <stdio.h>
int fun(int *x) {
    int f;
    f = *x + *(x + 1);
    return f;
}
void main() {
    int a[6] = { 1, 3, 5, 4, 2, 6 }, b[6], i = 0, k = 0;
    do {
        b[k] = fun(a + i);
        k++;
        i += 2;
    } while (i < 5);
    for (i = 0; i < k; i++)
        printf("%d,", b[i]);
}
程序運行后的輸出結果是()。
〖A〗4,8,9,6,8,
〖B〗4,9,8,
〖C〗6,7,7,10,
〖D〗5,5,11,
題意中, 函數fun的功能是將指針x所指向的元素與x所指向元素的下一個元素相加, 返回相加的結果; main函數定義一個整數數組a, b, 並對a的6個元素完成初始化, 接着通過do...while循環, 將數組a的下標為偶數的3個元素地址傳給函數fun, 將每個元素與其相鄰的后續元素之和存放到數組b的前3個元素中, 所以b中前三個元素值分別是:b[0] = a[0] + a[1] = 4, b[1] = a[2] + a[3] = 9, b[2] = a[4] + a[5] = 8, 輸出結果為:4, 9, 8, 本題答案B。
【29】若有定義和語句:
#include <string.h>
char str1[] = "Hello!", str2[8] = "\0", *str3 = "stop", *str4 = 0;
則以下對函數strcat的運用正確的是()。
〖A〗strcat(str2, str1)
〖B〗strcat(str1, str3)
〖C〗strcat(str3, str1)
〖D〗strcat(str4, str2)
strcat函數的功能是將第二個參數所指字符串的內容連接到第一個參數所指的字符串后面, 並自動覆蓋第一個參數末尾的空字符'\0', 所以第一個參數必須要有足夠的存儲空間來存放合並后的字符串; 題意中str1有7個字節空間, 存放空字符在內的7個字符, str2有8個字節空間, 存放1個空字符; str3有5個字節空間, 存放空字符在內的5個字符; str4有0個字節空間, 所以選項A將str1的7個字符連接到str2中, 8個字節剛好, 正確; 選項B將str3的5個字符連接到str1中, 連接后的新串占11個字節, 存儲空間不夠, 錯誤; 選項C將str1的7個字符連接到str3中, 連接后的新串占11個字節, 存儲空間不夠, 錯誤; 選項D將str2的空字符連接到str4中, 由於str4不占存儲, 所以也是錯誤的, 本題答案:A
【30】有以下程序
#include <stdio.h>
#include <string.h>
void fun(char *s) {
    int i = 0;
    while (s[i] != '\0')
        s[i++] = getchar();
}
void main() {
    char t[80] = "yes!";
    fun(t);
    puts(t);
}
程序運行時輸入:Good_luck !<回車>, 則輸出結果是()。
〖A〗yes!
〖B〗Good
〖C〗yes!_luck!
〖D〗Good_luck!
題意中函數fun的功能是讀入字符串, 逐個存放到s指向的存儲單元, 直到遇到空字符為止; main函數定義字符數組t, 它包含80字節存儲空間, 存放字符串"yes!", 所以從第5個字符開始, 后續字符默認都是空字符; 調用函數fun, 將t傳入, 由fun函數對t中的前4個字符重新輸入(第5個字符是空字符), 再將新輸入的字符串輸出, 所以輸出結果為輸入的前4個字符, 當輸入為Good_luck !, 輸出為:Good, 本題答案B
【31】有以下程序
#include <stdio.h>
#include <string.h>
void fun(char *s) {
    char *p1, *p2;
    p1 = s;
    p2 = s + strlen(s) - 1;
    while (p1 < p2) {
        if (*p1 > *p2)
            *p2 = *p1;
        else
            *p1 = *p2;
        p1++;
        p2--;
    }
}
void main() {
    char x[] = "string";
    fun(x);
    puts(x);
}
程序運行后的輸出結果是()。
〖A〗strstr
〖B〗gnirts
〖C〗strrts
〖D〗gniing
函數fun的功能是使用指針p1, p2指向字符串s的首尾, 用while循環從字符串首尾向中間遍歷, 在遍歷的過程中, 比較p1, p2指向的字符, 將ASCII碼小的字符用ASCII碼大的字符替換, 直到p1, p2在中間相遇; main函數定義字符數組x, 使用字符串"string"初始化, 接着調用fun函數, 將字符g使用s替換, 將n使用t替換, 將i使用r替換, fun函數調用結束后, 輸出x的值為:strrts, 本題答案:C
【32】設有以下語句:
int (*fp)(int *);
則下面敘述正確的是()。
〖A〗fp是一個指向函數的指針變量
〖B〗這是一條函數聲明語句
〖C〗fp是一個函數名
〖D〗(*fp)是強制類型轉換符
int (*fp)(int *)表示fp是一個函數指針, 指向一個函數, 該函數的特征是:返回值是int, 參數是int*, 選項A正確, 本題答案A。
【33】有以下程序
#include <stdio.h>
int k = 1;
int fun1(int x) {
    return (k * x);
}
int fun2(int y) {
    int k = 3;
    return (y / k);
}
void main() {
    k--;
    printf("%d\n", fun1(fun2(6)));
}
程序運行后的輸出結果是()。
〖A〗4
〖B〗2
〖C〗6
〖D〗0
題意程序中定義了一個全局變量k, 初值為1, fun1中的k是全局變量k, fun2中的k是局部變量, 這里使用f2k代替, main函數中使用的k是全局變量k; main函數中, 首先對全局變量k自減1, 此時k的值為0; 接着在printf函數中的表達式fun1(fun2(6)), 首先調用fun2(6), 返回6 / f2k, 即6 / 3 = 2, 接着調用fun1(2), 返回k * 2即0 * 2, 結果為0, 本題答案D。
【34】有以下程序
#include <stdio.h>
int fun(int *x, int n) {
    static int m = 0;
    int i, s = 0;
    for (i = m++; i < n; i++)
        s += x[i];
    return s;
}
void main() {
    int x[] = { 1, 2, 3, 4 }, k = 1;
    do {
        printf("%d,", fun(x, k));
        k++;
    } while (k < 3);
}
程序運行后的輸出結果是()。
〖A〗1,1,
〖B〗1,2,
〖C〗1,3,
〖D〗0,1,
題意中fun函數中定義了靜態變量m, 初始化值為0, for循環每次將數組x的下標區間[m, k)(左開右閉)的元素值累加作為函數返回; 對於靜態變量, 只有在第一次調用fun函數時才會初始化, 后續調用fun函數, m的值是上一次調用fun結束后的值; main函數定義了一個整型數組x, 使用4個元素初始化, k的初值為1, do...while循環中每次調用fun函數, 傳入數組x和k, 將返回值輸出, 並對k自增1, 所以:第1次循環:k = 1, m = 0, 數組x下標[0, 1)的元素是x[0], 返回值是x[0], 即1, 輸出1, 輸出后k和m的值自增1

第2次循環:k = 2, m = 1, 數組x下標[1, 2)的元素是x[1], 返回值是x[1], 即2, 輸出2, 輸出后k和m的值自增1 k此時取值為3, 循環結束

程序輸出1, 2, 本題答案:B

【35】有以下程序
#include <stdio.h>
#include <stdlib.h>
void main() {
    int i, *p1, *p2;
    p1 = p2 = (int *) calloc(5, sizeof(int));
    for (i = 0; i < 5; i++)
        *(p2 + i) = i * 10 + 1;
    printf("%d,%d\n", p2 - p1, *(p2 + 1) + *(p1 + 2));
}
程序運行后的輸出結果是()。
〖A〗4,32
〖B〗0,32
〖C〗0,22
〖D〗4,22
程序定義整型指針變量p1, p2, 調用calloc函數分配5個整型長度的內存空間賦給p1, p2, 所以p1, p2指向的是同一段內存的首地址, 接着for循環為該內存空間的各個元素賦值, 分別賦值為:1, 11, 21, 31, 41, 最后調用printf函數輸出, 其中p2 - p1等於0, p2 + 1指向第二個元素11, p1 + 2指向第三個元素21, 所以*(p1 + 1) + *(p2 + 1)輸出32, 綜上程序輸出:0, 32, 本題答案B。
【36】有以下程序
#include <stdio.h>
#define F(a, b) a > b ? (a / b) : (a % b)
#define DF(k) 2 * k
void main() {
    int a = 14, b = 8, x;
    x = DF(F(b, a));
    printf("%d\n", x);
}
程序運行后的輸出結果是()。
〖A〗6
〖B〗3
〖C〗1
〖D〗0
題意程序中有兩個宏定義, main函數中定義整型變量a, b, 分別賦值為14, 8, 接着使用兩個宏定義的結果為x賦值, 接下來我們把宏定義展開如下:F(b, a)等價於 b > a ? (b / a) : (b % a)。

DF(F(b, a))等價於2 * F(b, a), 也就等價於:2 * b > a ? (b / a) : (b % a)。

所以:x = 2 * b > a ? (b / a) : (b % a)。

條件運算符優先級高於賦值運算符, 所以原式等價於:x = (2 * b > a ? (b / a) : (b % a));
代入a, b的值:x = (2 * 8 > 14 ? (8 / 14) : (8 % 14));
x的值為0, 程序輸出0, 本題答案D

【37】設有如下定義
#include <stdio.h>
struct {
    int a;
    float b;
    double c;
    char d[5];
} s, *ps = &s;
則以下語句錯誤的是()。
〖A〗scanf("%s", *ps->d);
〖B〗scanf("%d", &(s.a));
〖C〗scanf("%f", &ps->b);
〖D〗scanf("%lf", &s.c);
s是結構體類型變量, ps是指向結構體變量s的指針, 使用結構體變量s訪問成員時, 用成員運算符".", 使用結構體指針ps訪問成員時, 使用指針運算符"->"; 選項A中scanf函數需要成員d的地址, 首先需要引用到d成員, 可以使用s.d或ps->d, 由於d是數組, 所以s.d或ps->d就表示成員d的首地址, 所以選項A是錯誤的, 其他選項正確; 本題答案A
【38】有以下程序
#include <stdio.h>
struct tt {
    int x;
    struct tt *next;
} m[5], *p = m;
void main() {
    int i;
    for (i = 0; i < 4; i++) {
        m[i].next = &m[i + 1];
        m[i].x = 2 * i + 1;
    }
    m[i].x = 0;
    m[i].next = '\0';
    printf("%d,", p++->x);
    printf("%d\n", p->x++);
}
程序運行后的輸出結果是()。
〖A〗1,3
〖B〗3,3
〖C〗3,4
〖D〗1,2
題意程序定義結構體類型tt, 定義tt類型的數組m, 它包含5個元素, 另外還定義tt類型的指針p, 初始化指向m的第一個元素; main函數中通過for循環, 將m前4個元素, 當前下標為i的元素的next成員賦值為下標為i + 1的元素地址, 另外將當前下標i的元素的x賦值為2 * i + 1, for循環結束后, 將m最后一個元素的next指針賦值為空指針, 將x賦值為0, printf函數輸出p++->x和p->x++, 對於表達式p++->x, 等價於p->x, p++, 由於當前p指向的是m[0], 所以執行后輸出m[0].x, 即1且p指向m[1], 對於表達式p->x++, 等價於(p->x)++, 當前p指向的是m[1], 所以執行后輸出m[1].x, 即輸出3, 再將m[1].x自增1, 綜上程序輸出:1, 3, 本題答案A
【39】有以下程序
#include <stdio.h>
void main() {
    char x = 020, y = 04;
    x >>= 1;
    y <<= 2;
    printf("%o\n", x ^ y);
}
程序運行后的輸出結果是()。
〖A〗0
〖B〗30
〖C〗41
〖D〗20
main函數定義字符變量x, y, 對x初始化020, 對y初始化04, 它們都是八進制數, 所以轉換成二進制:x = 10000, y = 100, 對x右移一位, x = 01000, y左移兩位, y = 10000, 再將x與y異或, 異或運算中, 若對應數值位相同, 則結果為0, 否則結果為1, 所以x ^ y結果為11000, 由於輸出格式控制符為%o, 所以需要換算成八進制輸出:30, 本題答案B
【40】關於文件的使用方式, 以下敘述中錯誤的是()。
〖A〗"w"為寫而打開文本文件, 指定文件不存在時則寫文件出錯
〖B〗"r"為讀而打開文本文件, 指定文件不存在時則讀文件出錯
〖C〗"a"為續寫數據打開文本文件, 原有內容得以保留
〖D〗"r+"為讀和寫而打開文本文件
C語言中, 打開文件使用fopen函數, 打開文件時需要指定打開方式, 其中:"w"表示為寫而打開文本文件, 如果指定的文件不存在, 系統將用在fopen調用中指定的文件名建立一個新文件, 選項A錯誤; "r"表示為讀而打開文本文件, 若指定的文件不存在, 則會出錯, 選項B正確; "a"表示為在文件后面添加數據而打開文本文件, 如果文件存在, 則文件中原有的內容將被保存, 新數據寫在原有文件之后, 選項C正確; "r+"表示為讀和寫而打開文本文件, 選項D正確; 本題答案:A

編程題

【41】給定程序中, 函數fun的功能是:根據形參c中存儲的整數序列, 將偶數下標位置所有偶數元素求和, 減去奇數下標位置所有奇數元素的和, 所得差由函數值返回。形參d中存儲的是序列的長度。
例如:若c中存儲的數值依次為 13, 15, 4, 7, 20, d為5, 則函數返回(4 + 20) - (15 + 7) = 2, 主程序輸出2。
請在程序的下划線處填入正確的內容並把下划線刪除, 使程序得出正確的結果。
注意:源程序存放在文件BLANK1.C中, 不得增行或刪行, 也不得更改程序的結構 !
(1) d
(2) c[i] % 2 != 0
(3) s0 - s1
(1) fun函數中s0表示數組c中偶數下標的偶數之和; s1表示數組c中奇數下標的奇數之和; 程序首先需要遍歷數組c的各個元素, 所以第一空為d。
(2) 在for循環中, 第一個if語句表示i為偶數且c[i]為偶數的情況下, 將c[i]累加到s0中; 第二個if語句表示i為奇數且c[i]為奇數的情況下, 將c[i]累加到s1中, 所以第二空為c[i] % 2 != 0(這里使用c[i] % 2 != 0而不使用c[i] % 2 == 1, 是因為c[i]可能為負數)。
(3) 題意要求函數返回值是數組c中偶數下標的偶數之和s0減去奇數下標的奇數之和s1, 所以第三空為s0 - s1。
【42】給定程序MODI1.C中, 函數fun的功能是:統計形參str中所出現的大寫字母的范圍跨度, 即按字典序最前面的大寫字母與最后面的大寫字母ASCII值之差, 並傳遞回主函數輸出。若沒有大寫字母, 則函數輸出0。
例如:若str的內容為"Baybye!Doom", 其中大寫字母為B和D, D與B之差為2, 函數返回2, 程序輸出2。
若str的內容為"M68C9Xaa", 其中字典序最前面的大寫字母為C, 最后面的大寫字母為X, X與C之差為21, 函數返回21, 程序輸出21。
請改正函數fun中指定部位的錯誤, 使它能得出正確的結果。
注意:不要改動main函數, 不得增行或刪行, 也不得更改程序的結構 !
(1) for (k = 0; k < strlen(str); k++)
(2) if ((str[k] >= 'A') && (str[k] <= 'Z'))
(3) str[c1] - str[c0]
(1) 根據題意, 函數fun中定義循環變量k, c0, c1, 其中k用來遍歷字符串str中的各個字符下標; c0用來存放str中字典序最前面大寫字母的下標, 初值為-1; c1用來存放str中字典序最后面大寫字母的下標, 初值為-1; 第一個for循環遍歷str, 查找str中第一個大寫字母, 並將下標賦值給c0和c1, 找到后執行break語句。
如果此時c0為-1, 表示str中沒有大寫字母, 按照題意返回0; 接着第二個for循環再次遍歷str, 所以第一個錯誤修改為for(k = 0; k < strlen(str); k++)。
(2) 第二個for循環再次遍歷str中, 判斷當前下標為k的字符是否為大寫字母, 所以需要通過if語句判斷str[k]的ASCII碼值在'A'和'Z'之間, 需要使用與運算符。
(3) 題意要求返回str中字典序最后面大寫字母與字典序最前面大寫字母的ASCII碼之差, 而c0表示存放str中字典序最前面大寫字母的下標, c1表示存放str中字典序最后面大寫字母的下標, 所以應該修改為str[c1] - str[c0]。
【43】請編寫函數fun, 其功能是:統計出x所指數組中能被e整除的所有元素, 這些元素的和通過函數值返回主函數, 元素個數通過形參num返回主函數。x所指數組的元素個數通過形參n傳入。
例如, 當數組x內容為1, 9, 8, 6, 12, 整數e內容為3時, 輸出結果應該是:sum = 27, num = 3
注意:部分源程序在文件PROG1.C中。請勿改動主函數main和其他函數中的任何內容, 僅在函數fun的花括號中填入所編寫的若干語句。
int fun(int x[], int n, int e, int *num) {
    int i, sum = 0;
    *num = 0;
    for (i = 0; i < n; i++) {
        if (x[i] % e == 0) {
            (*num)++;
            sum += x[i];
        }
    }
    return sum;
}
程序首先定義循環變量i和變量sum。
能被e整除的所有元素之和存放於變量sum。
並把num指向的存儲單元和sum賦初值為0; 接着遍歷數組x, 遍歷過程中, 判斷當前的元素x[i]是否能被e整除, 使用求余運算符%, 若求余的結果為0, 表示x[i]能被e整除, 需要對*num自增1, 並把x[i]累加到sum中。
遍歷結束后, num指針指向的存儲單元的值為數組x中能被e整除的元素個數, sum的值為數組x中能被e整除的元素之和; 函數返回sum即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM