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.

300/11.033 câuCòn 10.733
Đề 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 →
282What 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 →
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 →
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 →
285What 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 →
286What 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 →
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 →
Đề 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 →
289What 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 →
290Suppose 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 →
291Which 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 →
292What 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 →
Đề 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 →
Đề 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 →
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 →
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 →
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 →
Awhile (condition) {...}
Bwhile (initialization; condition) {...}
Cwhile (condition; increment) {...}
Dwhile (initialization; increment; condition) {...}
Lời giải

Đáp án đúng: "

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

". Lệnh while trong C chỉ nhận duy nhất một biểu thức trong cặp ngoặc tròn; biểu thức đó được tính trước mỗi lần chạy thân và vòng lặp còn tiếp khi giá trị khác 0, nên mọi việc khởi tạo phải làm trước vòng lặp còn việc cập nhật phải nằm trong thân. Khuôn "

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

" đưa phần khởi tạo vào trong ngoặc, đó là thành phần riêng của for, hơn nữa dấu chấm phẩy không được phép xuất hiện trong ngoặc điều kiện. Khuôn "

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

" mắc đúng lỗi ấy: phần tăng giảm phải là một lệnh trong thân chứ không phải vế thứ hai của điều kiện. Khuôn "

Lời giải
while (initialization; increment; condition) {
  ...
}

" là khuôn ba phần của for và còn xếp sai trật tự, vì trong for thì điều kiện đứng giữa còn phần cập nhật đứng cuối.

Mở trang câu hỏi này →
A5
B22
C18
D25
E28
Lời giải
Đáp án đúng: "25". Hằng 0x11 viết ở hệ mười sáu nên có giá trị 17 với dãy bit 10001; hằng 010 mở đầu bằng chữ số 0 nên C đọc là hệ tám, giá trị 8 với dãy bit 01000. Phép hoặc theo bit xét từng cặp bit và bật kết quả khi có ít nhất một bên bật, cho 11001, tức 25. Một tính chất giúp loại nhanh: phép hoặc chỉ bật thêm bit, không bao giờ tắt bit đang bật, nên kết quả không thể nhỏ hơn 17. Vì thế giá trị "5" bị loại ngay, nó còn nhỏ hơn cả toán hạng thứ nhất. Giá trị "22" có dãy bit 10110, vừa tắt mất bit thấp nhất mà 17 đang bật, vừa bật bit giá trị 4 mà không toán hạng nào bật. Giá trị "18" có dãy bit 10010, cũng tắt bit thấp nhất của 17 nên không thể là kết quả. Giá trị "28" có dãy bit 11100, mất bit thấp nhất và tự sinh bit giá trị 4, đó là kiểu sai do cộng dồn chứ không phải do lấy hoặc theo bit.
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 →