Danh sách câu hỏi của đề

Câu hỏi: PRF192 Cơ sở lập trình – Bộ ôn tập số 2

50 câu trắc nghiệm kèm lời giải của môn PRF192 - Cơ sở lập trình, xếp đúng thứ tự trong đề.

Danh sách câu hỏi

20/50 câuCòn 30
Aint number = 10;
Bint number == 10;
Cint number : 10;
Dint number 10;
Lời giải
Đáp án đúng: "int number = 10;". Một khai báo kèm khởi tạo trong C gồm tên kiểu, tên biến, dấu bằng đơn và giá trị, kết thúc bằng dấu chấm phẩy; dấu bằng đơn ở đây là phép gán, nó ghi giá trị vào ô nhớ vừa được dành ra cho biến. Ý "int number == 10;" sai vì hai dấu bằng là phép so sánh, đặt nó vào chỗ khởi tạo khiến trình biên dịch gặp một toán tử không được phép trong khai báo và báo lỗi cú pháp. Ý "int number : 10;" sai vì dấu hai chấm không phải toán tử gán, nó chỉ xuất hiện trong nhãn, trong toán tử điều kiện hoặc trong khai báo trường bit của cấu trúc. Ý "int number 10;" sai vì thiếu hẳn toán tử gán: trình biên dịch đọc xong tên biến lại thấy một hằng số nên không ghép được thành câu lệnh nào.
Mở trang câu hỏi này →
AA module performs its tasks independently.
BA module shares performance with other modules.
CA module accesses global data.
DA module depends on many other modules.
Lời giải
Đáp án đúng: "A module performs its tasks independently.". Mức liên kết giữa các mô đun đo xem một mô đun phải biết và phải dựa vào bao nhiêu thứ bên ngoài để làm xong việc của nó. Liên kết thấp nghĩa là mô đun nhận dữ liệu qua tham số, trả kết quả qua giá trị trả về và tự lo phần việc của mình, nhờ vậy sửa hay thay nó không kéo theo sửa chỗ khác. Ý "A module shares performance with other modules." sai vì chia sẻ phần xử lý với nhiều mô đun khác làm tăng số đường phụ thuộc, đó là liên kết cao. Ý "A module accesses global data." sai vì dữ liệu toàn cục là kênh ngầm giữa các mô đun, ai cũng sửa được nên không ai dám đoán trạng thái, đây là dạng liên kết đặc biệt khó tháo. Ý "A module depends on many other modules." sai vì nó chính là định nghĩa của liên kết cao, trái hẳn điều câu hỏi đang hỏi.
Mở trang câu hỏi này →
3What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int x = 5, y = 10;

    if (x >= y) {
        printf("x is greater than or equal to y\n");
    } else {
        printf("x is less than y\n");
    }
    return 0;
}
Ax is greater than or equal to y
Bx is less than y
Cx is equal to y
DCompilation error
Lời giải
Đáp án đúng: "x is less than y". Điều kiện so sánh x lớn hơn hoặc bằng y được tính với x bằng 5 và y bằng 10; 5 không lớn hơn mà cũng không bằng 10 nên biểu thức cho 0, tức là sai, vì thế khối sau if bị bỏ qua và khối sau else được chạy. Chỉ một trong hai khối được chạy, đó là bản chất của cấu trúc rẽ nhánh hai đường. Ý "x is greater than or equal to y" sai vì đó là chuỗi nằm trong khối chỉ chạy khi điều kiện đúng, điều không xảy ra với bộ giá trị này. Ý "x is equal to y" sai vì trong mã không có chuỗi nào như vậy, chương trình chỉ in được một trong hai chuỗi đã viết sẵn. Ý "Compilation error" sai vì mọi biến đều được khai báo, hai khối đều có cặp ngoặc nhọn đầy đủ và các lời gọi printf đều hợp lệ.
Mở trang câu hỏi này →
Aif (strcmp(s1, s2) >= 0)
Bif (strcmp(s1, s2) < 0)
Cif (strlen(s1) >= strlen(s2))
Dif (s1 >= s2)
Lời giải
Đáp án đúng: "if (strcmp(s1, s2) >= 0)". Thứ tự giữa hai chuỗi trong C do strcmp quyết định: hàm này so từng cặp ký tự theo mã, dừng ở chỗ đầu tiên khác nhau và trả về số dương khi chuỗi thứ nhất lớn hơn, số âm khi bé hơn, 0 khi trùng nhau; vậy điều kiện lớn hơn hoặc bằng tương ứng với kết quả không âm. Ý "if (strcmp(s1, s2) < 0)" sai vì nó thử điều ngược lại, chuỗi thứ nhất bé hơn. Ý "if (strlen(s1) >= strlen(s2))" sai vì nó chỉ đo độ dài, trong khi thứ tự từ điển phụ thuộc nội dung từng ký tự; một chuỗi dài hơn vẫn có thể bé hơn. Ý "if (s1 >= s2)" sai vì tên mảng chuỗi được chuyển thành địa chỉ phần tử đầu, nên phép so sánh đó đối chiếu hai địa chỉ trong bộ nhớ, không liên quan gì tới nội dung.
Mở trang câu hỏi này →
A1 byte
B2 bytes
C4 bytes
D8 bytes
Lời giải
Đáp án đúng: "4 bytes". Kiểu float được hiện thực theo dạng dấu phẩy động độ chính xác đơn của chuẩn IEEE 754, gồm 1 bit dấu, 8 bit số mũ và 23 bit phần định trị, cộng lại đúng 32 bit tức 4 byte; đây là kích thước trên mọi nền tảng phổ thông, và cách kiểm chắc chắn nhất vẫn là in sizeof của kiểu. Ý "1 byte" sai vì đó là kích thước của char, chuẩn quy định sizeof của char luôn bằng 1. Ý "2 bytes" sai vì đó là kích thước thường gặp của short, một kiểu nguyên chứ không phải kiểu thực. Ý "8 bytes" sai vì đó là độ chính xác kép, tức kiểu double; chính vì double rộng gấp đôi nên nó giữ được nhiều chữ số có nghĩa hơn float.
Mở trang câu hỏi này →
AChanging from one form of representation to another
BA category of data that represents individual, non-complex elements such as integers, floating-point numbers, and characters
CPerforming operations and expressions on data
DStoring a collection of elements accessible by an index or a key
Lời giải
Đáp án đúng: "A category of data that represents individual, non-complex elements such as integers, floating-point numbers, and characters". Kiểu dữ liệu đơn giản là những kiểu mà mỗi giá trị là một đơn vị trọn vẹn, không tách ra thành các thành phần nhỏ hơn có tên riêng, và được ngôn ngữ dựng sẵn cùng bộ phép toán của nó. Chúng đứng đối lập với kiểu có cấu trúc như mảng hay struct, nơi một giá trị gom nhiều phần tử. Ý "Changing from one form of representation to another" sai vì đó mô tả việc chuyển đổi biểu diễn hoặc chuyển kiểu, một hành động chứ không phải một nhóm kiểu. Ý "Performing operations and expressions on data" sai vì đó nói về phép toán và biểu thức, tức cách xử lý dữ liệu. Ý "Storing a collection of elements accessible by an index or a key" sai vì đó đúng là định nghĩa của kiểu có cấu trúc, trái hẳn tính không phức hợp mà câu hỏi nhắc tới.
Mở trang câu hỏi này →
7What will be the output of the C program?4 lựa chọncó code
Đề bài
char temp;
char arr[10] = {1, 2, 3, 4, 5, 6, 7, 8};
temp = (arr + 1)[2];
printf("%d\n", temp);
A1
B2
C3
D4
Lời giải
Đáp án đúng: "4". Cách viết chỉ số trong C chỉ là đường tắt của phép tính trên con trỏ: viết x[i] đồng nghĩa với lấy nội dung tại x cộng i. Vì vậy (arr + 1)[2] chính là lấy nội dung tại arr cộng 1 cộng 2, tức là arr[3]. Mảng được khởi tạo bằng các số từ 1 đến 8 nên arr[3] mang giá trị 4; kiểu phần tử là char nhưng các giá trị khởi tạo là số nguyên nhỏ, và đặc tả %d in ra số 4 chứ không in ký tự. Ý "1" sai vì 1 nằm ở arr[0], giá trị đó chỉ ra nếu bỏ cả hai lượng cộng. Ý "2" sai vì 2 nằm ở arr[1], ứng với việc chỉ cộng 1 mà bỏ mất chỉ số 2. Ý "3" sai vì 3 nằm ở arr[2], đó là kết quả nếu quên lượng cộng 1 và chỉ đọc arr[2].
Mở trang câu hỏi này →
ADataType ArrayName[NumberOfElements];
BArrayName DataType[NumberOfElements];
CDataType[NumberOfElements] ArrayName;
D[NumberOfElements] DataType ArrayName;
Lời giải
Đáp án đúng: "DataType ArrayName[NumberOfElements];". Khai báo mảng tĩnh đi theo đúng lối đọc khai báo của C: tên kiểu đứng trước cho biết mỗi phần tử trông thế nào, rồi tên biến, rồi số phần tử đặt trong cặp ngoặc vuông ngay sau tên; từ hai thông tin đó trình biên dịch tính ra tổng số byte phải dành và bước nhảy giữa các phần tử. Ý "ArrayName DataType[NumberOfElements];" sai vì tên biến bị đặt lên trước tên kiểu, trật tự này trình biên dịch không hiểu. Ý "DataType[NumberOfElements] ArrayName;" sai vì cặp ngoặc vuông phải gắn vào tên biến chứ không gắn vào tên kiểu, đó là cú pháp của một số ngôn ngữ khác. Ý "[NumberOfElements] DataType ArrayName;" sai vì không có khai báo nào trong C được mở đầu bằng cặp ngoặc vuông.
Mở trang câu hỏi này →
Acopy strings
Bcontcatenate (joins) two strings
Ccompare two strings
Lời giải
Đáp án đúng: "copy strings". Hàm strcpy trong string.h nhận con trỏ đích rồi con trỏ nguồn, sao chép lần lượt từng byte của chuỗi nguồn sang vùng nhớ đích và chép luôn ký tự kết thúc chuỗi, nên sau lệnh gọi thì vùng đích mang đúng nội dung của chuỗi nguồn; chính cái tên cpy đã là viết tắt của copy. Cách hiểu "contcatenate (joins) two strings" mô tả việc nối hai chuỗi, đó là việc của strcat: hàm đó đi tìm ký tự kết thúc của chuỗi đích rồi ghi tiếp chuỗi nguồn từ chỗ ấy, giữ lại nội dung cũ, khác hẳn kiểu ghi đè từ byte đầu tiên của strcpy. Cách hiểu "compare two strings" mô tả việc so sánh, đó là việc của strcmp: hàm này không ghi gì vào bộ nhớ mà chỉ trả về số nguyên âm, bằng không hay dương theo thứ tự từ điển. Bản chất phải nhớ là C không có kiểu chuỗi thật, strcpy chỉ chép byte nên vùng đích phải tự đủ chỗ cho cả ký tự kết thúc.
Mở trang câu hỏi này →
A1
B0
C-1
Lời giải
Đáp án đúng: "-1". Hàm strcmp so sánh hai chuỗi theo từng byte cho tới vị trí đầu tiên khác nhau rồi trả về dấu của hiệu hai mã ký tự tại vị trí đó. Hai chuỗi abcdef và abdc trùng nhau ở hai ký tự đầu, đến vị trí thứ ba thì một bên là c có mã 99, bên kia là d có mã 100, hiệu là số âm nên hàm trả về giá trị âm, và trong danh sách chỉ có đúng một số âm. Giá trị "1" ứng với trường hợp chuỗi thứ nhất lớn hơn theo thứ tự từ điển, tức ký tự khác nhau đầu tiên của nó phải có mã lớn hơn, điều không xảy ra ở đây. Giá trị "0" chỉ xuất hiện khi hai chuỗi giống nhau hoàn toàn kể cả độ dài, còn abcdef và abdc đã lệch ngay ký tự thứ ba nên hàm dừng tại đó mà không cần xét phần còn lại. Bản chất cần nhớ: chuẩn C chỉ bảo đảm dấu của kết quả, trị tuyệt đối do thư viện quyết định, nên luôn đọc kết quả theo dấu.
Mở trang câu hỏi này →
Astrcat()
Bstrcpy()
Cputs()
Dscanf()
Lời giải
Đáp án đúng: "strcpy()". Trong C, phép gán không chép được nội dung mảng ký tự, nên muốn nhân bản một chuỗi phải tự chạy vòng lặp hoặc gọi hàm chuyên dụng; strcpy đi từ byte đầu của chuỗi nguồn, ghi sang vùng đích cho tới khi chép xong ký tự kết thúc chuỗi, nhờ đó vùng đích trở thành một chuỗi hợp lệ. Hàm "strcat()" cũng ghi vào đích nhưng là nối thêm: nó bỏ qua phần nội dung cũ, bắt đầu ghi đúng tại ký tự kết thúc của đích, nên không thay thế được việc chép. Hàm "puts()" chỉ đẩy một chuỗi ra màn hình kèm ký tự xuống dòng, không tạo bản sao nào trong bộ nhớ. Hàm "scanf()" là hàm đọc dữ liệu có định dạng, nguồn của nó là dòng nhập từ bàn phím chứ không phải một chuỗi đã có trong chương trình, nên nó không làm việc nhân bản nội dung giữa hai vùng nhớ.
Mở trang câu hỏi này →
Aif
Bswitch
Cwhile
Dfor
Lời giải
Đáp án đúng: "switch". Lệnh switch tính một biểu thức nguyên rồi so khớp giá trị ấy với các hằng ghi ở từng nhãn case, nhờ đó nhiều trường hợp rời rạc của cùng một biến được xếp cạnh nhau thành một bảng dễ đọc; trình biên dịch còn có thể dựng bảng nhảy để tới thẳng nhánh đúng thay vì thử lần lượt. Lệnh "if" cũng rẽ nhánh được nhưng mỗi lần chỉ xét một biểu thức đúng hoặc sai, muốn phủ nhiều giá trị thì phải viết chuỗi else if dài, lặp lại tên biến và mất hẳn dạng bảng. Lệnh "while" là vòng lặp kiểm điều kiện trước mỗi lần chạy, nhiệm vụ của nó là lặp lại công việc chứ không phải chọn một nhánh trong nhiều nhánh. Lệnh "for" cũng là vòng lặp, chỉ gói sẵn phần khởi tạo, điều kiện và cập nhật trong một cặp ngoặc; dùng nó để chọn trường hợp là đi lệch công dụng của cấu trúc.
Mở trang câu hỏi này →
Đề bài
    #include <stdio.h>
    int main()
    {
        int a = 1;
        switch (a)
        case 1:
            printf("%d", a);
        case 2:
            printf("%d", a);
        case 3:
            printf("%d", a);
        return 0;
}
ANo error, output is 1111
BNo error, output is 1
CCompile time error, no break statements
DCompile time error, case label outside switch statement
Lời giải
Đáp án đúng: "Compile time error, case label outside switch statement". Phạm vi của một khối do ngoặc nhọn quyết định, không do thụt lề: sau switch (a) ở đây không có ngoặc nhọn nào, nên thân của switch chỉ ôm đúng một lệnh, và lệnh đó là lệnh mang nhãn case 1 kèm lời gọi in giá trị a. Hai nhãn case 2 và case 3 viết tiếp phía sau đã nằm ngoài thân switch dù được thụt vào, mà nhãn case chỉ hợp lệ bên trong một switch, nên trình biên dịch dừng với lỗi nhãn case nằm ngoài lệnh switch. Kết luận "No error, output is 1111" sai cả hai mặt: chương trình không dịch được, và trong mã cũng chỉ có ba lệnh in. Kết luận "No error, output is 1" cũng giả định dịch được, hơn nữa nếu các nhãn đều nằm trong thân switch thì do không có break nên các nhánh sau vẫn chạy tiếp. Kết luận "Compile time error, no break statements" đúng chuyện có lỗi nhưng sai nguyên nhân: thiếu break không phải lỗi, đó là hành vi rơi xuống nhánh dưới mà chuẩn cho phép.
Mở trang câu hỏi này →
AThe color of the variable
BHow much space the variable needs in memory
CHow fast the variable runs
DThe name of the variable
Lời giải
Đáp án đúng: "How much space the variable needs in memory". Khi khai báo một biến, kiểu dữ liệu là thứ nói cho trình biên dịch biết phải dành bao nhiêu byte cho biến đó, đồng thời quyết định cách diễn giải dãy bit ấy và tập phép toán hợp lệ trên nó; cùng một ô nhớ bốn byte có thể là số nguyên có dấu hoặc số thực tuỳ kiểu đã khai. Mô tả "The color of the variable" không mang nghĩa nào trong C, biến là một vùng nhớ chứ không phải đối tượng hiển thị. Mô tả "How fast the variable runs" lẫn lộn khái niệm: biến không chạy, tốc độ là chuyện của mã máy sinh ra cho các phép toán, dù kiểu rộng hơn có thể khiến phép tính tốn thêm lệnh. Mô tả "The name of the variable" lẫn tên với kiểu: tên do người lập trình đặt và chỉ là nhãn cho vị trí nhớ, hai biến khác tên vẫn có thể cùng kiểu, còn một biến thì không thể có hai kiểu.
Mở trang câu hỏi này →
A=
B||
C==
D!=
Lời giải
Đáp án đúng: "=". Dấu bằng đơn là phép gán: nó ghi giá trị của biểu thức bên phải vào ô nhớ bên trái rồi trả về chính giá trị vừa ghi, nên nó thuộc nhóm toán tử gán chứ không so sánh cũng không tổ hợp điều kiện. Đây là cái bẫy kinh điển của C, bởi viết if với một dấu bằng vẫn dịch được mà ý nghĩa đã khác hẳn phép so sánh bằng. Ý "||" sai vì đó là phép hoặc luận lý, nhận hai điều kiện và cho 1 khi có ít nhất một điều kiện đúng. Ý "==" sai vì đó là phép so sánh bằng, trả về 1 hoặc 0 tuỳ hai toán hạng có bằng nhau hay không. Ý "!=" sai vì đó cũng là một phép so sánh, nó kiểm tra hai toán hạng khác nhau và trả về 1 hoặc 0.
Mở trang câu hỏi này →
Astring a;
Bfloat a = 3e2;
Cint* a;
Dfloat *a;
Echar * a;
Lời giải
Đáp án đúng: "string a;". C không có kiểu chuỗi dựng sẵn; một chuỗi trong C là mảng char kết thúc bằng ký tự có mã 0, vì vậy tên kiểu string không tồn tại trong ngôn ngữ và dòng khai báo đó chỉ dịch được nếu chính người lập trình tạo ra cái tên ấy bằng typedef hoặc struct. Khai báo "float a = 3e2;" hợp lệ, vì 3e2 là cách viết khoa học của 300.0, một hằng số thực. Khai báo "int* a;" hợp lệ, dấu sao viết sát tên kiểu chỉ là cách trình bày, trình biên dịch vẫn đọc ra con trỏ tới int. Khai báo "float *a;" cũng vậy, khoảng trắng quanh dấu sao không mang nghĩa nào với bộ phân tích cú pháp. Khai báo "char * a;" là con trỏ tới char, dạng quen dùng để trỏ vào chuỗi, hoàn toàn đúng cú pháp. Bốn dòng vừa nêu đều là khai báo chuẩn, chỉ cái tên kiểu không hề tồn tại mới bị loại.
Mở trang câu hỏi này →
Đề bài
#include<stdio.h>
#include<ctype.h>
int main()
{
    char a[] = "hello world";
    int i = 0;
    while (!isspace(a[i]))
        i++;
    printf("%d, %c", i, a[i-1]);
    return 0;
}
A0, h
B5, o
C5,
D5, w
Lời giải
Đáp án đúng: "5, o". Mảng a chứa chuỗi hello world, chỉ số đếm từ 0 nên a[0] là h cho tới a[4] là o, còn a[5] là dấu cách. Vòng while còn chạy khi isspace(a[i]) trả về 0, nghĩa là còn ký tự thường thì i cứ tăng: i lần lượt qua 0, 1, 2, 3, 4 rồi thành 5; tại i bằng 5 hàm isspace gặp dấu cách nên trả về giá trị khác 0, phép phủ định cho sai và vòng lặp dừng với i bằng 5. Lệnh in xuất ra i là 5 rồi tới a[i-1] tức a[4] là o. Kết quả "0, h" chỉ xảy ra nếu ký tự đầu tiên đã là khoảng trắng, mà khi đó a[i-1] còn đọc ra ngoài mảng. Kết quả "5," ứng với việc in a[5] là dấu cách, nhưng mã in a[i-1] chứ không phải a[i]. Kết quả "5, w" ứng với a[6], ký tự ngay sau dấu cách, lệch một vị trí so với chỗ mà lệnh in thật sự lấy.
Mở trang câu hỏi này →
A5
B22
C18
D25
E28
Lời giải
Đáp án đúng: "25". Hằng 0x11 viết ở hệ mười sáu nên có giá trị 17 với dãy bit 10001; hằng 010 mở đầu bằng chữ số 0 nên C đọc là hệ tám, giá trị 8 với dãy bit 01000. Phép hoặc theo bit xét từng cặp bit và bật kết quả khi có ít nhất một bên bật, cho 11001, tức 25. Một tính chất giúp loại nhanh: phép hoặc chỉ bật thêm bit, không bao giờ tắt bit đang bật, nên kết quả không thể nhỏ hơn 17. Vì thế giá trị "5" bị loại ngay, nó còn nhỏ hơn cả toán hạng thứ nhất. Giá trị "22" có dãy bit 10110, vừa tắt mất bit thấp nhất mà 17 đang bật, vừa bật bit giá trị 4 mà không toán hạng nào bật. Giá trị "18" có dãy bit 10010, cũng tắt bit thấp nhất của 17 nên không thể là kết quả. Giá trị "28" có dãy bit 11100, mất bit thấp nhất và tự sinh bit giá trị 4, đó là kiểu sai do cộng dồn chứ không phải do lấy hoặc theo bit.
Mở trang câu hỏi này →
Awhile (condition) {...}
Bwhile (initialization; condition) {...}
Cwhile (condition; increment) {...}
Dwhile (initialization; increment; condition) {...}
Lời giải

Đáp án đúng: "

Lời giải
while (condition) {
  ...
}

". Lệnh while trong C chỉ nhận duy nhất một biểu thức trong cặp ngoặc tròn; biểu thức đó được tính trước mỗi lần chạy thân và vòng lặp còn tiếp khi giá trị khác 0, nên mọi việc khởi tạo phải làm trước vòng lặp còn việc cập nhật phải nằm trong thân. Khuôn "

Lời giải
while (initialization; condition) {
  ...
}

" đưa phần khởi tạo vào trong ngoặc, đó là thành phần riêng của for, hơn nữa dấu chấm phẩy không được phép xuất hiện trong ngoặc điều kiện. Khuôn "

Lời giải
while (condition; increment) {
  ...
}

" mắc đúng lỗi ấy: phần tăng giảm phải là một lệnh trong thân chứ không phải vế thứ hai của điều kiện. Khuôn "

Lời giải
while (initialization; increment; condition) {
  ...
}

" là khuôn ba phần của for và còn xếp sai trật tự, vì trong for thì điều kiện đứng giữa còn phần cập nhật đứng cuối.

Mở trang câu hỏi này →
Ado{ statements; } while(condition) ;
Bdo while(condition) { statements;}
Cdo{ statements; } while (condition)
Ddo( statements;) while (condition) ;
Lời giải

Đáp án đúng: "do{ statements; } while(condition) ; ". Vòng do-while chạy thân trước rồi mới kiểm điều kiện, và cả cấu trúc đó được ngôn ngữ coi là một lệnh duy nhất, nên bắt buộc phải kết thúc bằng dấu chấm phẩy ngay sau ngoặc điều kiện; thân có nhiều lệnh thì gom trong cặp ngoặc nhọn. Khuôn "do

Lời giải
while(condition) {
  statements;
}

" đặt điều kiện trước thân, thành ra do không có thân nào đi kèm còn khối phía sau trở thành một khối rời, sai hẳn trật tự của cấu trúc. Khuôn "do{ statements; } while (condition)" đúng mọi thứ trừ dấu chấm phẩy kết thúc, mà thiếu nó thì trình biên dịch coi lệnh chưa viết xong và báo lỗi cú pháp. Khuôn "do( statements;) while (condition) ; " dùng ngoặc tròn để gom lệnh, nhưng trong C chỉ cặp ngoặc nhọn mới tạo được khối lệnh, ngoặc tròn chỉ dành cho biểu thức và danh sách tham số.

Mở trang câu hỏi này →