Ngân hàng câu hỏi của chương

Câu hỏi: PRF192 - Phần 6: Thư viện chuẩn C và vào ra có định dạng

28 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 theo thứ tự nhập vào ngân hàng.

Danh sách câu hỏi

20/28 câuCòn 8
Đề bài
double a = -7.5, b = 7.5;
printf( "%.0f : %.0f\n", ceil( a ), ceil( b ) );
printf( "%.0f : %.0f\n", floor( a ), floor( b ) );
A-7 : 8 -8 : 7
B-7 : 7 -8 : 8
C-8 : 7 -8 : 7
D-8 : 7 -7 : 8
Lời giải
Đáp án đúng: "-7 : 8 -8 : 7". Hàm ceil làm tròn lên, lấy số nguyên nhỏ nhất không nhỏ hơn đối số: với -7.5 là -7 vì trên trục số -7 nằm bên phải -7.5, với 7.5 là 8. Hàm floor làm tròn xuống, lấy số nguyên lớn nhất không lớn hơn đối số: với -7.5 là -8, với 7.5 là 7. Vì vậy dòng đầu in -7 : 8 rồi dòng sau in -8 : 7; định dạng %.0f chỉ bỏ phần thập phân khi hiển thị, mà các giá trị đã nguyên nên không làm tròn thêm lần nào. "-7 : 7 -8 : 8" sai ở cột số dương vì ceil của 7.5 phải là 8. "-8 : 7 -8 : 7" lặp kết quả của floor cho cả hai dòng, tức coi ceil cũng làm tròn xuống. "-8 : 7 -7 : 8" đảo vai hai hàm, gán kết quả floor cho dòng gọi ceil và ngược lại.
Mở trang câu hỏi này →
Adouble
Bfloat
Cint
Dlong
Lời giải
Đáp án đúng: "double". Thư viện math.h làm việc với số thực độ chính xác kép, nên sqrt nhận một đối số double và trả về double; nhờ vậy căn bậc hai của 2 giữ được nhiều chữ số có nghĩa, và muốn in thì dùng định dạng %f hoặc %lf. "float" sai vì bản trả về float có tên riêng là sqrtf; gán kết quả của sqrt vào biến float thì bị thu hẹp và mất chính xác. "int" sai vì căn bậc hai nói chung không nguyên, trả về kiểu nguyên sẽ cắt mất phần thập phân, chẳng hạn căn của 2 thành 1. "long" sai cùng lý do, long vẫn là kiểu nguyên, chỉ khác độ rộng lưu trữ.
Mở trang câu hỏi này →
AA lowercase letter
BAn uppercase letter
CA digit
DA punctuation character
Lời giải
Đáp án đúng: "A lowercase letter". Hàm islower thuộc ctype.h, nhận mã của một ký tự và trả về giá trị khác 0 khi ký tự đó là chữ cái viết thường, trả 0 trong mọi trường hợp khác. Chuẩn chỉ hứa khác 0 chứ không hứa đúng bằng 1, nên nên dùng hàm này trực tiếp trong điều kiện thay vì so sánh với 1. "An uppercase letter" là việc của isupper; gặp chữ in hoa thì islower trả 0. "A digit" là việc của isdigit, ký tự chữ số không phải chữ cái thường nên cũng cho 0. "A punctuation character" là việc của ispunct, các dấu câu như dấu phẩy hay dấu chấm đều khiến islower trả 0.
Mở trang câu hỏi này →
Arandom()
Brand()
Cgenerate_random()
Dgetrand()
Lời giải
Đáp án đúng: "rand()". Hàm rand khai báo trong stdlib.h, mỗi lần gọi trả về một số nguyên giả ngẫu nhiên nằm trong khoảng từ 0 tới RAND_MAX, trong đó RAND_MAX là hằng do thư viện định nghĩa; muốn thu về đoạn hẹp hơn thì lấy phần dư, muốn dãy khác nhau giữa các lần chạy thì gọi srand với mầm thay đổi. "random()" không thuộc thư viện chuẩn C, nó là hàm mở rộng của một số hệ điều hành họ Unix và trả về kiểu long với khoảng giá trị khác. "generate_random()" không tồn tại trong thư viện chuẩn, gọi tới sẽ lỗi ở khâu liên kết. "getrand()" cũng không có trong thư viện chuẩn, tên này thường do người học tự đặt theo thói quen gọi hàm lấy giá trị.
Mở trang câu hỏi này →
AIt checks if a character is an alphabet.
BIt returns to a non-zero value if the character is a digit (0-9).
CIt only works with float inputs.
DIt converts a digit to integer.
Lời giải
Đáp án đúng: "It returns to a non-zero value if the character is a digit (0-9)." Hàm isdigit trong ctype.h xét mã ký tự và trả về giá trị khác 0 khi ký tự đó là một trong mười chữ số, trả 0 với mọi ký tự khác; đây là cách kiểm tra đúng khi đọc chuỗi nhập để biết người dùng có gõ số hay không. "It checks if a character is an alphabet." sai vì việc xét chữ cái thuộc hàm isalpha. "It only works with float inputs." sai vì hàm nhận một tham số kiểu int chứa mã ký tự, nó không liên quan gì tới số thực. "It converts a digit to integer." sai vì hàm chỉ kiểm tra chứ không chuyển đổi; muốn đổi ký tự số thành giá trị thì trừ đi mã của ký tự 0, hoặc dùng atoi cho cả chuỗi.
Mở trang câu hỏi này →
6What is the purpose of this function?4 lựa chọncó code
Đề bài
void get_a_line(char line[], int max) {
    int n = 0;
    char c;
    while ('\n' != (c = getchar()))
        if (n < max)
            line[n++] = c;
    line[n] = '\0';
}
AReads a line of input safely
BWrites a string to file
CCompares strings
DReverses string
Lời giải
Đáp án đúng: "Reads a line of input safely". Hàm đọc từng ký tự bằng getchar cho tới khi gặp ký tự xuống dòng, chỉ ghi vào mảng khi n còn nhỏ hơn max nên không bao giờ viết quá chỗ đã có, rồi đặt ký tự rỗng kết thúc chuỗi; chính phép kiểm tra n < max là thứ làm nó an toàn hơn cách đọc không giới hạn. Hàm vẫn còn điểm yếu đáng biết: phần dư của dòng nhập dài hơn max bị bỏ, và nếu luồng nhập kết thúc mà chưa có ký tự xuống dòng thì vòng lặp không gặp mốc dừng. "Writes a string to file" sai vì không có con trỏ tệp nào và cũng không gọi hàm ghi tệp. "Compares strings" sai vì hàm chỉ có một mảng và không có phép so sánh nào giữa hai chuỗi. "Reverses string" sai vì chỉ số n luôn tăng, các ký tự được đặt theo đúng thứ tự nhập.
Mở trang câu hỏi này →
Agetchar() and putchar()
Bgets() and puts()
Cscanf() and printf()
Dfgets() and fputs()
Lời giải
Đáp án đúng: "getchar() and putchar()". Hai hàm này thuộc nhóm vào ra một ký tự: getchar đọc đúng một ký tự từ dòng vào chuẩn và trả về mã của nó dưới dạng int để còn chỗ biểu diễn giá trị EOF, còn putchar ghi đúng một ký tự ra dòng ra chuẩn. Vì mỗi lần gọi chỉ xử lý một ký tự nên chúng là lựa chọn cho bài toán đọc hoặc ghi từng ký tự một. Ý "gets() and puts()" sai vì cặp này làm việc với cả một chuỗi, gets đọc trọn một dòng cho tới khi gặp ký tự xuống dòng và puts in cả chuỗi kèm dấu xuống dòng. Ý "scanf() and printf()" sai vì đó là vào ra có định dạng, đọc và ghi theo chuỗi định dạng với nhiều đối số thuộc nhiều kiểu khác nhau. Ý "fgets() and fputs()" sai vì chúng cũng thao tác trên chuỗi và còn nhận thêm đối số dòng tệp, dùng cho tệp hoặc cho dòng chuẩn chứ không phải cho một ký tự riêng lẻ.
Mở trang câu hỏi này →
Atime.h
Bconio.h
Cmath.h
Dstdlib.h
Lời giải
Đáp án đúng: "stdlib.h". Chuẩn C xếp hàm abs vào nhóm tiện ích số nguyên của stdlib.h cùng với labs, llabs và div, bởi abs làm việc trên int chứ không trên số thực, trong khi math.h được dành riêng cho các hàm toán học trên số thực. Ý "time.h" sai vì tệp tiêu đề đó khai báo những thứ liên quan tới thời gian như time, clock, difftime. Ý "conio.h" sai vì nó không phải tệp tiêu đề chuẩn, chỉ tồn tại trên một số trình biên dịch để làm các thao tác màn hình và bàn phím kiểu getch hay clrscr. Ý "math.h" sai vì nơi đó khai báo fabs cho double chứ không phải abs cho int; nhiều trình biên dịch có kèm thêm khai báo abs trong math.h như phần mở rộng riêng, nhưng chỗ được chuẩn hoá chính thức vẫn là stdlib.h.
Mở trang câu hỏi này →
A'c'
B'C'
C'c' or 'C' (depending on IDE)
DCompilation error
Lời giải
Đáp án đúng: "'c'". Hàm tolower chỉ đổi chữ hoa thành chữ thường tương ứng, còn với mọi ký tự khác nó trả về nguyên đối số. Ký tự truyền vào đã là chữ thường nên giá trị trả về vẫn là mã của chữ c, và đặc tả %c in ra đúng một ký tự c. Ý "'C'" sai vì biến chữ thường thành chữ hoa là việc của toupper, tolower không bao giờ làm ngược lại. Ý "'c' or 'C' (depending on IDE)" sai vì hành vi của tolower do chuẩn quy định dứt khoát theo miền ký tự đang dùng, nó không phụ thuộc môi trường soạn thảo hay trình biên dịch. Ý "Compilation error" sai vì lời gọi hoàn toàn hợp lệ, tolower nhận một int và trả về một int nên truyền hằng ký tự vào là chuyện bình thường; điều duy nhất cần nhớ là phải nạp tệp tiêu đề ctype.h để có khai báo của nó.
Mở trang câu hỏi này →
Aabs()
Blabs()
Cllabs()
Dfabs()
Lời giải
Đáp án đúng: "abs()". Thư viện chuẩn chia hàm lấy trị tuyệt đối theo từng kiểu để tránh chuyển đổi ngầm gây mất mát: abs nhận int và trả về int, nên đó là hàm dành riêng cho kiểu int. Ý "labs()" sai vì nó dành cho long, đem dùng cho int thì vẫn chạy nhờ phép nâng kiểu nhưng đó không phải hàm đặc trưng cho int. Ý "llabs()" sai vì nó dành cho long long, một kiểu nguyên rộng hơn và được bổ sung muộn hơn vào chuẩn. Ý "fabs()" sai vì nó nhận và trả về double, tức là dành cho số thực; truyền một int vào fabs thì giá trị bị đổi sang double, kết quả cũng là double, muốn gán về int lại phải cắt phần thập phân nên vừa sai kiểu vừa thừa hai bước chuyển đổi.
Mở trang câu hỏi này →
Amath.h
Bstdio.h
Cconio.h
Dmemory.h
Lời giải
Đáp án đúng: "math.h". Tệp tiêu đề này chứa nguyên mẫu của các hàm toán học trên số thực như sqrt, pow, sin, cos, fabs, ceil, floor, cùng các macro như HUGE_VAL. Có nguyên mẫu thì trình biên dịch mới biết hàm trả về double và mới kiểm được kiểu đối số; thiếu nó, lời gọi dễ bị hiểu sai kiểu trả về và cho ra kết quả lệch. Ý "stdio.h" sai vì nơi đó khai báo những thứ thuộc vào ra như printf, scanf, fopen và kiểu FILE. Ý "conio.h" sai vì đó không phải tệp tiêu đề chuẩn, nó chỉ có trên một số trình biên dịch để làm thao tác bàn phím và màn hình kiểu getch. Ý "memory.h" sai vì đó cũng là tệp ngoài chuẩn, gom vài hàm xử lý khối nhớ mà chuẩn C đặt trong string.h, chẳng hạn memcpy và memset.
Mở trang câu hỏi này →
Adouble result = sqrt(9);
Bint result = sqrt(9);
Cfloat result = sqrt(9);
Dresult = power(9, 0.5);
Lời giải
Đáp án đúng: "double result = sqrt(9);". Hàm sqrt được khai báo trong math.h với kiểu trả về double, nên hứng kết quả bằng một biến double là cách duy nhất giữ trọn giá trị mà hàm trả về, không có phép chuyển đổi thu hẹp nào xảy ra. Ý "int result = sqrt(9);" sai vì gán double cho int buộc phải cắt phần thập phân, ở đây tình cờ ra đúng 3 nhưng với căn của 2 hay của 10 thì mất hết phần lẻ. Ý "float result = sqrt(9);" sai vì float hẹp hơn double nên giá trị bị làm tròn khi gán, một lần nữa chỉ vô tình đúng với số chính phương. Ý "result = power(9, 0.5);" sai vì thư viện chuẩn không có hàm nào tên là power, hàm luỹ thừa tên là pow; thêm nữa biến result ở đó còn chưa được khai báo kiểu.
Mở trang câu hỏi này →
A3
B2
C2.5
D2.6
Lời giải
Đáp án đúng: "3". Hàm ceil trong math.h làm tròn lên: nó trả về số nguyên nhỏ nhất không bé hơn đối số, nên với 2.55 kết quả là 3, dù phần thập phân có nhỏ tới đâu cũng vẫn bị kéo lên số nguyên kế tiếp. Cần nhớ kiểu trả về vẫn là double nên giá trị thực chất là 3.0, muốn in ra dạng số nguyên thì phải chuyển kiểu hoặc chọn đặc tả thích hợp. Ý "2" sai vì đó là kết quả của floor, phép làm tròn xuống, hoặc của việc cắt phần thập phân khi ép sang int. Ý "2.5" sai vì ceil không làm tròn tới nửa đơn vị, nó luôn đưa về một số nguyên. Ý "2.6" sai vì đó là làm tròn tới một chữ số thập phân, việc mà ceil không bao giờ làm.
Mở trang câu hỏi này →
14What 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 →
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 →
Ascanf will expect two integers inputted by user and write them to variables a and b.
Bscanf will expect two floating-point numbers inputted by user and write them to variables a and b.
Cscanf will expect two integers inputted by user separated by a comma, and write the first integer to variable a, the comma to variable b.
Dscanf will expect two integers inputted by user separated by a comma, and write the first integer to variable a, the second integer to variable b.
Lời giải
Đáp án đúng: "scanf will expect two integers inputted by user separated by a comma, and write the first integer to variable a, the second integer to variable b.". Trong chuỗi định dạng của scanf, mỗi đặc tả %d đọc một số nguyên rồi ghi qua địa chỉ đi kèm, còn ký tự thường như dấu phẩy là đòi hỏi phải khớp đúng ký tự ấy trong dòng nhập; không gặp dấu phẩy thì scanf dừng ngay tại đó và biến thứ hai không nhận được gì. Vậy mô tả đúng phải nêu cả dấu phẩy phân cách lẫn thứ tự ghi vào a trước rồi b sau. Cách nói "scanf will expect two integers inputted by user and write them to variables a and b" bỏ mất ràng buộc dấu phẩy, khiến người đọc tưởng cứ cách nhau bằng khoảng trắng là đọc được. Cách nói "two floating-point numbers" sai đặc tả: số thực phải dùng %f cùng con trỏ float, đưa %d cho số thực là hành vi không xác định. Cách nói "the comma to variable b" sai bản chất: ký tự khớp được tiêu thụ rồi bỏ đi, scanf không lưu nó vào biến nào.
Mở trang câu hỏi này →
AAssign value to n
BPrint n
CRead an integer input
DDeclare n
Lời giải
Đáp án đúng: "Read an integer input". Lời gọi này đọc một số nguyên từ dòng nhập chuẩn: đặc tả %d bỏ qua khoảng trắng dẫn đầu, gom các chữ số thành một số nguyên, rồi ghi số đó vào ô nhớ mà toán tử lấy địa chỉ đã chỉ ra, bởi scanf phải có địa chỉ mới ghi được ra ngoài phạm vi của chính nó. Mô tả "Assign value to n" bỏ mất phần quan trọng nhất là nguồn dữ liệu: giá trị không do chương trình ấn định mà do người dùng nhập, và việc ghi xảy ra qua con trỏ chứ không bằng toán tử gán. Mô tả "Print n" nói ngược chiều dữ liệu, đưa nội dung ra màn hình là việc của printf hoặc puts. Mô tả "Declare n" sai loại câu lệnh: khai báo là dòng nêu tên và kiểu của biến, phải có trước lời gọi này, còn scanf chỉ dùng biến đã tồn tại.
Mở trang câu hỏi này →
Amath.h
Bstdlib.h
Ctime.h
Dctype.h
Lời giải
Đáp án đúng: "math.h". Các hàm toán học như sqrt, pow, sin, cos, fabs, floor cùng những hằng liên quan được khai báo trong math.h, nên muốn gọi chúng phải nạp tệp tiêu đề này; thiếu nó thì trình dịch không biết hàm trả về double và dễ sinh kết quả sai, trên một số hệ còn phải nối thêm thư viện toán khi liên kết. Lựa chọn "stdlib.h" chứa tiện ích chung như malloc, free, atoi, rand và exit, không chứa hàm lượng giác hay căn bậc hai. Lựa chọn "time.h" lo thời gian và ngày tháng với time, clock, localtime. Lựa chọn "ctype.h" lo phân loại ký tự và đổi hoa thường với isdigit, isalpha, toupper, nó không làm tính toán số học.
Mở trang câu hỏi này →
Afflush()
Bclearbuffer()
Cclear input()
Dclrscr()
Lời giải
Đáp án đúng: "fflush()". Trong bốn tên được nêu chỉ fflush là hàm thật của thư viện chuẩn, khai báo trong stdio.h, dùng để đẩy sạch vùng đệm của một dòng vào ra; thói quen quen thuộc khi dạy nhập liệu là gọi nó để bỏ phần còn sót trong vùng đệm bàn phím sau scanf, chẳng hạn ký tự xuống dòng còn lại làm getchar kế tiếp nhận sai. Cần nói rõ: chuẩn chỉ định nghĩa fflush cho dòng xuất, dùng nó cho dòng nhập là hành vi không xác định dù nhiều trình dịch vẫn làm đúng ý người viết. Lựa chọn "clearbuffer()" không tồn tại trong thư viện chuẩn. Lựa chọn "clear input()" thậm chí không phải một tên hợp lệ vì có khoảng trắng ở giữa. Lựa chọn "clrscr()" thuộc conio.h phi chuẩn và nhiệm vụ của nó là xoá màn hình, không dính gì tới vùng đệm bàn phím.
Mở trang câu hỏi này →
Arand(time(0));
Bsrand(time(NULL));
Csrand();
Drandomize();
Lời giải
Đáp án đúng: "srand(time(NULL));". Hàm rand sinh dãy giả ngẫu nhiên hoàn toàn xác định từ một hạt giống; không gieo hạt thì chương trình coi như hạt bằng 1 và mỗi lần chạy lại cho đúng dãy cũ. Gọi srand với time(NULL), tức số giây tính từ mốc thời gian hệ thống, làm hạt đổi theo từng lần chạy nên dãy số cũng đổi. Chỉ nên gieo một lần ở đầu chương trình, gieo lại trong vòng lặp sẽ phản tác dụng vì trong cùng một giây hạt không đổi. Lựa chọn "rand(time(0));" sai vì rand không nhận đối số, nhiệm vụ gieo hạt thuộc srand. Lựa chọn "srand();" thiếu đối số bắt buộc nên không dịch được, và nếu bỏ hẳn lời gọi thì lại rơi vào hạt mặc định. Lựa chọn "randomize();" là hàm riêng của Borland, không có trong thư viện chuẩn nên mã dùng nó không dịch được ở nơi khác.
Mở trang câu hỏi này →