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ố 4

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 đề. Trang 2/3 — câu 21–40.

Danh sách câu hỏi

40/50 câuCòn 10
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 →
ACompile time error
BLoop infinitely
CNo Output will be printed
DThe loop will not work
Lời giải
Đáp án đúng: "Compile time error". Câu hỏi viết thiếu một từ, phải hiểu là vòng while không có điều kiện lặp. Cú pháp của while trong C đòi bắt buộc một biểu thức điều khiển trong cặp ngoặc tròn, nên viết while với ngoặc rỗng là sai cú pháp: trình biên dịch báo lỗi và không sinh ra bản thực thi nào; muốn lặp mãi thì vẫn phải viết một biểu thức luôn đúng. Kết luận "Loop infinitely" là hành vi của while có điều kiện luôn khác 0, chẳng hạn hằng số 1, tức là vẫn có biểu thức chứ không phải để trống. Kết luận "No Output will be printed" giả định chương trình đã chạy rồi không in gì, trong khi ở đây chưa có chương trình nào để chạy. Kết luận "The loop will not work" cũng nói về lúc chạy và lại mơ hồ, không phân biệt được chuyện lỗi dịch với chuyện vòng lặp chạy không lần nào.
Mở trang câu hỏi này →
AIt must always be placed at the beginning of the switch statement
BIt is mandatory for every switch statement
CIt executes when none of the case conditions match
DIt can be used multiple times within a single switch
Lời giải
Đáp án đúng: "It executes when none of the case conditions match". Nhánh mặc định là nơi switch rẽ vào khi giá trị của biểu thức điều khiển không khớp bất kỳ nhãn case nào, nhờ đó mọi đầu vào ngoài dự kiến vẫn được xử lý thay vì rơi qua switch mà không làm gì. Lựa chọn "It must always be placed at the beginning of the switch statement" sai vì vị trí của nó tự do, đặt ở cuối chỉ là thói quen cho dễ đọc, và nếu đặt giữa thì vẫn cần break để không chạy tràn sang nhãn sau. Lựa chọn "It is mandatory for every switch statement" sai vì nhánh này không bắt buộc, thiếu nó thì switch đơn giản không làm gì khi không khớp. Lựa chọn "It can be used multiple times within a single switch" sai vì mỗi switch chỉ được có một nhánh mặc định, viết hai lần là lỗi dịch.
Mở trang câu hỏi này →
AThe way the condition is checked.
BThey are essentially the same.
CThe type of tasks they can perform.
DThe variable in loop construct.
Lời giải
Đáp án đúng: "The way the condition is checked.". Khác biệt cốt lõi nằm ở chỗ điều kiện được xét trước hay sau thân vòng lặp: while xét trước nên thân có thể không chạy lần nào, còn do while xét ở cuối nên thân luôn chạy ít nhất một lượt. Hệ quả thực tế là do while phù hợp cho việc phải làm một lần rồi mới quyết định lặp lại, chẳng hạn hiện bảng chọn rồi đọc lựa chọn của người dùng. Lựa chọn "They are essentially the same." sai vì hai dạng cho kết quả khác nhau ngay khi điều kiện sai từ đầu. Lựa chọn "The type of tasks they can perform." sai vì cả hai đều lặp được mọi việc và luôn viết lại được từ dạng này sang dạng kia. Lựa chọn "The variable in loop construct." sai vì cả hai đều không ràng buộc phải dùng biến nào, điều kiện có thể là bất kỳ biểu thức nào.
Mở trang câu hỏi này →
25What is the output of this reverse loop?4 lựa chọncó code
Đề bài
#define SIZE 5
int nums[SIZE] = {5, 10, 2, -45, 6};
for (int i = SIZE - 1; i >= 0; i--)
    printf("%d ", nums[i]);
A5 10 2 -45 6
B6 -45 2 10 5
C-45 2 10 5 6
DError
Lời giải
Đáp án đúng: "6 -45 2 10 5". Vòng for đặt i bắt đầu ở SIZE trừ 1 là 4, chạy tiếp khi i còn lớn hơn hoặc bằng 0 và giảm một đơn vị mỗi lượt, nên các chỉ số được thăm theo thứ tự 4, 3, 2, 1, 0. Đọc mảng theo thứ tự đó cho ra 6, -45, 2, 10, 5, mỗi số kèm một dấu cách vì chuỗi định dạng có dấu cách ở cuối. Ở đây vòng for không có cặp ngoặc nhọn nên nó chỉ ôm đúng một lệnh printf, vừa khớp ý định của mã. Ý "5 10 2 -45 6" sai vì đó là thứ tự xuôi, ứng với vòng lặp đi từ 0 lên. Ý "-45 2 10 5 6" sai vì nó bắt đầu từ chỉ số 3 rồi vòng lại phần tử cuối, không có phép lặp nào trong mã sinh ra trật tự ấy. Ý "Error" sai vì khai báo biến đếm ngay trong câu for là hợp lệ từ chuẩn C99, và chỉ số 4 vẫn nằm trong mảng 5 phần tử.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>
void swap(int *px, int *py)
{
    int z;
    z=*px;
    *px=*py ;
    *py=z ;
}
int main()
{
    int a=15, b=21 ;
    swap(&a,&b);
    printf ("%d  %d",a,b);
   return 0;
}
A15 21
B21 15
CError while executing the program
DNone of these
Lời giải
Đáp án đúng: "21 15". Hàm main truyền địa chỉ của a và địa chỉ của b, nên hai tham số con trỏ trỏ thẳng vào hai biến của main. Thân hàm giữ nội dung ô thứ nhất vào biến tạm, ghi nội dung ô thứ hai sang ô thứ nhất, rồi ghi biến tạm sang ô thứ hai; mọi phép ghi đều đi qua dấu sao nên tác động lên chính a và b chứ không lên bản sao. Sau lời gọi, a mang 21 và b mang 15. Lựa chọn "15 21" là trạng thái ban đầu, chỉ đúng nếu hàm nhận hai int theo giá trị và đổi chỗ trên bản sao. Lựa chọn "Error while executing the program" sai vì địa chỉ của hai biến đang sống trong main là hợp lệ, việc ghi vào đó không gây sự cố nào. Lựa chọn "None of these" không dùng được vì đã có một lựa chọn khớp đúng kết quả thật của chương trình.
Mở trang câu hỏi này →
AReturn type, function name, parameters, and function body.
BReturn type, function name, return value, and function body
CReturn type, function name, parameters, and return value
DReturn value, function name, parameters, and function body
Lời giải
Đáp án đúng: "Return type, function name, parameters, and function body.". Một định nghĩa hàm trong C được viết theo đúng trật tự mà trình biên dịch cần để biết cách gọi và cách nhận kết quả: trước hết là kiểu trả về, rồi tên hàm, rồi danh sách tham số trong cặp ngoặc đơn, cuối cùng là thân hàm trong cặp ngoặc nhọn. Ba thành phần đầu hợp thành tiêu đề hàm, cũng chính là phần được lặp lại khi khai báo nguyên mẫu, còn thân hàm mới chứa các lệnh thực thi. Ý "Return type, function name, return value, and function body" sai vì giá trị trả về không phải một thành phần cú pháp nằm trong tiêu đề, nó do lệnh return bên trong thân hàm sinh ra lúc chạy. Ý "Return type, function name, parameters, and return value" sai vì bỏ mất thân hàm, mà thiếu thân thì chỉ còn là một nguyên mẫu, không phải định nghĩa. Ý "Return value, function name, parameters, and function body" sai vì chỗ mở đầu buộc phải là một kiểu dữ liệu, không phải một giá trị cụ thể.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>

double average(int a, int b, int c) {
    double result;
    result = (a+b+c)/3.0;
    return result;
}

int main() {
    printf("%.6f", average(5, 8, 7));
    return 0;
}
A6.666667
B6.000000
C20.000000
D6
Lời giải
Đáp án đúng: "6.666667". Tổng ba đối số là 20, và chia cho 3.0 là phép chia có một toán hạng thực nên C nâng 20 lên double rồi chia thực, cho 6.666 và còn lặp mãi, khác hẳn việc chia cho hằng nguyên. Giá trị ấy được trả về qua kiểu double, còn đặc tả yêu cầu in sáu chữ số sau dấu thập phân kèm làm tròn chữ số cuối, nên màn hình hiện 6.666667. Lựa chọn "6.000000" là kết quả nếu mẫu số viết là hằng nguyên 3, khi đó chia nguyên cắt phần thập phân trước cả lúc gán vào biến double. Lựa chọn "20.000000" là tổng chưa chia. Lựa chọn "6" sai về dạng in vì đặc tả này luôn kéo đủ sáu chữ số thập phân chứ không rút ngắn, và cũng sai về giá trị vì phần thập phân bị bỏ mất.
Mở trang câu hỏi này →
29What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
void main()
{
    int *ptr, a = 10;
    ptr = &a;
    *ptr += 1;
    printf("%d,%d\n", *ptr, a);
}
A10,10
B10,11
C11,10
D11,11
Lời giải
Đáp án đúng: "11,11". Lệnh ptr = &a làm ptr giữ địa chỉ ô nhớ của a, nên *ptr và a là hai cách gọi cùng một chỗ chứ không phải hai bản sao; *ptr += 1 cộng 1 vào chính ô đó nên a thành 11, và khi in thì cả *ptr lẫn a đều đọc ra 11. Bản chất là bí danh: con trỏ không chứa giá trị, nó chỉ chứa địa chỉ. "10,10" sai vì phép cộng đã thực sự ghi vào bộ nhớ, giá trị không còn là 10. "10,11" sai vì *ptr không thể đọc ra giá trị cũ khi ô nhớ đã đổi. "11,10" sai vì a không phải bản sao riêng, nó chính là ô nhớ mà ptr trỏ tới, nên không thể giữ 10 trong khi *ptr đã là 11.
Mở trang câu hỏi này →
30Assume we have a function such as:4 lựa chọncó code
Đề bài
void swap(int a, int b){
    int t = a;
    a=b;
    b=t;
}

What is the problem with a and b after executing the swap (a, b) function?

Aa and b do not change values.
Bcannot execute the swap(a,b) function.
Ca has the old value of b, and b has the new value of t.
Da and b change values for each other;
Lời giải

Đáp án đúng: "a and b do not change values.". C truyền tham số theo giá trị: lúc gọi hàm, hai đối số được sao chép vào hai biến cục bộ trùng tên bên trong swap. Mọi phép đổi chỗ sau đó chỉ xáo trộn bản sao, và khi hàm kết thúc các bản sao biến mất, hai biến ở chỗ gọi vẫn nguyên như trước. Muốn đổi thật thì tham số phải là con trỏ và thân hàm phải làm việc qua phép lấy nội dung. Ý "cannot execute the swap(a,b) function." sai vì hàm hoàn toàn hợp lệ, nó dịch được và chạy được, chỉ là không có tác dụng ra bên ngoài. Ý "a has the old value of b, and b has the new value of t." sai vì điều đó chỉ đúng với hai bản sao cục bộ và chỉ tới thời điểm trước khi hàm trả về. Ý "a and b change values for each other; " sai vì đó chính là ngộ nhận mà câu hỏi muốn phá: việc đổi chỗ có xảy ra nhưng không chạm tới ô nhớ của hai biến gốc.

Mở trang câu hỏi này →
Adouble
Bfloat
Cint
Dlong
Lời giải
Đáp án đúng: "double". Thư viện math.h làm việc với số thực độ chính xác kép, nên sqrt nhận một đối số double và trả về double; nhờ vậy căn bậc hai của 2 giữ được nhiều chữ số có nghĩa, và muốn in thì dùng định dạng %f hoặc %lf. "float" sai vì bản trả về float có tên riêng là sqrtf; gán kết quả của sqrt vào biến float thì bị thu hẹp và mất chính xác. "int" sai vì căn bậc hai nói chung không nguyên, trả về kiểu nguyên sẽ cắt mất phần thập phân, chẳng hạn căn của 2 thành 1. "long" sai cùng lý do, long vẫn là kiểu nguyên, chỉ khác độ rộng lưu trữ.
Mở trang câu hỏi này →
32What is the main() function in C?4 lựa chọn
AIt is the function where the program's execution starts.
BEvery program has exactly one main function.
CThe main function always returns an integer value or void.
DAll answers are correct.
Lời giải
Đáp án đúng: "All answers are correct.". Cả ba nhận định còn lại đều nói về cùng một hàm và đều đúng: main là nơi quá trình thực thi bắt đầu, mỗi chương trình có đúng một hàm main vì nếu không bộ liên kết không biết chọn điểm vào nào, và kiểu trả về của nó là số nguyên theo chuẩn, còn dạng void chỉ được một số trình biên dịch chấp nhận. Ý "It is the function where the program's execution starts." đúng về nội dung nhưng không thể là lựa chọn vì nó bỏ qua hai tính chất kia, chọn nó là bỏ sót phần còn lại của câu trả lời. Ý "Every program has exactly one main function." cũng đúng mà vẫn thiếu, nó không nói gì về điểm khởi đầu hay kiểu trả về. Ý "The main function always returns an integer value or void." đúng theo cách dùng phổ biến nhưng cũng chỉ mô tả một mặt, không đủ bao phủ câu hỏi.
Mở trang câu hỏi này →
AIt checks if a character is an alphabet.
BIt returns to a non-zero value if the character is a digit (0-9).
CIt only works with float inputs.
DIt converts a digit to integer.
Lời giải
Đáp án đúng: "It returns to a non-zero value if the character is a digit (0-9)." Hàm isdigit trong ctype.h xét mã ký tự và trả về giá trị khác 0 khi ký tự đó là một trong mười chữ số, trả 0 với mọi ký tự khác; đây là cách kiểm tra đúng khi đọc chuỗi nhập để biết người dùng có gõ số hay không. "It checks if a character is an alphabet." sai vì việc xét chữ cái thuộc hàm isalpha. "It only works with float inputs." sai vì hàm nhận một tham số kiểu int chứa mã ký tự, nó không liên quan gì tới số thực. "It converts a digit to integer." sai vì hàm chỉ kiểm tra chứ không chuyển đổi; muốn đổi ký tự số thành giá trị thì trừ đi mã của ký tự 0, hoặc dùng atoi cho cả chuỗi.
Mở trang câu hỏi này →
34What is required in each C program?4 lựa chọn
AThe program must have at least one function.
BThe program does not require any function.
CInput data
DOutput data
Lời giải
Đáp án đúng: "The program must have at least one function.". Mọi chương trình C đứng riêng đều phải có hàm main, vì đó là điểm vào mà môi trường gọi tới sau khi nạp chương trình; không có main thì bộ liên kết báo thiếu điểm vào và không tạo nổi tệp chạy. Vậy số hàm tối thiểu của một chương trình là một. Kết luận "The program does not require any function." sai đúng ở chỗ đó: lệnh trong C không thể nằm ngoài thân hàm, ở mức tệp chỉ được khai báo biến, kiểu và hàm. Yêu cầu "Input data" không bắt buộc, một chương trình chỉ tính toán rồi in ra, hoặc thậm chí chẳng làm gì, vẫn hợp lệ. Yêu cầu "Output data" cũng vậy, chương trình có thể chỉ trả mã kết thúc về cho hệ điều hành mà không in ra gì. Hai việc vào ra là nhu cầu của bài toán, còn hàm main là ràng buộc của ngôn ngữ.
Mở trang câu hỏi này →
Đề bài
int a[MAX_SIZE];
int s = 0;
for (int i = 0; i < n; i++)
    s = s +  a[i] * a[i];
AThe sum of squares of all elements in the array a.
BThe sum of all even elements in the array a.
CThe sum of all odd elements in the array a.
DThe sum of all elements in the array a.
Lời giải
Đáp án đúng: "The sum of squares of all elements in the array a.". Biến s bắt đầu từ 0, vòng lặp đi qua mọi chỉ số từ 0 tới n trừ 1, và mỗi lượt cộng vào s tích của phần tử với chính nó, tức bình phương của nó. Vì không có câu điều kiện nào lọc bớt nên mọi phần tử đều góp phần, và vì bình phương không bao giờ âm nên s luôn không âm dù mảng có chứa số âm. Lựa chọn "The sum of all even elements in the array a." đòi một phép kiểm tra chia hết cho 2 trước khi cộng, điều mã không có. Lựa chọn "The sum of all odd elements in the array a." cũng đòi phép lọc theo tính chẵn lẻ tương tự. Lựa chọn "The sum of all elements in the array a." ứng với dòng cộng thẳng phần tử vào s, không có phép nhân phần tử với chính nó.
Mở trang câu hỏi này →
AArrays provide constant-time access to elements.
BArrays allow for dynamic resizing during runtime.
CArrays can store elements of different data types.
DArrays automatically adjust their size based on the number of elements.
Lời giải
Đáp án đúng: "Arrays provide constant-time access to elements.". Mảng chiếm một dải ô nhớ liên tục và mọi phần tử cùng một kiểu nên cùng kích thước; nhờ vậy địa chỉ phần tử thứ i tính ra ngay bằng địa chỉ đầu cộng i nhân kích thước một phần tử, một phép tính không phụ thuộc vào i, tức là thời gian truy xuất là hằng số. Ý "Arrays allow for dynamic resizing during runtime." sai vì mảng khai báo tĩnh có kích thước cố định từ lúc dịch, muốn thay đổi dung lượng thì phải tự cấp vùng nhớ động rồi gọi realloc, và đó không còn là mảng ban đầu nữa. Ý "Arrays can store elements of different data types." sai vì mảng đòi hỏi các phần tử đồng kiểu, chính điều đó mới cho phép tính địa chỉ bằng một bước nhảy cố định. Ý "Arrays automatically adjust their size based on the number of elements." sai vì số phần tử ghi trong khai báo là bất biến; khởi tạo thiếu giá trị thì phần còn lại nhận 0 chứ mảng không tự co lại hay nở ra.
Mở trang câu hỏi này →
Apointers
Bvalue
Ctype
Daddress
Lời giải
Đáp án đúng: "address". Vị trí ô nhớ của một biến được gọi là địa chỉ của biến đó, và toán tử lấy địa chỉ cho ra đúng giá trị này; chính nhờ địa chỉ mà chương trình đọc ghi được dữ liệu, mà hàm sửa được biến của nơi gọi, và mà số học con trỏ đi lại được trên mảng. Lựa chọn "pointers" nói về biến dùng để chứa địa chỉ, tức cái hộp, chứ không phải bản thân vị trí ô nhớ. Lựa chọn "value" là dữ liệu đang nằm trong ô nhớ, thứ thay đổi được trong khi địa chỉ của biến thì cố định suốt thời gian biến tồn tại. Lựa chọn "type" là kiểu dữ liệu, nó quyết định ô nhớ rộng bao nhiêu byte và nội dung được hiểu theo nghĩa nào, nhưng không nói gì về vị trí.
Mở trang câu hỏi này →
38What does the following program print?4 lựa chọncó code
Đề bài
#include <stdio.h>

int main() {
    int a = 4, *b = &a;
    a--;
    *b=*b-1;
    printf("%d %d", a, *b);
    return 0;
}
A2 2
B2 1
C3 1
D3 3
Lời giải
Đáp án đúng: "2 2". Con trỏ b được gán địa chỉ của a nên từ đó a và *b là hai tên gọi của cùng một ô nhớ. Lệnh a-- hạ ô đó từ 4 xuống 3, rồi *b = *b - 1 đọc chính ô đó được 3, trừ đi 1 và ghi lại 2; khi printf chạy, cả a lẫn *b đều lấy từ ô duy nhất ấy nên hai số in ra buộc phải giống nhau. Ý "3 1" sai vì nó coi a và *b là hai biến riêng, mỗi biến bị giảm đúng một lần; đây cũng là khuyết điểm phải công bố của câu này, bộ khoá đi kèm đề ghi đúng cặp số ấy trong khi mã nguồn không thể sinh ra hai giá trị khác nhau. Ý "2 1" sai vì nó cộng cả hai lần giảm vào a nhưng chỉ tính một lần cho *b, điều không thể xảy ra với hai tên của cùng một ô nhớ. Ý "3 3" sai vì nó bỏ quên một trong hai lệnh giảm, chỉ hạ giá trị từ 4 xuống 3.
Mở trang câu hỏi này →
39What will be the output of the following C code?4 lựa chọncó code
Đề bài
int a[5] = {1, 2, 3};
printf("%d", a[4]);
A3
B0
CRuntime error
DCompilation error
Lời giải
Đáp án đúng: "0". Khi danh sách khởi tạo có ít giá trị hơn số phần tử khai báo, chuẩn C bắt phần còn lại phải được khởi tạo như đối tượng tĩnh, nghĩa là bằng 0 với kiểu số. Mảng này có năm ô, ba ô đầu nhận 1, 2, 3 còn hai ô cuối được điền 0, nên phần tử ở chỉ số 4 là 0 và lệnh in cho ra 0. Chính quy tắc đó là lý do người ta hay viết cặp ngoặc với một số 0 duy nhất để xoá trắng cả mảng. Lựa chọn "3" là giá trị ở chỉ số 2, tức giá trị khởi tạo cuối cùng được viết ra. Lựa chọn "Runtime error" sai vì chỉ số 4 vẫn nằm trong năm phần tử đã khai báo, không có truy cập ngoài biên. Lựa chọn "Compilation error" sai vì viết thiếu giá trị khởi tạo là hợp lệ; chỉ viết nhiều hơn số phần tử mới bị báo lỗi.
Mở trang câu hỏi này →
40What is the output of the following code snippet?4 lựa chọncó code
Đề bài
void main()
{
        int const *p = 5;
        printf("%d", ++(*p));
        getchar();
}
ACompile error
B5
CNULL
D6
Lời giải
Đáp án đúng: "Compile error". Khai báo ở đây nói p là con trỏ tới int có tính bất biến, nghĩa là không được phép ghi vào vùng mà p trỏ tới. Vì vậy phép tăng áp lên nội dung được trỏ tới là ghi vào một đối tượng bất biến và trình dịch phải báo lỗi, không cần biết p đang trỏ đi đâu. Mã còn một chỗ sai nữa ngay trên đó: gán số 5 cho một con trỏ mà không ép kiểu cũng là vi phạm ràng buộc kiểu. Lựa chọn "5" giả định lệnh in chạy được và phép tăng không có hiệu lực, nhưng chương trình không bao giờ tới được bước thực thi. Lựa chọn "6" giả định phép tăng thành công, điều mà tính bất biến chặn lại ngay lúc dịch; hơn nữa nếu có chạy thì việc đọc nội dung tại địa chỉ 5 cũng làm chương trình gãy. Lựa chọn "NULL" không ứng với gì vì p được gán 5 chứ không phải hằng con trỏ rỗng.
Mở trang câu hỏi này →