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

Câu hỏi: PRF192 Cơ sở lập trình – Đề thi cuối kỳ SU26

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
AC has object-oriented features.
BC is English-like
CC is faster and more powerful than other high-level languages.
DC supports basic ways to understand the memory of a program
Lời giải
Đáp án đúng: "C has object-oriented features." Ngôn ngữ C không có lớp, đối tượng, kế thừa hay đa hình, nên đặc tính hướng đối tượng không thể là lý do chọn C làm ngôn ngữ đầu tiên; muốn những thứ đó phải sang ngôn ngữ khác. "C is English-like" là lý do có thật được nêu, các từ khoá if, else, while, return đọc gần như tiếng Anh nên người mới dễ đoán ý. "C is faster and more powerful than other high-level languages." cũng là lý do được nêu, mã C dịch ra mã máy gọn và cho phép làm việc sát phần cứng. "C supports basic ways to understand the memory of a program" là lý do quan trọng nhất về mặt học thuật: con trỏ, địa chỉ và cấp phát động buộc người học hình dung bộ nhớ thật thay vì coi nó là chuyện trừu tượng.
Mở trang câu hỏi này →
AThe comment mark will be removed. The content of the comments will be compiled line by line.
BThe comment is treated as an array of characters.
CComments are removed in the pre-processing step.
DEach comment is compiled as a statement that does nothing.
Lời giải
Đáp án đúng: "Comments are removed in the pre-processing step." Chú thích chỉ dành cho người đọc, không mang nghĩa gì với máy, nên nó bị loại bỏ ngay ở bước tiền xử lý, trước khi khâu phân tích cú pháp nhìn tới mã; mỗi chú thích được thay bằng một khoảng trắng, vì vậy mã máy sinh ra không đổi dù chú thích dài hay ngắn. "The comment mark will be removed. The content of the comments will be compiled line by line." sai vì nội dung chú thích không bao giờ được biên dịch; nếu biên dịch thì mọi câu văn trong chú thích đều thành lỗi cú pháp. "The comment is treated as an array of characters." sai vì chỉ chuỗi nằm trong dấu nháy kép mới trở thành mảng ký tự trong bộ nhớ, chú thích không sinh ra byte dữ liệu nào. "Each comment is compiled as a statement that does nothing." sai vì không có lệnh rỗng nào được sinh ra, chương trình dịch xong không còn dấu vết của chú thích.
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 →
ACompile time error
BRun time error
CInput error
DLinking error
Lời giải
Đáp án đúng: "Compile time error". Lỗi cú pháp là chuyện vi phạm quy tắc viết của ngôn ngữ, chẳng hạn thiếu dấu chấm phẩy hay lệch cặp ngoặc, nên trình biên dịch phát hiện ngay khi phân tích mã nguồn và từ chối sinh tệp thực thi; chương trình chưa từng chạy nên không thể có lỗi lúc chạy. "Run time error" là loại khác, chỉ xuất hiện khi tệp thực thi đã chạy, như chia cho 0 hay truy cập con trỏ rỗng, lúc đó cú pháp vốn đã đúng. "Input error" nói về dữ liệu người dùng nhập sai khuôn dạng, thuộc phạm vi kiểm tra của chính chương trình, không liên quan tới cách viết mã. "Linking error" xảy ra sau khâu biên dịch, khi bộ liên kết không tìm thấy định nghĩa của một hàm đã khai báo, tức mã từng dịch thành công rồi mới vỡ.
Mở trang câu hỏi này →
5What will the following code output?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int a = 5, b = 3;
    printf("%d", a & b);
    return 0;
}
A1
B2
C3
D5
Lời giải
Đáp án đúng: "1". Một dấu và đơn lẻ là phép và theo từng bit, khác hẳn hai dấu và của phép và logic. Viết 5 ở hệ hai là 0101, viết 3 là 0011; ghép từng cặp bit cùng vị trí, chỉ chỗ nào cả hai đều bằng 1 mới cho 1, nên kết quả là 0001, tức 1, và printf in nó bằng %d. Số "2" ở hệ hai là 0010, nó đòi bit thứ hai bằng 1 trong cả hai toán hạng, nhưng 5 không có bit đó. Số "3" là chính giá trị của b, ứng với việc hiểu nhầm dấu và thành phép lấy toán hạng bên phải. Số "5" là chính giá trị của a, ứng với việc hiểu nhầm thành phép lấy toán hạng bên trái; cả hai cách hiểu đó đều bỏ qua việc so từng bit, thứ làm nên bản chất của toán tử này.
Mở trang câu hỏi này →
Aconst
Bdefine
Cconstant
Dnamed
Lời giải
Đáp án đúng gồm hai ý: "const" và "define". Trong C có hai cách đặt tên cho một giá trị bất biến: từ khoá const gắn vào khai báo biến, bắt trình biên dịch chặn mọi phép gán lại; và chỉ thị tiền xử lý #define, thay tên bằng dãy ký tự giá trị trước khi biên dịch. Cần công bố một khuyết điểm của đề: câu ghi rõ chọn hai nhưng bản khoá in kèm chỉ tô được một ô, nên lời giải này dựng lại cặp đáp án từ chính quy tắc của ngôn ngữ chứ không đọc được từ khoá. "constant" không phải từ khoá của C, nó chỉ là từ tiếng Anh chỉ khái niệm hằng, viết vào mã sẽ bị xem là tên tự đặt và gây lỗi. "named" cũng không phải từ khoá, nó chỉ là tính từ trong cụm hằng có tên, trình biên dịch không hiểu gì.
Mở trang câu hỏi này →
A2 bytes
B1 byte
C8 bytes
D4 bytes
Lời giải
Đáp án đúng: "4 bytes". Trên gần như mọi trình dịch C hiện hành, float là số thực theo chuẩn IEEE 754 độ chính xác đơn: ba mươi hai bit chia thành một bit dấu, tám bit số mũ và hai mươi ba bit phần định trị, tức đúng bốn byte, và sizeof(float) trả về 4. Số "2 bytes" là kích thước thường thấy của short int, không có kiểu thực chuẩn nào nhỏ như vậy. Số "1 byte" là kích thước của char, kiểu mà chuẩn ấn định bằng một byte, quá nhỏ để chứa cả dấu, số mũ và phần định trị. Số "8 bytes" là kích thước của double, bản độ chính xác kép với mười một bit số mũ và năm mươi hai bit định trị; chính vì gấp đôi chỗ mà double giữ được nhiều chữ số nghĩa hơn float.
Mở trang câu hỏi này →
8Given the following code snippet:4 lựa chọncó code
Đề bài
#include <stdio.h>
#define MONTHS_IN_YEAR 12
int main() {
    const int WORKING_DAYS = 22;
    printf("%d ", MONTHS_IN_YEAR);
    printf("%d", WORKING_DAYS);
    return 0;
}

Choose the correct statement:

AThe output will be: 12 22
BNo output
CCompile error
DRuntime error
Lời giải
Đáp án đúng: "The output will be: 12 22". Dòng define là chỉ thị tiền xử lý: trước khi dịch, mọi chỗ viết MONTHS_IN_YEAR bị thay bằng dãy ký tự 12, nên lệnh in đầu nhận hằng số 12. Biến WORKING_DAYS khai báo const int kèm giá trị khởi tạo là hợp lệ, vì const chỉ ngăn gán lại về sau chứ không ngăn khởi tạo, nên lệnh in thứ hai cho 22. Chuỗi định dạng đầu có dấu cách sau %d nên hai số cách nhau một khoảng. Kết luận "No output" sai vì cả hai lệnh printf đều chạy với đối số hợp lệ. Kết luận "Compile error" sai vì không có vi phạm nào: tên hằng viết hoa chỉ là quy ước, và const int khởi tạo ngay là lối dùng đúng. Kết luận "Runtime error" sai vì chương trình chỉ in hai số nguyên rồi trả về 0, không chạm tới vùng nhớ nào có thể gây lỗi.
Mở trang câu hỏi này →
A0
B1
C10
D11
Lời giải
Đáp án đúng: "0". Dấu chấm than là phép phủ định logic trên một toán hạng: C coi mọi giá trị khác không là đúng và chỉ số không là sai, còn kết quả của phép logic luôn là int mang giá trị 0 hoặc 1. Toán hạng 1 là đúng nên phủ định nó cho sai, tức 0. Số "1" là kết quả của phép phủ định hai lần, hoặc là chính toán hạng ban đầu khi quên áp phép toán. Số "10" ứng với cách hiểu nhầm dấu chấm than thành phép ghép ký tự, như thể viết 1 rồi 0 cạnh nhau; C không có phép nối số kiểu đó. Số "11" cũng là một dãy ký tự ghép lại, lại thêm hiểu nhầm rằng phủ định của 1 vẫn là 1. Cần phân biệt phủ định logic với đảo bit, vì đảo bit của 1 trên int bốn byte cho -2.
Mở trang câu hỏi này →
A14
B3
C10
D0
Lời giải
Đáp án đúng: "3". Trong hằng chuỗi, dãy gồm dấu chéo ngược và số không là một ký tự duy nhất, chính là byte rỗng dùng để đánh dấu kết thúc chuỗi. Khi trình dịch dựng hằng này, vùng nhớ lần lượt chứa ba chữ in hoa của FPT, một byte rỗng, mười chữ của University, rồi một byte rỗng nữa, tổng cộng mười lăm byte. Hàm strlen đi từ byte đầu và dừng ở byte rỗng đầu tiên, nên nó chỉ đếm được ba ký tự. Số "14" là số chữ cái nhìn thấy trên mặt chữ, tức cách đếm bỏ qua ý nghĩa của byte rỗng. Số "10" là độ dài của phần đứng sau byte rỗng, phần mà strlen không bao giờ chạm tới. Số "0" chỉ đúng nếu ký tự đầu tiên đã là byte rỗng, trong khi ở đây byte đầu là một chữ in hoa.
Mở trang câu hỏi này →
11What is printed?4 lựa chọncó code
Đề bài
char sentence[81] = "This is a test";
int n = strlen(sentence);
printf("%d", n);
A13
B14
C15
DCompilation error
Lời giải
Đáp án đúng: "14". Mảng sentence có tám mươi mốt ô nhưng được khởi tạo từ hằng chuỗi, nên chỉ phần đầu mang nội dung, ô ngay sau chữ cuối giữ byte rỗng kết thúc và các ô còn lại cũng bằng không. Hàm strlen đếm số ký tự tới trước byte kết thúc, kể cả dấu cách: bốn chữ của This, một dấu cách, hai chữ của is, một dấu cách, một chữ a, một dấu cách rồi bốn chữ của test, cộng lại đúng 14. Số "13" là kết quả khi bỏ sót một dấu cách, lỗi đếm thường gặp vì dấu cách không nhìn thấy rõ. Số "15" là số byte chuỗi thật sự chiếm, tức mười bốn ký tự cộng byte kết thúc. Kết luận "Compilation error" sai vì khởi tạo mảng char tám mươi mốt ô bằng một chuỗi ngắn hơn là hợp lệ.
Mở trang câu hỏi này →
Aint a = 25;
Ba = 25;
CInt a = 25;
Da = (Int) 25;
Lời giải
Đáp án đúng: "int a = 25;". Một khai báo đầy đủ cần tên kiểu đứng trước, rồi tên biến, và có thể kèm dấu bằng với giá trị khởi tạo; int là từ khoá kiểu nguyên viết toàn chữ thường, nên dòng này vừa tạo biến vừa gán giá trị đầu cho nó. Dòng "a = 25;" chỉ là một phép gán, nó đòi a phải được khai báo ở đâu đó trước; chuẩn C hiện hành đã bỏ luật ngầm hiểu kiểu int nên dòng này không tự tạo ra biến. Dòng "Int a = 25;" sai vì C phân biệt chữ hoa chữ thường, từ viết hoa đó không phải từ khoá mà bị coi là một tên kiểu chưa từng định nghĩa. Dòng "a = (Int) 25;" mắc cả hai lỗi cùng lúc: không có khai báo kiểu cho a, và phép ép kiểu lại viện tới một tên kiểu không tồn tại.
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 →
14What does a variable store in memory?4 lựa chọn
ACompiler instructions
BDebug information
CBinary data
DMemory addresses of other programs
Lời giải
Đáp án đúng: "Binary data". Biến là một vùng ô nhớ được đặt tên, mà bộ nhớ chỉ lưu được các bit, nên mọi thứ nằm trong biến đều là dữ liệu nhị phân; kiểu của biến chỉ là cách trình biên dịch quy định đọc dãy bit đó thành số nguyên, số thực hay ký tự. "Compiler instructions" sai vì chỉ thị dành cho trình biên dịch tồn tại trong mã nguồn và biến mất sau khi dịch, chúng không được lưu vào biến lúc chạy. "Debug information" sai vì thông tin gỡ lỗi nằm ở các phần riêng của tệp thực thi do trình biên dịch sinh ra, không nằm trong biến của chương trình. "Memory addresses of other programs" sai vì một biến con trỏ chỉ giữ địa chỉ trong không gian nhớ của chính tiến trình này; hệ điều hành không cho chương trình này chạm vào vùng nhớ của chương trình khác.
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 →
AIdentification
BName
CDeclaration
DDefinition
Lời giải
Đáp án đúng: "Declaration". Khai báo là câu lệnh cho trình biên dịch biết một tên sẽ tồn tại và mang kiểu gì; nhờ có kiểu, trình biên dịch mới biết dành bao nhiêu byte và hiểu dãy bit ấy theo nghĩa nào, nên thuật ngữ chỉ việc nêu đồng thời kiểu và tên chính là khai báo. "Identification" không phải thuật ngữ của C cho việc này; từ gần nó là identifier, chỉ riêng cái tên do người viết đặt. "Name" chỉ nói tới phần tên, không mang thông tin kiểu, nên không đủ để trình biên dịch làm việc. "Definition" là bước mạnh hơn, nó vừa khai báo vừa cấp chỗ thật trong bộ nhớ hoặc viết thân hàm; với hàm thì nguyên mẫu đặt ở đầu tệp là khai báo, còn phần thân mới là định nghĩa.
Mở trang câu hỏi này →
AIt improves code portability
BIt makes the code shorter
CIt prevents the use of symbolic names
DIt increases code complexity
Lời giải
Đáp án đúng: "It improves code portability". Giá trị thần bí nằm rải rác trong mã là nguồn lỗi khi phải chuyển chương trình sang môi trường khác; đặt tên cho nó bằng #define thì mọi nơi dùng chung một chỗ sửa, nên khi kích thước bộ đệm hay giới hạn của một kiểu thay đổi theo máy, chỉ cần sửa một dòng là cả chương trình thích ứng. "It makes the code shorter" sai vì tên có nghĩa thường dài hơn con số nó thay; lợi ích nằm ở chỗ dễ đọc và sửa một nơi, không ở số ký tự. "It prevents the use of symbolic names" sai ngược hẳn, bởi #define chính là công cụ tạo ra tên tượng trưng. "It increases code complexity" sai vì thay con số vô nghĩa bằng tên nói rõ ý làm mã dễ hiểu hơn, độ phức tạp giảm chứ không tăng.
Mở trang câu hỏi này →
A2.5
B2.0
C2
D3.5
Lời giải
Đáp án đúng: "2.0". Biểu thức 5 / 2 chỉ gồm hai hằng số nguyên nên trình dịch dùng phép chia nguyên, cho 2 và bỏ phần dư; kiểu của biến đích không quay lại ảnh hưởng cách tính biểu thức bên phải, đây là chỗ bẫy của câu hỏi. Giá trị 2 sau đó mới được nâng lên float thành 2.0, và %.1f in một chữ số sau dấu chấm nên màn hình hiện 2.0. Muốn có phép chia thực phải để ít nhất một toán hạng là số thực, chẳng hạn viết 5.0 / 2. Số "2.5" là kết quả của phép chia thực, chỉ xuất hiện khi đã có toán hạng thực. Số "2" là cách in một số nguyên bằng %d, còn %.1f luôn kèm dấu chấm và một chữ số. Số "3.5" không ứng với cách tính nào của 5 chia 2, dù chia nguyên hay chia thực.
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 →
AIt can only be used with integer or character type expressions.
BIt can be used with any data type.
CIt can only be used in functions.
DIt can only have one case statement inside.
Lời giải
Đáp án đúng: "It can only be used with integer or character type expressions.". Chuẩn C đòi biểu thức điều khiển của switch phải có kiểu nguyên, và mỗi nhãn case phải là hằng nguyên tính được lúc dịch; ký tự thoả yêu cầu này vì char được nâng lên int và hằng ký tự chính là một số nguyên. Lý do nằm ở cách dịch: trình dịch cần so sánh bằng chính xác hoặc dựng bảng nhảy, điều không làm được với số thực hay chuỗi. Lựa chọn "It can be used with any data type." sai vì float, double hay mảng ký tự đều bị từ chối, muốn phân nhánh theo chúng phải dùng chuỗi if else. Lựa chọn "It can only be used in functions." không nói lên điều gì riêng của switch, bởi mọi câu lệnh thực thi trong C đều nằm trong thân hàm. Lựa chọn "It can only have one case statement inside." sai vì switch mang bao nhiêu nhãn case cũng được, đó chính là lý do người ta chọn nó.
Mở trang câu hỏi này →