Tất cả câu hỏi

Ngân hàng câu hỏi trắc nghiệm có giải thích chi tiết.

360/11.248 câuCòn 10.888
Đề bài
#include <stdio.h>
int main(){
    int n =12, re;float x, y;
    printf("input =");
    re = scanf("%d%f%f",&n,&x,&y);
    printf("%d, %d, %f",n, re, x);
}
A2, 2, 2.5
B2, 3, 2.5
C2, 2, 0.5
D2, 3, 0.5
Lời giải
Đáp án đúng: "2, 3, 0.5". Dãy ký tự nhập là 2.5 rồi dấu cách rồi 3.6, nhưng scanf đọc theo đặc tả chứ không theo cách con người đọc. Đặc tả %d chỉ nhận chữ số nên nó lấy 2 rồi dừng ngay trước dấu chấm, n thành 2. Đặc tả %f tiếp tục từ dấu chấm, đọc .5 thành số thực 0.5 cho x. Đặc tả %f thứ hai bỏ qua dấu cách rồi đọc 3.6 cho y. Cả ba chuyển đổi đều thành công nên scanf trả về 3, giá trị gán cho re. Dãy "2, 2, 2.5" đếm thiếu một chuyển đổi và coi như %f đã lấy trọn 2.5. Dãy "2, 3, 2.5" đúng số chuyển đổi nhưng vẫn gán 2.5 cho x, điều không thể vì phần nguyên đã bị %d lấy mất. Dãy "2, 2, 0.5" đúng x nhưng báo chỉ hai chuyển đổi, trong khi y cũng được nạp từ 3.6.
Mở trang câu hỏi này →
AAddress of the variable a
BValue of the variable a or 5
CSize of the variable a or 8
DType of the variable a or double
Lời giải
Đáp án đúng: "Address of the variable a". Dấu và đứng trước một toán hạng là phép lấy địa chỉ: nó cho biết vị trí trong bộ nhớ nơi biến được cấp chỗ, và kiểu của kết quả là con trỏ tới kiểu của biến, ở đây là con trỏ double. Giá trị này thường in bằng %p sau khi ép sang con trỏ void, và chính nó là thứ phải truyền cho scanf hay cho hàm muốn ghi vào biến. Mô tả "Value of the variable a or 5" là thứ lấy được khi đọc chính a, không cần toán tử nào; dù a khởi tạo từ số nguyên 5 thì nó vẫn là double mang giá trị 5.0. Mô tả "Size of the variable a or 8" là việc của sizeof. Mô tả "Type of the variable a or double" không phải giá trị mà biểu thức C trả về được; kiểu chỉ tồn tại lúc dịch, chương trình đang chạy không có phép toán nào cho ra tên kiểu.
Mở trang câu hỏi này →
Aprintf("a[3] = %d\n", a[3]);
Bprintf("*(a + 3) = %d\n", *(a + 3));
Cprintf("&a[3] = %p\n", (void*)&a[3]);
DAll the above
Lời giải

Đáp án đúng: "All the above". Phần tử thứ tư nằm ở chỉ số 3 vì chỉ số đếm từ 0, và chuẩn C định nghĩa a[3] chính là *(a + 3), nên hai lối viết khác nhau trên mặt chữ lại sinh ra cùng một phép truy cập; lấy &a[3] thì chạm tới đúng phần tử đó ở mức địa chỉ. Cả ba lệnh in đều hợp lệ và đều nói về phần tử thứ tư, nên chỉ lựa chọn gộp mới trả lời đủ. Lệnh "printf("a[3] = %d\n", a[3]);" đúng nhưng chỉ là một trong ba cách. Lệnh "printf("*(a + 3) = %d\n", *(a + 3));" cũng đúng và theo định nghĩa là cùng một thao tác với lối dùng chỉ số, nên không thể đúng một mình. Lệnh "printf("&a[3] = %p\n", (void*)&a[3]); " in địa chỉ của phần tử thứ tư, vẫn là truy cập hợp lệ tới nó, chỉ khác là lấy địa chỉ thay vì lấy giá trị.

Mở trang câu hỏi này →
Đề bài
void input(int* a, int n);
AIt is a pointer to the first element of the array
BIt holds the array size
CIt defines the function return type
DIt stores the index of the element
Lời giải
Đáp án đúng: "It is a pointer to the first element of the array". Trong C mảng không truyền được theo giá trị: viết tên mảng ở lời gọi thì nó tự suy biến thành địa chỉ phần tử đầu, nên tham số int* a nhận đúng địa chỉ đó, và trong hàm a[i] tương đương *(a + i), cho phép hàm ghi thẳng vào mảng của nơi gọi. Vì địa chỉ không mang theo số phần tử, hàm cần thêm tham số n, và đó mới là chỗ giữ kích thước, nên "It holds the array size" gán sai vai. Mô tả "It defines the function return type" sai vì kiểu trả về là void, viết trước tên hàm, chẳng liên quan tới danh sách tham số. Mô tả "It stores the index of the element" cũng sai vì chỉ số là một số nguyên thường, dùng bên trong hàm khi duyệt mảng, không phải một con trỏ.
Mở trang câu hỏi này →
A1 bytes
B2 bytes
C4 bytes
D8 bytes
Lời giải
Đáp án đúng: "4 bytes". Kiểu của con trỏ quyết định trình dịch đọc ghi bao nhiêu byte khi lấy giá trị qua dấu sao, và bước nhảy khi cộng trừ con trỏ. Trên các trình dịch phổ thông ngày nay, kiểu int chiếm bốn byte, nên *p làm việc trên bốn byte và p + 1 nhảy bốn byte. Số "1 bytes" là kích thước của char, kiểu duy nhất mà chuẩn ấn định bằng một byte. Số "2 bytes" là kích thước thường thấy của short, và cũng là kích thước int trên những trình dịch mười sáu bit rất cũ. Số "8 bytes" là kích thước của double hay long long, và cũng là chỗ chứa chính biến con trỏ trên nền sáu mươi tư bit, nhưng câu hỏi hỏi vùng nhớ được truy cập qua con trỏ chứ không hỏi chỗ chứa con trỏ.
Mở trang câu hỏi này →
346What does the following program print?4 lựa chọncó code
Đề bài
#include <stdio.h>

int main()
{
    int a = 4;
    int *b = &a;

    a -= 1;
    *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". Câu int *b = &a cho b giữ địa chỉ của a, nên từ đó a và *b là hai cách gọi cùng một ô nhớ chứ không phải hai bản sao. Lệnh a -= 1 hạ ô đó từ 4 xuống 3, rồi *b -= 1 hạ tiếp chính ô đó xuống 2; vậy cả hai cách đọc đều cho 2 và printf in hai số giống nhau. Dãy "2 1" giả định *b có ô riêng cũng bắt đầu từ 4 rồi chỉ bị trừ một lần, tức hiểu con trỏ thành bản sao. Dãy "3 1" giả định a chỉ chịu phép trừ thứ nhất còn phép trừ thứ hai tác động lên một vùng khác. Dãy "3 3" chỉ đúng nếu phép trừ qua con trỏ không có tác dụng gì, trong khi *b -= 1 ghi thẳng vào ô mà b trỏ tới.
Mở trang câu hỏi này →
A-6 and 5.
B-5 and 5.
C-6 and 6.
D-5 and 6.
Lời giải
Đáp án đúng: "-6 and 5." Hàm floor của thư viện toán lấy số nguyên lớn nhất không vượt quá đối số, tức luôn làm tròn xuống phía âm vô cực, chứ không cắt phần thập phân và cũng không làm tròn về số gần nhất. Với -5.9, các số nguyên không vượt quá nó là -6, -7 và nhỏ hơn, lớn nhất trong đó là -6. Với 5.9, số nguyên lớn nhất không vượt quá là 5. Cặp "-5 and 5." là kết quả của phép cắt phần thập phân, tức hành vi của ép kiểu sang int, và với số âm nó cho giá trị lớn hơn floor. Cặp "-6 and 6." trộn floor cho số âm với ceil cho số dương. Cặp "-5 and 6." chính là làm tròn ra xa số không, không phải floor. Cần nhớ floor trả về double, nên in bằng %f sẽ thấy -6.000000 và 5.000000.
Mở trang câu hỏi này →
AThe getchar() function is defined in the <stdio.h> header file.
Bgetchar() gets a string from stdin.
Cgetchar() retrieves a single character from the standard input stream buffer without translating the input.
Dgetchar() gets a character (an unsigned char) from stdin.
Lời giải

Đáp án đúng: "getchar() gets a string from stdin." Câu hỏi tìm phát biểu sai, và đây đúng là phát biểu sai: getchar không đọc chuỗi, nó lấy đúng một ký tự rồi trả về dưới dạng int để còn chỗ cho giá trị báo hết tệp; muốn đọc cả dòng phải dùng fgets. Câu "The getchar() function is defined in the <stdio.h> header file." là phát biểu đúng, hàm thuộc thư viện vào ra chuẩn. Câu "getchar() retrieves a single character from the standard input stream buffer without translating the input." cũng đúng: hàm lấy một ký tự từ vùng đệm của luồng vào chuẩn và không diễn dịch gì thêm. Câu "getchar() gets a character (an unsigned char) from stdin." đúng nốt, vì ký tự đọc được hiểu như unsigned char rồi nâng lên int. Ba phát biểu đúng ấy không thể là thứ câu hỏi đang tìm.

Mở trang câu hỏi này →
349What does the following program print?4 lựa chọncó code
Đề bài
#include <stdio.h>

float max(float a, float b) {
    return a > b ? a : b;
}

int main() {
    float x = 5.5, y = 4.5, z = 2;
    printf("%f", max(max(x++, y--), ++z));

    return 0;
}
A5.5
B5.500000
C4.500000
DAn error will be raised.
Lời giải
Đáp án đúng: "5.500000". Hàm max dùng toán tử ba toán hạng để trả về số lớn hơn. Lời gọi trong cùng là max(x++, y--): cả hai phép tăng giảm đều ở dạng hậu tố nên truyền sang hàm giá trị cũ, tức 5.5 và 4.5, và hàm cho 5.5; sau đó x thành 6.5, y thành 3.5 nhưng không còn ai đọc. Lời gọi ngoài so 5.5 với ++z, dạng tiền tố nên z tăng trước rồi truyền sang 3.0, kết quả vẫn là 5.5. Đặc tả %f in số thực với sáu chữ số thập phân mặc định, nên màn hình hiện 5.500000. Dòng "5.5" là cách con người viết số đó, không phải cách printf in với %f. Dòng "4.500000" là giá trị cũ của y, thứ bị loại ngay ở lời gọi trong cùng. Kết luận "An error will be raised." sai vì tham số float, phép tăng giảm trên số thực và việc lồng hai lời gọi đều hợp lệ.
Mở trang câu hỏi này →
Aint minus(int a; int b) {return (a - b);}
Bint minus (int a, b) {return (a - b);};
Cint minus (int a, int b) {return (a - b);}
Dint minus (int a, b) {return (a - b);}
Lời giải

Đáp án đúng: "int minus (int a, int b) { return (a - b); }". Định nghĩa hàm theo lối nguyên mẫu đòi mỗi tham số mang đủ kiểu riêng, các tham số ngăn nhau bằng dấu phẩy, và thân hàm là một khối trong ngoặc nhọn; khoảng trắng thừa giữa các thành phần vô hại vì trình dịch bỏ qua. Dạng "int minus(int a; int b) { return (a - b); }" dùng dấu chấm phẩy ngăn hai tham số, thứ chỉ hợp lệ trong danh sách khai báo biến thường, nên danh sách tham số vỡ ngay. Dạng "int minus (int a, b) { return (a - b); }" để b không kiểu; chuẩn C hiện hành đã bỏ quy tắc ngầm hiểu kiểu int nên tham số thiếu kiểu bị báo lỗi. Dạng "int minus (int a, b) { return (a - b); };" mắc đúng lỗi thiếu kiểu đó, lại thêm một dấu chấm phẩy trống sau thân hàm, thứ chuẩn không cho phép ở mức tệp.

Mở trang câu hỏi này →
ALocal variables within a function are declared and initialized each time the function is called.
BLocal variables within a function can be accessed from any other function in the program.
CLocal variables within a function retain their value between different function calls.
DLocal variables within a function can be declared outside the function and still maintain local scope.
Lời giải
Đáp án đúng: "Local variables within a function are declared and initialized each time the function is called." Biến cục bộ mặc định có lớp lưu trữ tự động: chỗ cho nó được dành trên khung ngăn xếp lúc vào hàm và mất đi lúc ra hàm, nên mỗi lần gọi là một bản mới, và nếu khai báo kèm giá trị khởi tạo thì phép khởi tạo chạy lại từng lần. Câu "Local variables within a function can be accessed from any other function in the program." sai vì tên biến cục bộ chỉ thấy được trong khối khai báo nó; hàm khác muốn chạm vào phải nhận địa chỉ qua tham số. Câu "Local variables within a function retain their value between different function calls." là tính chất của biến thêm từ khoá static, thứ sống suốt chương trình. Câu "Local variables within a function can be declared outside the function and still maintain local scope." tự mâu thuẫn: khai báo ngoài hàm là có phạm vi tệp, không còn cục bộ.
Mở trang câu hỏi này →
Awhile (condition) { statements; }
B(condition){ statements ;}
Cwhile (condition) { statements };
D{ statements } while (condition);
Lời giải

Đáp án đúng: "

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

". Vòng while chuẩn gồm từ khoá while, điều kiện trong ngoặc tròn, rồi một câu lệnh làm thân; thân là cả khối khi bọc trong ngoặc nhọn, và mỗi câu lệnh bên trong khối phải kết thúc bằng dấu chấm phẩy. Sau ngoặc nhọn đóng không cần dấu chấm phẩy vì khối đã là một câu lệnh hoàn chỉnh. Dạng "(condition){ statements ;}" thiếu hẳn từ khoá while nên trình dịch chỉ thấy một biểu thức rồi một khối rời rạc. Dạng "

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

;" đặt dấu chấm phẩy sai chỗ: lệnh bên trong khối bị bỏ dấu kết thúc, còn dấu chấm phẩy lại nằm sau ngoặc nhọn đóng. Dạng "{ statements } while (condition); " là do while nhưng mất từ khoá do mở đầu, nên khối và phần while thành hai mảnh không gắn với nhau.

Mở trang câu hỏi này →
Avoid
Bint
Cfloat
Dchar
Lời giải
Đáp án đúng: "void". Từ khoá void ở vị trí kiểu trả về nói với trình dịch rằng hàm không mang giá trị nào về cho nơi gọi, nên trong thân hàm lệnh return chỉ được viết trơ một mình để kết thúc sớm, và lời gọi hàm không dùng được làm toán hạng của biểu thức hay vế phải của phép gán. Kiểu "int" trả về số nguyên, bắt buộc với main và là mặc định của các trình dịch rất cũ, nhưng khai báo kiểu này rồi không trả giá trị là hành vi không xác định khi nơi gọi đọc kết quả. Kiểu "float" trả về số thực độ chính xác đơn, vẫn là một giá trị cụ thể. Kiểu "char" trả về một ký tự, tức một byte, cũng là một giá trị. Cả ba đều buộc hàm phải có giá trị để mang về, trái với điều câu hỏi nêu.
Mở trang câu hỏi này →
354What will be the output of the following C code?4 lựa chọncó code
Đề bài
#include <stdio.h>
void main()
{
    int total=0;
    for(int s=1; s<15; s++)
        total=total+s;
    printf("%d",total);
}
A105
B150
C120
D210
Lời giải
Đáp án đúng: "105". Biến s khởi tạo bằng 1 và vòng lặp còn chạy khi s nhỏ hơn 15, nên s nhận lần lượt các giá trị từ 1 tới 14; thân vòng không có ngoặc nhọn nên chỉ gồm đúng lệnh cộng dồn total = total + s. Tổng các số nguyên từ 1 tới 14 bằng 14 nhân 15 rồi chia 2, tức 105, và printf in giá trị đó. Số "150" không ứng với tổng của dãy liên tiếp nào ở đây. Số "120" là tổng từ 1 tới 15, tức hiểu điều kiện s nhỏ hơn 15 thành nhỏ hơn hoặc bằng 15, nhưng khi s lên 15 thì điều kiện đã sai và thân vòng không chạy nữa. Số "210" là tổng từ 1 tới 20. Kiểu void main không chuẩn nhưng nhiều trình dịch vẫn nhận, nên kết quả in ra không đổi.
Mở trang câu hỏi này →
355What will be the output of the C program?4 lựa chọncó code
Đề bài
int 2_var = 15;
printf("%d", 2_var);
A0
B15
CCompilation error.
DRuntime error.
Lời giải
Đáp án đúng: "Compilation error." Tên định danh trong C phải bắt đầu bằng chữ cái hoặc dấu gạch dưới, các ký tự sau mới được là chữ số. Dãy 2_var mở đầu bằng chữ số nên bộ phân tích từ vựng tách nó thành hằng số 2 rồi tới _var, câu khai báo trở thành vô nghĩa và lỗi bị bắt ngay lúc dịch, chương trình không bao giờ có tệp chạy. Kết quả "0" giả định biến vẫn tồn tại và mang giá trị rỗng, điều chỉ xảy ra với biến toàn cục chưa gán. Kết quả "15" giả định khai báo chạy được và printf in đúng số vừa gán, nhưng đoạn mã không qua nổi bước dịch nên không có gì được in. Kết luận "Runtime error." đòi chương trình phải chạy rồi mới hỏng, trong khi đây là lỗi cú pháp thuần, phát hiện trước khi chạy.
Mở trang câu hỏi này →
AThe condition
BThe initialization block
CThe iteration statement
DThe body of the loop
Lời giải
Đáp án đúng: "The initialization block". Cấu trúc for có ba phần trong ngoặc tròn, cách nhau bằng dấu chấm phẩy, và phần đầu chạy đúng một lần trước khi vòng lặp thực sự bắt đầu, thường để tạo và gán giá trị đầu cho biến đếm. Thứ tự sau đó lặp lại mãi: kiểm điều kiện, chạy thân, rồi chạy phần cập nhật. Mô tả "The condition" được kiểm trước mỗi nhịp kể cả nhịp đầu, nhưng nó chỉ chạy sau khi phần khởi tạo đã xong nên không phải thứ chạy trước vòng lặp. Mô tả "The iteration statement" là phần thứ ba, chạy ở cuối mỗi nhịp rồi mới quay lại kiểm điều kiện. Mô tả "The body of the loop" chỉ chạy khi điều kiện còn đúng, và có thể không chạy lần nào nếu điều kiện sai ngay từ đầu.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>

int main()
{
    int x = 5, y = 3, z = 1;
    x = x % 3 + z++;
    z = x * y--;
    printf("%d %d %d", x, y, z);

    return 0;
}
A5 3 1
B3 2 9
C2 2 5
DCompiler error
Lời giải
Đáp án đúng: "3 2 9". Đề hỏi biến b nhưng chương trình không có biến nào tên b, nên chỉ có thể trả lời theo đúng thứ printf in ra. Dòng x = x % 3 + z++ tính 5 % 3 bằng 2, còn z++ là tăng sau nên nó đưa vào biểu thức giá trị cũ 1 rồi mới nâng z lên 2; vậy x thành 3. Dòng z = x * y-- lấy x bằng 3 nhân với giá trị cũ của y là 3, cho 9, sau đó y giảm còn 2. Lúc printf chạy, x bằng 3, y bằng 2, z bằng 9. Dãy "5 3 1" là bộ giá trị khởi tạo ban đầu, tức bỏ qua cả hai phép gán. Dãy "2 2 5" ứng với việc tính x chỉ bằng 5 % 3 mà bỏ quên phần cộng z++, nên cả ba số sau đó đều lệch. Kết luận "Compiler error" sai vì mã hợp lệ: phép lấy dư, tăng sau và giảm sau đều áp đúng trên biến int.
Mở trang câu hỏi này →
Đề bài
char s[] = "AbCd";
printf("%d;%d;%d;%d", s[1],  s[2],  s[3],  s[4]);
A97;98;99;100
B65;66;67;68
C65;98;67;100
D98;67;100;0
Lời giải
Đáp án đúng: "98;67;100;0". Mảng s chiếm năm byte: bốn chữ cái và byte rỗng kết thúc ở chỉ số 4. Mỗi phần tử là một char, in bằng %d nên giá trị được nâng lên int và hiện ra dưới dạng mã ASCII. Chỉ số đếm từ 0, vậy s[1] là chữ b thường mã 98, s[2] là chữ hoa thứ hai mã 67, s[3] là chữ d thường mã 100, còn s[4] là byte kết thúc mang giá trị 0. Dãy "97;98;99;100" là mã của bốn chữ thường liên tiếp, tức giả định chuỗi toàn chữ thường và đọc từ chỉ số 0. Dãy "65;66;67;68" là mã của bốn chữ hoa liên tiếp, cũng không khớp vì chuỗi xen chữ thường. Dãy "65;98;67;100" đọc từ s[0] nên lấy mã chữ hoa đầu tiên, lệch một nhịp so với yêu cầu của đề.
Mở trang câu hỏi này →
A5
B6
C4
DUndefined
Lời giải
Đáp án đúng: "5". Hàm strlen đếm số ký tự thực của chuỗi bằng cách đi từ byte đầu tới khi gặp byte rỗng kết thúc, và không tính byte đó. Chuỗi hello có năm chữ cái nên hàm trả về 5, dù mảng str chiếm sáu byte trong bộ nhớ. Đây là ranh giới cần nhớ: strlen cho độ dài logic, còn sizeof cho kích thước vùng nhớ. Số "6" chính là sizeof(str), tức năm ký tự cộng byte kết thúc, không phải thứ strlen trả về. Số "4" thiếu một ký tự, chỉ đúng nếu chuỗi là hell. Kết luận "Undefined" sai vì mảng được khởi tạo từ hằng chuỗi nên byte kết thúc đã có sẵn, strlen tìm thấy điểm dừng hợp lệ và kết quả hoàn toàn xác định.
Mở trang câu hỏi này →
A+=
B+
C++
D-
Lời giải
Đáp án đúng: "+=". Bảng ưu tiên của C xếp phép gán, kể cả gán phức hợp, ở gần đáy, chỉ trên toán tử phẩy; lý do là gán phải nhận trọn giá trị của biểu thức bên phải nên mọi phép tính bên phải buộc phải xong trước. Vì thế a += b * 2 được hiểu là a += (b * 2) chứ không phải (a += b) * 2. Toán tử "+" cộng hai toán hạng, nằm ở mức cộng trừ, chặt hơn mức gán. Toán tử "++" tăng một đơn vị, thuộc nhóm một toán hạng, đứng ở mức cao nhất cùng với ngoặc tròn và chỉ số mảng. Toán tử "-" khi trừ hai số thì cùng mức với phép cộng, còn khi làm dấu âm một toán hạng thì còn cao hơn nữa, nên cả ba đều ưu tiên hơn phép gán phức hợp.
Mở trang câu hỏi này →