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

244/266 câuCòn 22
225What 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 →
226What 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 →
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 →
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 →
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 →
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 →
231What 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 →
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 →
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 →
234What 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 →
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 →
Đề 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 →
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 →
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 →
Đề 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 →
AWriting formatted data to a file.
BReading formatted data from a file.
CAppending formatted data to a file.
DClosing a file.
Lời giải
Đáp án đúng: "Writing formatted data to a file." Hàm fprintf là bản mở rộng của printf: tham số đầu là con trỏ tệp chỉ luồng đích, phần sau vẫn là chuỗi định dạng và danh sách giá trị, nên nó biến các giá trị trong bộ nhớ thành văn bản rồi ghi vào luồng đó. Mô tả "Reading formatted data from a file." là việc của fscanf, hàm đi hướng ngược lại và cần địa chỉ biến để nạp vào. Mô tả "Appending formatted data to a file." nói về vị trí ghi chứ không phải về hàm: ghi nối vào cuối hay ghi từ đầu do chế độ mở trong fopen quyết định, cùng một fprintf sẽ nối thêm với chế độ mở nối và ghi đè với chế độ mở ghi. Mô tả "Closing a file." là việc của fclose, hàm đẩy nốt vùng đệm xuống đĩa rồi giải phóng cấu trúc tệp.
Mở trang câu hỏi này →
Afputs()
Bfscanf()
Cfgets()
Dfopen()
Lời giải
Đáp án đúng: "fputs()". Hàm này nhận một chuỗi kết thúc rỗng cùng con trỏ tệp, rồi ghi các ký tự của chuỗi vào luồng, bỏ lại byte kết thúc và không tự thêm dấu xuống dòng, nên nó là cách trực tiếp nhất để đưa một chuỗi ra tệp. Hàm "fscanf()" đi hướng ngược lại, đọc dữ liệu từ tệp theo chuỗi định dạng và cần địa chỉ biến để nạp vào, nên không ghi gì cả. Hàm "fgets()" cũng là hàm đọc, lấy một dòng từ tệp vào vùng đệm có giới hạn độ dài; cặp fgets và fputs dễ nhầm chính vì tên gần giống nhau mà hướng dữ liệu trái ngược. Hàm "fopen()" chỉ mở tệp và trả về con trỏ tệp cho các hàm khác dùng, bản thân nó không chuyển một byte nội dung nào.
Mở trang câu hỏi này →
Afopen("file.txt", "r")
Bopen("file.txt", "w")
Cfopen("file.txt", "w")
Dopen("file.txt", "r")
Lời giải
Đáp án đúng: "fopen("file.txt", "r")". Thư viện chuẩn mở tệp bằng fopen: hàm nhận tên tệp và chuỗi chế độ, trả về con trỏ tệp hoặc giá trị rỗng nếu thất bại; chế độ đọc mở tệp sẵn có, đặt vị trí ở đầu và không làm hỏng nội dung. Lệnh "fopen("file.txt", "w")" vẫn đúng hàm nhưng chế độ ghi cắt tệp về rỗng nếu tệp đã có, dùng để đọc là mất dữ liệu. Lệnh "open("file.txt", "r")" sai hàm: open là lời gọi hệ thống của POSIX, khai báo trong fcntl.h, nhận cờ dạng số chứ không nhận chuỗi chế độ, và trả về số hiệu tệp chứ không phải con trỏ tệp. Lệnh "open("file.txt", "w")" sai cả hai mặt, vừa dùng lời gọi hệ thống với chuỗi chế độ không hợp lệ, vừa nhắm ý ghi trong khi đề hỏi mở để đọc.
Mở trang câu hỏi này →
Đề bài
for (i = 2; i <= n; i++) {
    S *= i;
}
printf("%d", S);
A120
B60
C24
D100
Lời giải
Đáp án đúng: "120". Biến tích khởi tạo bằng 1 vì đó là phần tử trung tính của phép nhân; khởi tạo bằng 0 thì mọi phép nhân sau đó đều cho 0. Vòng lặp cho i chạy từ 2 tới n là 5, mỗi nhịp nhân dồn, nên giá trị lần lượt là 2, 6, 24 rồi 120, đúng bằng giai thừa của 5. Số "60" đúng bằng tích của 3, 4 và 5, tức bỏ mất nhịp nhân với 2 ở đầu vòng lặp. Số "24" là giai thừa của 4, tức kết quả khi điều kiện dừng ở i nhỏ hơn n thay vì nhỏ hơn hoặc bằng n, bỏ mất nhịp cuối. Số "100" không phải tích của dãy số nguyên liên tiếp nào bắt đầu từ 2. Ở đây thân vòng có ngoặc nhọn nên phạm vi rõ ràng, dù bên trong chỉ có một lệnh.
Mở trang câu hỏi này →
244What will the following code output?4 lựa chọncó code
Đề bài
#include <stdio.h>
int main() {
    int a = 5, b = 3;
    printf("%d", a & b);
    return 0;
}
A1
B2
C3
D5
Lời giải
Đáp án đúng: "1". Một dấu và đơn lẻ là phép và theo từng bit, khác hẳn hai dấu và của phép và logic. Viết 5 ở hệ hai là 0101, viết 3 là 0011; ghép từng cặp bit cùng vị trí, chỉ chỗ nào cả hai đều bằng 1 mới cho 1, nên kết quả là 0001, tức 1, và printf in nó bằng %d. Số "2" ở hệ hai là 0010, nó đòi bit thứ hai bằng 1 trong cả hai toán hạng, nhưng 5 không có bit đó. Số "3" là chính giá trị của b, ứng với việc hiểu nhầm dấu và thành phép lấy toán hạng bên phải. Số "5" là chính giá trị của a, ứng với việc hiểu nhầm thành phép lấy toán hạng bên trái; cả hai cách hiểu đó đều bỏ qua việc so từng bit, thứ làm nên bản chất của toán tử này.
Mở trang câu hỏi này →