PRF192Chưa đoKỳ 1Cơ sở ngành Cập nhật 2 ngày trước

PRF192 - Cơ sở lập trình

PRF192 - Cơ sở lập trình (Programming Fundamentals) là môn học 3 tín chỉ của Đại học FPT, dạy cách giải quyết bài toán thực tế bằng máy tính thông qua ngôn ngữ C, với trọng tâm là thiết kế chương trình hướng hàm, mô-đun hoá, kiểm thử và kỷ luật lập trình. Nội dung môn học bao quát trọn bộ chương trình 60 buổi theo chín chuẩn đầu ra CLO1 đến CLO9. Nội dung gồm: máy tính và phần mềm (khái niệm cơ bản về hệ thống máy tính, các bước phát triển phần mềm, quy trình mã nguồn - biên dịch - liên kết - thực thi, cấu trúc một chương trình C với chỉ thị tiền xử lý #include, hàm main, dấu chấm phẩy kết thúc câu lệnh, chú thích, trình biên dịch và môi trường DevC++); biến, kiểu dữ liệu và biểu thức (khai báo biến và hằng, quy tắc đặt tên định danh, const và #define, các kiểu int, float, double, char và unsigned cùng miền giá trị, nhập xuất bằng scanf và printf với các đặc tả %d %f %c %s, toán tử số học, phép chia nguyên và phép chia lấy dư, toán tử quan hệ, toán tử logic, toán tử trên bit, toán tử gán rút gọn, tăng giảm một đơn vị, trộn kiểu dữ liệu, ép kiểu tường minh và ngầm định, độ ưu tiên và tính kết hợp); cấu trúc điều khiển (rẽ nhánh if, if-else, if lồng nhau, thang else-if, switch-case với break và default; vòng lặp for, while, do-while, break và continue, vòng lặp lồng nhau; phong cách lập trình với thụt lề, đặt tên có nghĩa và chú thích); mô-đun hoá và hàm (mô-đun là gì và vì sao phải mô-đun hoá, tính kết dính cao và ghép nối lỏng, nguyên tắc định nghĩa mô-đun, định nghĩa hàm với kiểu trả về và danh sách tham số, nguyên mẫu hàm, lời gọi hàm, truyền tham số theo giá trị, phân biệt hàm thư viện với hàm tự viết, phạm vi và thời gian sống của biến cục bộ - toàn cục - static, chương trình dạng menu gọi hàm); con trỏ (khái niệm và công dụng, khai báo con trỏ, toán tử lấy địa chỉ và toán tử truy xuất giá trị, số học con trỏ, con trỏ NULL, truyền tham số theo tham chiếu, quan hệ giữa con trỏ và mảng, cấp phát động bằng malloc, calloc, realloc và free, rò rỉ bộ nhớ); thư viện chuẩn C (stdlib.h, time.h, math.h, ctype.h và vào ra có định dạng); mảng và cấu trúc (mảng một chiều, chỉ số bắt đầu từ 0, mảng hai chiều và ma trận, tìm kiếm tuyến tính, sắp xếp chọn, kiểu struct, truy cập thành viên, mảng struct, typedef); chuỗi ký tự (chuỗi là mảng char kết thúc bằng ký tự null, nhập xuất chuỗi, các hàm trong string.h như strlen, strcpy, strcat, strcmp, mảng chuỗi); và tệp tin (tệp văn bản và tệp nhị phân, con trỏ FILE, fopen với các chế độ mở, fclose, truy cập tuần tự và ngẫu nhiên, fprintf, fscanf, fgets, fputs, fread, fwrite, fseek, ftell, feof).

266Câu hỏi
7Bộ đề
9Chủ đề

Câu hỏi của môn

204/266 câuCòn 62
185What will be the output of the following program?4 lựa chọncó code
Đề bài
int main()
{
        int i = 100;
        int *p = &i;
        *p +=2;
        printf("%d, %d", i, *p);
        getchar();
        return 0;
}
A102, 102
B100, 102
C100, 100
D102, 100
Lời giải
Đáp án đúng: "102, 102". Con trỏ p được gán địa chỉ của i nên nó trỏ thẳng vào ô nhớ của i; phép cộng dồn qua dấu sao không tạo bản sao nào mà cộng 2 ngay tại ô đó, vì vậy i trở thành 102. Khi printf chạy, cả i và nội dung được p trỏ tới đều đọc cùng một ô nhớ nên hai số in ra giống nhau; đó là bản chất của bí danh qua con trỏ, hai cách gọi tên cho cùng một vùng dữ liệu. Lựa chọn "100, 102" đòi i giữ nguyên trong khi vùng được trỏ tới đổi, chuyện chỉ xảy ra nếu p trỏ vào một biến khác. Lựa chọn "100, 100" là kết quả nếu phép cộng áp lên bản thân con trỏ, khi đó i không đổi nhưng con trỏ lại đọc sang vùng nhớ lạ. Lựa chọn "102, 100" vừa đòi i đổi vừa đòi phép lấy nội dung cho ra giá trị cũ, mâu thuẫn vì chúng là cùng một ô nhớ.
Mở trang câu hỏi này →
Aint* a = (int*)malloc(5*sizeof(int));
Bint a[5];
Cint a[5][5];
Dfree(a);
Lời giải
Đáp án đúng: "int* a = (int*)malloc(5*sizeof(int));". Cấp phát động nghĩa là xin bộ nhớ lúc chương trình đang chạy, với kích thước có thể tính ra tại thời điểm đó, và vùng xin được nằm trên heap, sống tới khi được giải phóng. Hàm malloc làm đúng việc đó: nhận số byte cần, trả về địa chỉ đầu vùng nhớ hoặc con trỏ rỗng khi thất bại, nên phải gán vào một con trỏ. Lựa chọn "int a[5];" là mảng tự động, kích thước cố định ghi sẵn lúc dịch và vùng nhớ bị thu hồi khi ra khỏi khối. Lựa chọn "int a[5][5];" chỉ là mảng hai chiều, bản chất vẫn là cấp phát theo khai báo. Lựa chọn "free(a);" đứng ở đầu bên kia của vòng đời: nó trả vùng nhớ đã cấp phát về cho hệ thống, không xin thêm ô nhớ nào.
Mở trang câu hỏi này →
Aopen()
Bfopen()
Cfileopen()
Dopenfile()
Lời giải
Đáp án đúng: "fopen()". Thư viện chuẩn mở tệp bằng fopen, khai báo trong stdio.h: nó nhận tên tệp cùng chế độ mở rồi trả về một con trỏ tệp để các hàm fscanf, fgets, fprintf, fclose dùng tiếp, hoặc trả về con trỏ rỗng nếu mở thất bại, nên luôn phải kiểm tra trước khi đọc ghi. Lựa chọn "open()" là lời gọi hệ thống của POSIX, nằm ngoài thư viện chuẩn và trả về một số hiệu tệp chứ không phải con trỏ tệp, nên không ghép được với họ hàm trong stdio.h. Lựa chọn "fileopen()" không tồn tại trong thư viện chuẩn. Lựa chọn "openfile()" cũng không tồn tại; cả hai chỉ là những cái tên nghe hợp lý được dựng ra để gây nhầm.
Mở trang câu hỏi này →
Aputc(s)
Bputs(s)
Cprintf(s)
Dprintf("%s",s)
Lời giải
Đáp án đúng gồm hai ý: "putc(s)" và "printf(s)". Hàm putc được khai báo để ghi một ký tự ra một dòng xuất, nên nó cần hai đối số là ký tự và dòng đích; đưa cho nó một chuỗi vừa thiếu đối số vừa sai kiểu, và dù có dịch được thì nó cũng chỉ xuất một ký tự. Còn cách gọi printf với chuỗi dữ liệu đặt ở vị trí chuỗi định dạng thì hễ trong chuỗi có dấu phần trăm, printf sẽ hiểu đó là đặc tả chuyển đổi rồi đi đọc đối số không tồn tại, sinh ra kết quả sai hoặc sự cố; đây là lỗi chuỗi định dạng kinh điển. Lựa chọn "puts(s)" là cách xuất chuỗi đúng và gọn, nó còn tự thêm ký tự xuống dòng. Lựa chọn "printf("%s",s)" cũng đúng vì chuỗi định dạng là hằng do người viết kiểm soát, còn dữ liệu được đặt đúng vị trí đối số.
Mở trang câu hỏi này →
189What does the following code print?6 lựa chọncó code
Đề bài
float y = 3 / 2;
printf("%f", y);
A1.000000
B1.500000
C1.0
D1.5
E1
FCompiler error
Lời giải
Đáp án đúng: "1.000000". Phép 3 chia 2 có hai toán hạng đều là hằng nguyên, nên C thực hiện chia nguyên và cắt phần thập phân ngay tại đó, cho ra 1; kiểu của biến nhận kết quả không hề tham gia quyết định phép chia nào được dùng. Chỉ sau khi đã có 1, giá trị ấy mới được chuyển ngầm thành 1.0 khi gán cho y. Đặc tả số thực in sáu chữ số sau dấu thập phân theo mặc định, nên màn hình hiện 1.000000. Lựa chọn "1.500000" chỉ đúng nếu ít nhất một toán hạng là số thực, chẳng hạn viết 3.0 chia 2. Lựa chọn "1.0" sai về dạng in vì đặc tả này không rút ngắn phần thập phân. Lựa chọn "1.5" sai cả về giá trị lẫn dạng in. Lựa chọn "1" là dạng của đặc tả số nguyên chứ không phải số thực. Lựa chọn "Compiler error" sai vì gán một số nguyên cho biến float là chuyển kiểu hợp lệ.
Mở trang câu hỏi này →
Afgets
Bfgetc
Cfputs
Dfpusc
Lời giải
Đáp án đúng: "fgets". Hàm fgets đọc từ dòng đã mở cho tới khi gặp ký tự xuống dòng, hết tệp hay đủ số ký tự tối đa, rồi đặt kết quả vào vùng đệm do người gọi đưa tới và tự thêm ký tự kết thúc chuỗi. Chính tham số giới hạn kích thước làm nó an toàn hơn gets, hàm đã bị loại khỏi chuẩn vì không chặn được tràn vùng đệm. Cũng lưu ý fgets giữ lại ký tự xuống dòng nếu vùng đệm còn đủ chỗ. Lựa chọn "fgetc" chỉ đọc đúng một ký tự mỗi lần gọi, muốn lấy cả dòng phải tự viết vòng lặp. Lựa chọn "fputs" đi theo chiều ngược lại, nó ghi một chuỗi ra dòng xuất. Lựa chọn "fpusc" không phải tên hàm nào của thư viện chuẩn, nó chỉ là biến dạng gõ sai của fputc.
Mở trang câu hỏi này →
A"r"
B"w+"
C"a+"
D"r+"
Lời giải
Đáp án đúng gồm hai ý: "w+" và "a+". Dấu cộng trong chế độ mở nghĩa là cho phép cả đọc lẫn ghi trên cùng một dòng; còn chữ đứng trước quyết định chuyện tệp có được tạo hay không. Chế độ ghi cắt sẽ tạo tệp mới nếu chưa có và xoá trắng nội dung nếu đã có; chế độ nối thêm cũng tạo tệp khi chưa có, giữ nguyên nội dung cũ và mọi lần ghi đều dồn về cuối tệp bất kể con trỏ tệp đang ở đâu. Cả hai vì vậy thoả đồng thời hai tiêu chí của câu hỏi. Lựa chọn "r" chỉ cho đọc và fopen trả về con trỏ rỗng nếu tệp không tồn tại, nên trượt cả hai tiêu chí. Lựa chọn "r+" cho cả đọc và ghi nhưng vẫn đòi tệp phải có sẵn, nó không tạo tệp mới, nên trượt đúng ở tiêu chí tạo tệp.
Mở trang câu hỏi này →
192What does the following code do?4 lựa chọncó code
Đề bài
int a = 5, b = 7;
int *pa = &a, *pb = &b;
*pa = *pa + *pb;
AAdds values at addresses a and b
BSwaps the values
CStores the address of b in a
DMultiplies both numbers
Lời giải
Đáp án đúng: "Adds values at addresses a and b". Con trỏ thứ nhất trỏ vào a, con trỏ thứ hai trỏ vào b, nên hai phép lấy nội dung chính là hai ô nhớ đó. Dòng lệnh đọc nội dung của cả hai ô, cộng lại rồi ghi tổng trở lại vào ô mà con trỏ thứ nhất trỏ tới, vì vậy a thành 12 còn b vẫn là 7. Toàn bộ việc diễn ra trên dữ liệu được trỏ tới, không có con trỏ nào bị gán lại. Lựa chọn "Swaps the values" sai vì đổi chỗ cần một biến tạm cùng hai phép gán, còn ở đây b không hề bị ghi. Lựa chọn "Stores the address of b in a" sai vì muốn vậy phải gán con trỏ này bằng con trỏ kia hay gán cho a địa chỉ của b, trong khi dòng lệnh chỉ làm việc với nội dung sau dấu sao. Lựa chọn "Multiplies both numbers" sai vì toán tử trong biểu thức là dấu cộng, không phải dấu nhân.
Mở trang câu hỏi này →
AAs an array of characters
BAs an array of strings
CAs individual characters
DAs integers referencing ASCII values
Lời giải
Đáp án đúng: "As an array of characters". Trong C không có kiểu chuỗi dựng sẵn: một chuỗi chỉ là dãy ký tự liền kề kết thúc bằng ký tự rỗng, và hầu hết hàm trong string.h dò đúng ký tự kết thúc ấy để biết chuỗi dài bao nhiêu. Vì vậy khi cấp ô nhớ cho chuỗi phải tính thêm một ô cho ký tự kết thúc. Lựa chọn "As an array of strings" mô tả một danh sách nhiều chuỗi, tức mảng con trỏ ký tự hay mảng hai chiều, không phải cách biểu diễn một chuỗi. Lựa chọn "As individual characters" nói về kiểu char đơn lẻ; một ký tự rời không có ký tự kết thúc nên các hàm chuỗi không làm việc được với nó. Lựa chọn "As integers referencing ASCII values" đúng ở chỗ mỗi ký tự được lưu bằng mã số, nhưng chuỗi không phải mảng số nguyên và cũng không bỏ được ký tự kết thúc.
Mở trang câu hỏi này →
194What does the following program display?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int arr[] = {3, 6, 9, 12};
    for (int i = 3; i >= 0; i -= 2)
        printf("%d ", arr[i]);
    return 0;
}
A3 9
B12 6
C12 6 3
D12 9 6
Lời giải
Đáp án đúng: "12 6". Vòng lặp khởi tạo i bằng 3, điều kiện là i không nhỏ hơn 0, và mỗi lượt i giảm đi 2. Lượt đầu i bằng 3 nên in phần tử cuối mảng là 12; lượt sau i bằng 1 nên in phần tử thứ hai là 6; tiếp đó i thành -1, điều kiện sai nên dừng. Hai bước đã đủ vì bước nhảy 2 làm vòng lặp chỉ chạm các chỉ số lẻ. Lựa chọn "3 9" là kết quả khi đi từ chỉ số 0 tăng dần 2 đơn vị, tức đọc các chỉ số chẵn theo chiều thuận. Lựa chọn "12 6 3" thêm phần tử đầu mảng, nhưng từ chỉ số 1 giảm 2 sẽ ra -1 chứ không ghé chỉ số 0. Lựa chọn "12 9 6" ứng với bước giảm 1 đơn vị rồi dừng sớm, không khớp với phép giảm 2 viết trong mã.
Mở trang câu hỏi này →
195What is an algorithm?4 lựa chọn
AA program executed using a computer
BA procedure used for solving a problem or performing a computation.
CA sequence of steps to solve a problem
DA description of hidden information
Lời giải
Đáp án đúng: "A procedure used for solving a problem or performing a computation.". Đây là định nghĩa gọn của thuật toán: một quy trình xác định dùng để giải một bài toán hoặc thực hiện một phép tính, gồm hữu hạn bước rõ nghĩa, có đầu vào đầu ra xác định và phải dừng. Thuật toán tồn tại độc lập với ngôn ngữ và máy móc, nên cùng một thuật toán viết được bằng nhiều ngôn ngữ khác nhau. Lựa chọn "A program executed using a computer" lẫn thuật toán với chương trình: chương trình chỉ là một cách hiện thực thuật toán trên máy. Lựa chọn "A sequence of steps to solve a problem" nghe gần đúng nhưng lỏng: một dãy bước mơ hồ hoặc không bao giờ dừng thì không phải thuật toán, và cách nói ấy cũng bỏ mất mảng thực hiện phép tính. Lựa chọn "A description of hidden information" không liên quan gì tới khái niệm thuật toán.
Mở trang câu hỏi này →
196What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
void main()
{
    int i = 10, j = 3, k = 3;
    printf("%d %d ", i, j, k);
}
ACompile time error
B10 3 3
C10 3
D10 3 somegarbage value
Lời giải
Đáp án đúng: "10 3". Hàm printf nhận số đối số thay đổi nên nó không kiểm tra số lượng lúc dịch; chính chuỗi định dạng quyết định lấy ra bao nhiêu giá trị. Ở đây chuỗi chỉ có hai đặc tả nên printf lấy i và j, in 10 rồi 3 kèm khoảng trắng, còn k vẫn được tính nhưng bị bỏ qua hoàn toàn. Chuẩn C cho phép truyền thừa đối số; chỉ truyền thiếu mới là hành vi không xác định. Lựa chọn "Compile time error" sai vì thừa đối số nhiều lắm chỉ bị cảnh báo, và dạng main trả về void dù phi chuẩn vẫn được nhiều trình dịch nhận. Lựa chọn "10 3 3" đòi chuỗi định dạng phải có ba đặc tả. Lựa chọn "10 3 somegarbage value" hiểu sai cơ chế: đối số thừa không bị in ra dưới dạng rác, nó chỉ nằm lại trong vùng tham số và không ai đọc tới.
Mở trang câu hỏi này →
197What is the output?4 lựa chọncó code
Đề bài
int arr[] = {1, 2, 3, 4};
printf("%d", *(arr + 2));
A1
B2
C3
D4
Lời giải
Đáp án đúng: "3". Tên mảng dùng trong biểu thức suy biến thành địa chỉ phần tử đầu, và số học con trỏ đếm theo phần tử chứ không theo byte, nên cộng 2 vào tên mảng cho ra địa chỉ của phần tử có chỉ số 2. Dấu sao lấy nội dung tại địa chỉ đó nên in ra 3. Đây đúng là nghĩa gốc của phép viết chỉ số: ngôn ngữ định nghĩa truy cập mảng chính là phép lấy nội dung của địa chỉ đầu cộng độ lệch. Lựa chọn "1" là phần tử ở chỉ số 0, tức kết quả nếu không cộng độ lệch nào. Lựa chọn "2" là phần tử ở chỉ số 1, ứng với cách đếm bắt đầu từ 1 thay vì từ 0. Lựa chọn "4" là phần tử ở chỉ số 3, sẽ đúng nếu độ lệch viết là 3.
Mở trang câu hỏi này →
198What is the output of the following program?4 lựa chọncó code
Đề bài
#include <stdio.h>
#include <string.h>
int main() {
    char s1[] = "FPTU";
    char s2[] = "fpt";
    char s3[] = "FPTU";
    printf("%d %d %d", strcmp(s1,s2), strcmp(s1,s3), strcmp(s2,s3));
    return 0;
}
A-1 0 1
B2 0 -2
C1 0 2
D1 0 -1
Lời giải
Đáp án đúng: "-1 0 1". Hàm strcmp so hai chuỗi theo mã ký tự tại vị trí lệch đầu tiên và chỉ cam kết dấu của giá trị trả về. So chuỗi viết hoa với chuỗi viết thường thì cặp lệch đầu tiên nằm ngay ký tự đầu: mã chữ hoa nhỏ hơn mã chữ thường nên kết quả âm. So chuỗi viết hoa với chuỗi giống hệt nó cho 0. So chuỗi viết thường với chuỗi viết hoa cho giá trị dương vì đảo chiều của phép so đầu. Thư viện của Visual Studio chuẩn hoá về -1, 0 và 1 nên dãy in ra khớp lựa chọn này; cần biết thư viện khác có thể trả về đúng chênh lệch 32 đơn vị, chỉ dấu là bất biến. Lựa chọn "2 0 -2" sai dấu ở cả hai đầu. Lựa chọn "1 0 2" cho kết quả dương ở phép so đầu, trái với việc chữ hoa đứng trước chữ thường trong bảng mã. Lựa chọn "1 0 -1" đảo dấu cả hai phép so khác 0.
Mở trang câu hỏi này →
Aa >= b
Ba == b
Ca != b
Da := b
Lời giải
Đáp án đúng: "a := b". C không có toán tử gồm dấu hai chấm kèm dấu bằng; cách viết đó là phép gán của Pascal, đưa vào mã C sẽ bị báo lỗi cú pháp. Trong C, gán là một dấu bằng, so sánh bằng là hai dấu bằng, và đây cũng là nguồn lỗi kinh điển khi người viết gõ thiếu một dấu bằng trong câu điều kiện: phép gán vẫn là biểu thức hợp lệ nên trình dịch không nhất thiết báo gì. Lựa chọn "a >= b" là phép so sánh lớn hơn hoặc bằng, hoàn toàn hợp lệ. Lựa chọn "a == b" là phép so sánh bằng đúng chuẩn, trả về 1 hoặc 0. Lựa chọn "a != b" là phép so sánh khác, cũng hợp lệ và cũng trả về số nguyên 1 hoặc 0.
Mở trang câu hỏi này →
ATo track variable changes and program output
BTo automatically compile and optimize the source code for better performance.
CTo generate comprehensive documentation and user manuals for the entire project
DTo convert high-level pseudocode into machine-readable assembly language instructions
Lời giải
Đáp án đúng: "To track variable changes and program output". Dò bước là việc người viết tự chạy chương trình trên giấy: lần theo từng câu lệnh, ghi lại giá trị mới của từng biến sau mỗi bước và ghi lại những gì chương trình xuất ra, nhờ đó phát hiện chỗ lệch giữa điều mình nghĩ và điều mã thực sự làm, kể cả khi mã dịch được và không báo lỗi nào. Lựa chọn "To automatically compile and optimize the source code for better performance." là việc của trình dịch, một bước tự động, trong khi dò bước là thao tác tay của con người. Lựa chọn "To generate comprehensive documentation and user manuals for the entire project" là việc của công cụ sinh tài liệu, không nhằm theo dõi giá trị biến. Lựa chọn "To convert high-level pseudocode into machine-readable assembly language instructions" tả quá trình dịch sang hợp ngữ, cũng không phải mục đích của dò bước.
Mở trang câu hỏi này →
Aint i = (double)123.5;
Bdouble t = double(2);
Cdouble t = (double) 2;
Ddouble t = (int) 2.7;
Lời giải
Đáp án đúng: "int i = (double)123.5;". Hằng 123.5 vốn đã mang kiểu double nên phép ép kiểu viết ra ở đây không làm gì cả; việc thật sự xảy ra là phép chuyển ngầm khi gán một giá trị double cho biến int, và chính phép chuyển ngầm đó cắt phần thập phân để i nhận 123. Đó là mẫu chuyển kiểu ngầm thu hẹp kinh điển mà câu hỏi nhắm tới. Lựa chọn "double t = double(2);" không phải cú pháp của C, cách gọi kiểu như hàm chỉ có trong C++. Lựa chọn "double t = (double) 2;" đã nói rõ ý định bằng phép ép kiểu tường minh, sau đó không còn phép chuyển nào nữa vì hai bên đã cùng kiểu. Lựa chọn "double t = (int) 2.7;" cũng có một bước ngầm từ int lên double, nhưng bước ấy giữ nguyên giá trị, còn thay đổi đáng kể là cắt 2.7 xuống 2 thì đã do phép ép kiểu tường minh làm, nên dòng này tiêu biểu cho chuyển kiểu tường minh.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>
void main()
{
    int i = 0;
    while (i < 5)
    {
        i++;
        printf("Hi-");
        while (i < 4)
        {
            i++;
            printf("Hello-");
        }
    }
}
AHi-Hi-Hi-Hi-Hello-Hello-Hello-Hi-
BHi-Hi-Hi-Hi-Hi-Hello-Hello-Hello-
CHi-Hello-Hello-Hello-Hello-Hi-
DHi-Hello-Hello-Hello-Hi-
Lời giải
Đáp án đúng: "Hi-Hello-Hello-Hello-Hi-". Hai vòng lặp dùng chung biến i nên vòng trong ăn luôn phần đếm của vòng ngoài. Vào vòng ngoài lần đầu với i bằng 0: i tăng thành 1 rồi in Hi-; vòng trong chạy khi i còn nhỏ hơn 4, lần lượt đưa i lên 2, 3, 4 và in Hello- ba lần. Quay lại vòng ngoài, i bằng 4 vẫn nhỏ hơn 5 nên i thành 5 và in Hi- lần thứ hai; lúc này điều kiện vòng trong đã sai nên không in thêm Hello-. Vòng ngoài kiểm tra lại, i bằng 5 nên dừng. Lựa chọn "Hi-Hi-Hi-Hi-Hello-Hello-Hello-Hi-" giả định vòng ngoài chạy nhiều lượt trước khi vòng trong vào việc, trái với thứ tự lồng nhau. Lựa chọn "Hi-Hi-Hi-Hi-Hi-Hello-Hello-Hello-" tách hẳn hai vòng thành hai giai đoạn rời. Lựa chọn "Hi-Hello-Hello-Hello-Hello-Hi-" đếm bốn lần Hello-, nhưng i đã là 1 khi vào vòng trong nên chỉ còn ba bước để tới 4.
Mở trang câu hỏi này →
203What is the output of the following code?4 lựa chọncó code
Đề bài
for (int i = 0; i < 5; i++) {
    if (i == 2) continue;
    printf("%d ", i);
}
A0 1 3 4
B0 1 2 3 4
C0 1
D2 3 4
Lời giải
Đáp án đúng: "0 1 3 4". Lệnh continue không thoát vòng lặp, nó chỉ bỏ phần thân còn lại của lượt đang chạy rồi nhảy tới bước cập nhật và kiểm tra điều kiện. Với i bằng 0 và 1 thì điều kiện trong không thoả nên printf chạy; tới i bằng 2, continue cắt ngang trước printf nên số 2 không được in, nhưng i vẫn tăng bình thường; các lượt i bằng 3 và 4 lại in như thường. Lựa chọn "0 1 2 3 4" là kết quả nếu bỏ hẳn câu điều kiện, tức không bỏ qua lượt nào. Lựa chọn "0 1" là kết quả nếu dùng break, vì break mới kết thúc cả vòng lặp tại i bằng 2. Lựa chọn "2 3 4" làm ngược lại ý nghĩa của câu điều kiện, như thể chỉ bắt đầu in từ lúc i đạt 2.
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 →