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

Danh sách câu hỏi

40/50 câuCòn 10
Afor ( Init1, Init2; Condition ; Task1, Task2);
Bfor ( Init1, Condition ,Task1);
Cfor (Condition ; Init1, Init2; Task1);
Dfor ( Init1; Init2; Condition ; Task2)
Lời giải

Đáp án đúng: "for ( Init1, Init2; Condition ; Task1, Task2); ". Cặp ngoặc của for luôn chia thành đúng ba phần bởi hai dấu chấm phẩy: phần khởi tạo chạy một lần khi vào vòng, phần điều kiện kiểm trước mỗi lần chạy thân, phần cập nhật chạy sau mỗi lần chạy thân. Muốn nhồi nhiều việc vào một phần thì dùng toán tử phẩy, nên hai khởi tạo và hai việc cập nhật viết cách nhau bằng dấu phẩy là hợp lệ; dấu chấm phẩy ngay sau ngoặc đóng chỉ làm thân rỗng, vẫn dịch được. Khuôn "for ( Init1, Condition ,Task1); " chỉ dùng dấu phẩy nên cả ngoặc trở thành một biểu thức duy nhất, trình biên dịch không tìm ra điều kiện lặp. Khuôn "for (Condition ; Init1, Init2; Task1); " đảo chỗ: vế đầu bị tính một lần rồi bỏ, còn phần khởi tạo lại bị dùng làm điều kiện. Khuôn "for ( Init1; Init2; Condition ; Task2)"có tới ba dấu chấm phẩy, tức bốn phần, vượt khuôn mà ngôn ngữ cho phép.

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 →
Đề bài
#include <stdio.h>
int main() {
    int i = 10;
    do {
        printf("%d ", i);
        i -= 2;
    } while (i >= 1);
    return 0;
}
A10 8 6 4 2
B10 8 6 4 2 0
C10 8 6 4 2 0 -2 -4
D10 9 8 7 6 5 4 3 2
Lời giải
Đáp án đúng: "10 8 6 4 2". Phép kiểm điều kiện của vòng lặp này nằm ở cuối thân, nên mỗi lượt diễn ra theo đúng thứ tự in xong, giảm đi, rồi mới so sánh. Biến i vào vòng với 10: in 10 rồi i thành 8, in 8 rồi i thành 6, in 6 rồi i thành 4, in 4 rồi i thành 2, in 2 rồi i thành 0; lúc này điều kiện i lớn hơn hoặc bằng 1 cho sai nên vòng lặp dừng. Dãy "10 8 6 4 2 0" cần thân chạy thêm một lượt với i bằng 0, nhưng giá trị 0 chỉ sinh ra ở cuối lượt cuối và điều kiện đã chặn trước khi kịp in. Dãy "10 8 6 4 2 0 -2 -4" đòi điều kiện cho phép số âm, trong khi mốc so sánh là 1. Dãy "10 9 8 7 6 5 4 3 2" ứng với bước giảm một đơn vị, còn lệnh i -= 2 ở đây lấy đi hai đơn vị mỗi lượt nên chỉ in các số chẵn.
Mở trang câu hỏi này →
Đề bài
#include<stdio.h>
int main()
{
    const int a=5;
    if(a>3)
        a++;
        break;
    else
        a--;
    printf("%d",a);
    return 0;
}
ACompile time error
B6
C4
D5
Lời giải
Đáp án đúng: "Compile time error". Phạm vi khối do ngoặc nhọn quyết định, không do thụt lề: nhánh if ở đây không có ngoặc nhọn nên chỉ ôm đúng một lệnh là lệnh tăng a, còn lệnh break phía sau đã nằm ngoài if dù được thụt vào ngang hàng. Vì vậy khi gặp từ khoá else, trình biên dịch không còn if nào để ghép nên báo lỗi ngay. Mã này còn hai lỗi nữa: break chỉ hợp lệ trong vòng lặp hoặc trong switch, mà đây không có cái nào; và a khai báo const nên cả lệnh tăng lẫn lệnh giảm đều là ghi vào đối tượng chỉ đọc. Giá trị "6" giả định lệnh tăng chạy được trên một hằng rồi chương trình in ra sau đó. Giá trị "4" ứng với nhánh giảm chạy, nhưng điều kiện a lớn hơn 3 với a bằng 5 vốn đã đúng. Giá trị "5" giả định không nhánh nào chạy, trong khi vấn đề thật là chương trình không dịch nổi.
Mở trang câu hỏi này →
25What the matter is the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int a=1,b=2,c=3;
    printf("%d %d %d");
    return 0;
}
AThe program outputs undefined values.
BThe program has compile errors but still prints 1 2 3
CThe program output 3 2 1.
DThe program runtime error.
Lời giải
Đáp án đúng: "The program outputs undefined values.". Hàm printf nhận số tham số biến thiên và không có cách nào tự kiểm tra xem người lập trình đã truyền đủ giá trị cho các đặc tả hay chưa; chuỗi định dạng ở đây đòi ba số nguyên nhưng không có tham số nào đi kèm, nên hàm vẫn đi lấy ở đúng những chỗ mà quy ước gọi hàm dành cho tham số thứ nhất, thứ hai, thứ ba và đọc ra rác còn sót trong thanh ghi hoặc trên ngăn xếp. Đó là hành vi không xác định, mỗi lần chạy có thể in ra số khác nhau. Kết luận "The program has compile errors but still prints 1 2 3" tự mâu thuẫn: có lỗi dịch thì không có bản chạy, mà ở đây trình biên dịch nhiều nhất chỉ cảnh báo. Kết luận "The program output 3 2 1." giả định printf tự tìm được các biến a, b, c rồi còn đảo thứ tự, việc ngôn ngữ không làm. Kết luận "The program runtime error." quá chắc tay: đọc rác thường chỉ in ra số vô nghĩa chứ không bắt buộc làm chương trình chết.
Mở trang câu hỏi này →
26Which is a function in C language?6 lựa chọn
Ais_prime()
B#include()
Cint()
Dif()
Ereturn()
F2ndElement()
Lời giải
Đáp án đúng: "is_prime()". Hàm trong C là khối mã có tên do người lập trình đặt theo luật định danh: mở đầu bằng chữ cái hoặc dấu gạch dưới, tiếp theo là chữ, số hoặc gạch dưới, và không được trùng từ khoá; is_prime thoả hết nên là tên hàm hợp lệ, kiểu tên quen dùng cho hàm kiểm tra số nguyên tố. Dòng "#include()" không phải hàm mà là chỉ thị tiền xử lý, được xử lý trước khi biên dịch và chỉ để chèn nội dung một tệp tiêu đề. Tên "int()" lấy đúng từ khoá kiểu int làm tên, trình biên dịch không cho phép. Tên "if()" cũng là từ khoá, đó là lệnh rẽ nhánh của ngôn ngữ chứ không phải lời gọi hàm. Tên "return()" là từ khoá trả về giá trị, thêm cặp ngoặc cũng không biến nó thành hàm. Tên "2ndElement()" mở đầu bằng chữ số nên vi phạm luật định danh ngay ở ký tự đầu tiên.
Mở trang câu hỏi này →
27Suppose there is a function in C as follows:4 lựa chọncó code
Đề bài
double g (double x, double y){
    return (x - 2)*(x - 2) + y*y;
}

What is the value of z after executing the statement z=g(2,0)?

A0
B4
C2
D8
Lời giải
Đáp án đúng: "0". Hàm g nhận hai số thực và trả về giá trị của biểu thức (x - 2)*(x - 2) + y*y. Thay x bằng 2 thì x - 2 cho 0 nên tích thứ nhất bằng 0; thay y bằng 0 thì y*y cũng bằng 0; tổng hai phần là 0, và vì kiểu trả về là double nên z nhận 0 ở dạng số thực. Hai đối số viết dưới dạng hằng nguyên nhưng được chuyển ngầm sang double khi truyền vào, nhờ nguyên mẫu hàm đã khai rõ kiểu tham số. Giá trị "4" là kết quả nếu bỏ sót phép trừ, tức tính x*x với x bằng 2. Giá trị "2" chỉ là chính đối số thứ nhất, không phải giá trị của biểu thức. Giá trị "8" không khớp với bất cứ cách thay số nào: với x bằng 2 thì số hạng đầu luôn triệt tiêu và y bằng 0 làm số hạng sau cũng triệt tiêu, muốn có 8 thì biểu thức phải có thêm số hạng khác. Lời gọi hàm chỉ thay giá trị vào tham số rồi tính, không có bước nào khác.
Mở trang câu hỏi này →
28What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
void main()
{
    int k = 5;
    int *p = &k;
    int **m  = &p;
    **m = 6;
    printf("%d\n", k);
}
A5
BRun time error
C6
DJunk
Lời giải
Đáp án đúng: "6". Con trỏ p giữ địa chỉ của k, còn m giữ địa chỉ của p. Khi viết **m, lần lấy nội dung thứ nhất đi từ m sang p, lần thứ hai đi từ p sang chính ô nhớ của k, nên **m = 6 ghi số 6 thẳng vào ô của k. Vì k và **m là hai con đường tới cùng một ô, printf đọc ra 6. Đây là bản chất của con trỏ nhiều cấp: chúng không sao chép giá trị mà chỉ nối thêm một chặng đường tới ô nhớ gốc. Ý "5" sai vì 5 chỉ là giá trị ban đầu, nó đã bị ghi đè trước lúc in. Ý "Run time error" sai vì cả hai con trỏ đều trỏ vào biến còn sống trong hàm, không có địa chỉ nào không hợp lệ. Ý "Junk" sai vì k đã được khởi tạo rồi sau đó còn được gán tường minh, không còn chỗ nào để giá trị rác xen vào.
Mở trang câu hỏi này →
29What is the output of the following code snippet?4 lựa chọncó code
Đề bài
#include <stdio.h>
int change(int a)
{
    a =10;
    return a;
}
void main()
{
    int i=5;
    i = change(i);
    printf("%d",i);
}
A10
B5
C15
DCompiler error
Lời giải
Đáp án đúng: "10". Tham số của hàm trong C là một bản sao: lời gọi change(i) đẩy giá trị 5 vào biến cục bộ a, trong thân hàm a bị đặt lại thành 10 rồi trả về 10, còn biến i của hàm chính không hề bị hàm đụng tới. Thứ làm i đổi giá trị là phép gán ở ngoài, vì i = change(i) ghi giá trị trả về vào i, nên lệnh in xuất ra 10. Giá trị "5" là kết quả nếu bỏ phép gán và chỉ gọi change(i) rồi in i, vì khi đó mọi thay đổi chết theo bản sao lúc hàm kết thúc. Giá trị "15" cần một phép cộng dồn, trong khi hàm gán thẳng 10 cho tham số. Kết luận "Compiler error" không đúng: hàm có đầy đủ kiểu trả về và kiểu tham số, giá trị trả về khớp kiểu của i; riêng việc viết void cho hàm chính là không chuẩn nhưng các trình biên dịch quen dùng chỉ cảnh báo chứ vẫn dịch được.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>
void level2(int** ppa)
{
    printf("%d\n", **ppa);
}
void level1(int* pa)
{
    level2(&pa);
}
main()
{
    int a = 10;
    level1(&a);
}
AThe address of variable a
BThe address of the pointer pa
CThe address of the double pointer ppa
D10
Lời giải
Đáp án đúng: "10". Biến a mang giá trị 10; lời gọi level1(&a) truyền địa chỉ của a nên tham số pa trỏ tới a. Trong level1, phép lấy địa chỉ của chính tham số pa cho một con trỏ hai cấp, và level2 nhận nó dưới tên ppa. Bỏ một lớp sao thì được lại con trỏ pa, bỏ lớp thứ hai thì lấy nội dung chỗ pa trỏ tới, tức a, nên biểu thức hai lớp sao cho 10 và đặc tả %d in ra số nguyên 10. Kết quả "The address of variable a" ứng với việc chỉ bỏ một lớp sao. Kết quả "The address of the pointer pa" ứng với việc in thẳng ppa mà không bỏ lớp nào. Kết quả "The address of the double pointer ppa" còn cần lấy địa chỉ của ppa, thứ mã này không làm. Thêm nữa, ba kết quả địa chỉ đều lệch kiểu với đặc tả đang dùng: in địa chỉ phải dùng %p, còn %d luôn đọc đối số như một số nguyên.
Mở trang câu hỏi này →
Astdio.h
Bstdlib.h
Cctype.h
Dconio.h
Lời giải
Đáp án đúng: "stdlib.h". Hàm rand cùng với srand và hằng RAND_MAX được chuẩn C xếp vào nhóm tiện ích chung, khai báo trong tệp tiêu đề stdlib.h, nên muốn sinh số nguyên giả ngẫu nhiên thì phải khai báo tệp này; thiếu nó thì trình biên dịch không biết nguyên mẫu của rand nên báo lỗi hoặc sinh mã sai kiểu. Tệp "stdio.h" chỉ giữ phần vào ra có định dạng như printf, scanf và nhóm hàm tệp, không chứa rand. Tệp "ctype.h" giữ nhóm hàm phân loại ký tự như isdigit hay isspace, cũng không liên quan tới số ngẫu nhiên. Tệp "conio.h" không thuộc chuẩn C, nó là tệp riêng của vài trình biên dịch trên hệ điều hành cũ, phục vụ các hàm bàn phím và màn hình kiểu getch, nên vừa không chứa rand vừa không mang theo được sang môi trường khác.
Mở trang câu hỏi này →
32What 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 →
33What is the output?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main(){
    int a=6,b=15;
    int* ptr1= &a, *ptr2=&b;
    *ptr1 +=12-b+ (*ptr2);
    *ptr2 = b + a- 2*(*ptr1);
    printf("%d, %d, %d", a,b,b+a*3);
}
A18, -3, 51
B12, 3, 39
CSyntax error
DRuntime error
Lời giải
Đáp án đúng: "18, -3, 51". Hai con trỏ ptr1 và ptr2 lần lượt trỏ tới a và b, nên ghi qua con trỏ là ghi thẳng vào hai biến đó. Lệnh thứ nhất tính 12 - b + (*ptr2) với b bằng 15, được 12 - 15 + 15 là 12, rồi cộng dồn vào a nên a thành 6 + 12 là 18. Lệnh thứ hai tính b + a - 2*(*ptr1) với b bằng 15 và a đã là 18, được 15 + 18 - 36 là -3, gán qua ptr2 nên b thành -3. Lệnh in xuất a là 18, b là -3, còn b + a*3 do phép nhân ưu tiên hơn phép cộng nên bằng -3 + 54 là 51. Dãy "12, 3, 39" ứng với việc lấy 12 làm giá trị mới của a thay vì cộng dồn vào giá trị cũ. Kết luận "Syntax error" không đúng, mọi lệnh đều hợp cú pháp kể cả việc khai hai con trỏ trên một dòng. Kết luận "Runtime error" cũng không, hai con trỏ đều trỏ vào biến cục bộ còn sống nên không có truy cập bất hợp lệ.
Mở trang câu hỏi này →
Aint a[5] = {0};
Bint a[5] = [0, 0, 0, 0, 0];
Cint a[5] = (0, 0, 0, 0, 0);
Dint a[5];
Lời giải
Đáp án đúng: "int a[5] = {0};". Danh sách khởi tạo của mảng trong C đặt trong cặp ngoặc nhọn, và chuẩn quy định nếu số giá trị ít hơn số phần tử thì phần còn lại được khởi tạo về 0, nên viết đúng một số 0 là đủ để cả năm phần tử bằng 0. Cách viết "int a[5] = [0, 0, 0, 0, 0];" dùng ngoặc vuông làm danh sách, nhưng ngoặc vuông trong C chỉ dành cho khai kích thước và truy cập phần tử, nên đây là lỗi cú pháp. Cách viết "int a[5] = (0, 0, 0, 0, 0);" dùng ngoặc tròn nên vế phải thành một biểu thức với toán tử phẩy, giá trị của nó là một số 0 đơn lẻ và không thể gán cho cả mảng. Cách viết "int a[5];" không có phần khởi tạo: mảng cục bộ như vậy chứa đúng những byte rác còn lại trong bộ nhớ, chỉ mảng toàn cục hoặc static mới tự về 0, nên không bảo đảm được điều đề bài đòi.
Mở trang câu hỏi này →
A*/ Comments */
B** Comment **
C/* Comment */
D{ Comment }
Lời giải
Đáp án đúng: "/* Comment */". Chú thích khối trong C mở bằng dấu gạch chéo rồi dấu sao và đóng bằng dấu sao rồi gạch chéo; phần giữa bị bộ tiền xử lý thay bằng một khoảng trắng nên trình biên dịch không bao giờ thấy nội dung đó. Cách viết "*/ Comments */" đảo chỗ hai ký tự mở, mà dấu mở buộc phải là gạch chéo trước dấu sao, nên dòng đó bị đọc như biểu thức và báo lỗi. Cách viết "** Comment **" chỉ có hai dấu sao, ngôn ngữ đọc chúng thành phép nhân hoặc phép lấy nội dung con trỏ, không mở chú thích nào cả. Cách viết "{ Comment }" là cú pháp chú thích của Pascal, còn trong C cặp ngoặc nhọn tạo khối lệnh nên nội dung bên trong vẫn bị đòi phải là lệnh hợp lệ. Dạng chú thích thứ hai mà C cho phép là hai dấu gạch chéo kéo tới hết dòng.
Mở trang câu hỏi này →
36What will the following program print?4 lựa chọncó code
Đề bài
#include <stdio.h>

int hours_and_minutes2(int total, int *pminutes) {
    return (*pminutes = total % 60, total / 60);
}

int main() {
    int minutes;
    printf("Hours: %d, Minutes: %d\n", hours_and_minutes2(135, &minutes), minutes);
    return 0;
}
AHours: 2, Minutes: 15
BHours: 2, Minutes: 30
CHours: 3, Minutes: 15
DHours: 3, Minutes: 30
Lời giải
Đáp án đúng: "Hours: 2, Minutes: 15". Lệnh trả về của hàm dùng toán tử phẩy: vế trái gán 135 phần trăm 60, tức phần dư 15, vào chỗ pminutes trỏ tới chính là biến minutes của hàm chính; vế phải lấy 135 chia 60 mà cả hai đều là số nguyên nên đó là phép chia lấy phần nguyên, cho 2. Giá trị của một biểu thức phẩy chính là giá trị vế phải, nên hàm trả về 2 và lệnh in xuất 2 cho giờ, 15 cho phút. Dãy "Hours: 2, Minutes: 30" đòi phần dư 30, nhưng 135 bớt đi hai lần 60 chỉ còn 15. Dãy "Hours: 3, Minutes: 15" đòi thương 3, trong khi ba lần 60 đã vượt quá 135. Dãy "Hours: 3, Minutes: 30" sai cả hai phần theo đúng hai lý do vừa nêu. Cần biết thêm rằng chuẩn C không ấn định thứ tự tính các đối số của một lời gọi, nên mã kiểu này chỉ cho kết quả như trên khi lời gọi hàm được tính trước lúc lấy giá trị của minutes.
Mở trang câu hỏi này →
Đề bài
int a[] = {1,2,3,4};
int i, s = 0;
for (i=0; i<4; ++i)
    s += a[i];
printf("%f", (float)(s/4));
A2.5
B2
C2.500000
D2.000000
Lời giải
Đáp án đúng: "2.000000". Vòng for cộng dồn 1, 2, 3, 4 vào s nên s bằng 10; cả s và 4 đều là số nguyên nên s/4 là phép chia nguyên, cho 2 chứ không phải 2.5, phần dư bị cắt ngay tại đó. Phép ép kiểu sang float chỉ tác động lên con số 2 đã mất phần dư, biến nó thành 2.0, và đặc tả %f in số thực với sáu chữ số sau dấu thập phân nên màn hình hiện 2.000000. Giá trị "2.5" là kết quả nếu ép kiểu trước khi chia, nhưng ngay cả khi đó %f vẫn in thành 2.500000 chứ không in gọn một chữ số. Giá trị "2" là con số đúng của phép chia nguyên nhưng ứng với cách in bằng %d. Giá trị "2.500000" đúng khuôn in của %f nhưng vẫn cần một phép chia thực, điều không xảy ra khi hai toán hạng đều là số nguyên.
Mở trang câu hỏi này →
Aint linearSearch(int a[], int n)
Bint binarySearch(int x, int a[], int n)
Cint firstLinearSearch(double x, double a[], int n)
Dvoid sort(int a[], int n)
Lời giải
Đáp án đúng: "int binarySearch(int x, int a[], int n)". Tìm nhị phân cần đủ ba thứ: khoá cần tìm, mảng đã sắp xếp và số phần tử; mỗi bước nó so khoá với phần tử giữa rồi bỏ hẳn nửa không thể chứa khoá, nên nguyên mẫu phải có tham số cho khoá và kiểu trả về nguyên để đưa về chỉ số tìm được. Nguyên mẫu "int linearSearch(int a[], int n)" thiếu hẳn tham số khoá nên không có gì để so, và cái tên cũng chỉ ra lối tìm tuần tự. Nguyên mẫu "int firstLinearSearch(double x, double a[], int n)" đủ tham số nhưng tên nói rõ đây là tìm tuần tự từ đầu mảng, cách làm không đòi mảng phải sắp xếp trước. Nguyên mẫu "void sort(int a[], int n)" là hàm sắp xếp: nó trả về void nên không báo lại được vị trí nào, việc của nó là chuẩn bị dữ liệu cho tìm nhị phân chứ không phải tìm kiếm.
Mở trang câu hỏi này →
AIt moved to the end of the sorted part
BIt moved to the beginning of the sorted part
CIt stays in its position
DIt removed from the array
Lời giải
Đáp án đúng: "It moved to the beginning of the sorted part". Sắp xếp nổi bọt tăng dần so từng cặp kề nhau và đổi chỗ khi cặp đó nghịch, nên sau một lượt quét phần chưa sắp, phần tử lớn nhất của phần đó bị đẩy dần tới ô cuối cùng của phần chưa sắp. Ô ấy nằm sát ngay vùng đã sắp ở đuôi mảng và từ lúc này thuộc vùng đã sắp, tức nó đứng ở vị trí đầu tiên của phần đã sắp xếp, còn ranh giới giữa hai phần lùi lại một ô. Mô tả "It moved to the end of the sorted part" chỉ đúng cho lượt đầu tiên, khi phần đã sắp còn rỗng nên ô cuối mảng vừa là đầu vừa là cuối; từ lượt thứ hai, cuối phần đã sắp luôn là ô cuối mảng đã có chủ từ trước. Mô tả "It stays in its position" trái với cơ chế đổi chỗ, phần tử lớn nhất bị mang đi sau mỗi lần so. Mô tả "It removed from the array" sai về bản chất, thuật toán chỉ đổi chỗ trong cùng một mảng và không xoá phần tử nào.
Mở trang câu hỏi này →
40Assume we have the following code:4 lựa chọncó code
Đề bài
int i=4;
int *p = &i;

What is the result of the following expression: ++*p?

A5
B4
C9
D12
Lời giải
Đáp án đúng: "5". Con trỏ p giữ địa chỉ của i, nên biểu thức lấy nội dung chỗ p trỏ tới chính là biến i và dùng được ở cả hai vai, đọc lẫn ghi. Hai toán tử một toán hạng ở đây cùng mức ưu tiên và kết hợp từ phải sang trái, nên phép tăng được áp lên giá trị đã lấy ra: i tăng từ 4 lên 5 trước khi biểu thức cho giá trị, và giá trị đó cũng là 5. Giá trị "4" là giá trị cũ của i, nó chỉ xuất hiện khi dùng dạng tăng sau viết với ngoặc quanh phần lấy nội dung, khi ấy biểu thức cho 4 còn i vẫn thành 5. Giá trị "9" cần cộng thêm năm đơn vị, không có phép nào trong mã làm việc đó. Giá trị "12" cần một phép nhân hoặc một lượng cộng lớn hơn hẳn, cũng không có nguồn nào sinh ra. Điều dễ lẫn là dạng tăng đặt sau tên con trỏ, vì khi đó phép tăng tác động lên con trỏ chứ không lên giá trị được trỏ tới.
Mở trang câu hỏi này →