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

Câu hỏi: PRF192 - Phần 8: Chuỗi ký tự

29 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/29 câuCòn 9
AUses array indexing
BUses pointer arithmetic
CRequires memory allocation
DWorks without checking for buffer overflow
Lời giải
Đáp án đúng gồm hai ý: "Uses array indexing" và "Uses pointer arithmetic". Chép chuỗi bằng tay nghĩa là tự viết vòng lặp chuyển từng ký tự của s1 sang s2 cho tới khi gặp ký tự rỗng kết thúc, rồi đặt ký tự rỗng cho s2; vòng lặp đó có đúng hai cách cài đặt tương đương trong C, hoặc truy cập theo chỉ số kiểu s2[i] = s1[i], hoặc dịch con trỏ kiểu *d++ = *s++, bởi phép lấy chỉ số trong C vốn được định nghĩa qua số học con trỏ. Cần công bố khuyết điểm của đề: câu ghi rõ chọn hai nhưng bản khoá in kèm chỉ tô được một ô. "Requires memory allocation" sai vì s2 là mảng đã có sẵn chỗ từ lúc khai báo, vòng lặp chỉ ghi vào chỗ đó, không gọi malloc. "Works without checking for buffer overflow" nói đúng về sự kiện nhưng đó là khuyết điểm phải tránh của cách làm, không phải cách chép chuỗi; nếu s1 dài hơn s2 thì chương trình ghi tràn và hỏng bộ nhớ.
Mở trang câu hỏi này →
Đề bài
#include <stdio.h>
#include <string.h>
int main() {
    char s[1000];
    int i, count = 0;
    printf("Enter a sentence: ");
    fgets(s, sizeof(s), stdin);
    for (i = 0; s[i] != '\0'; i++) {
        if (condition???) {
            count++;
        }
    }
    printf("Total words: %d\n", count);
    return 0;
}
As[i] != ' '
Bs[i] != '\n'
Cs[i] != ' ' && (i == 0 || s[i-1] == ' ')
Ds[i] == ' ' && s[i-1] == ' '
Lời giải
Đáp án đúng: "s[i] != ' ' && (i == 0 || s[i-1] == ' ')". Đếm từ thực chất là đếm số lần một từ bắt đầu, nên điều kiện phải nhận ra hai việc cùng lúc: ký tự hiện tại không phải khoảng trắng, và chỗ ngay trước nó là ranh giới, tức đang ở đầu chuỗi hoặc ký tự liền trước là khoảng trắng. Nhánh i == 0 đặt trước phép đọc s[i-1] nên nhờ tính rút mạch của toán tử hoặc, chương trình không bao giờ đọc ra ngoài mảng. "s[i] != ' '" sai vì nó cộng một lần cho mỗi ký tự khác khoảng trắng, một từ năm chữ sẽ bị đếm thành năm từ. "s[i] != '\n'" sai nặng hơn, nó so với ký tự xuống dòng nên đếm gần như mọi ký tự, kể cả khoảng trắng. "s[i] == ' ' && s[i-1] == ' '" sai vì nó đếm các cặp khoảng trắng liền nhau, lại còn đọc s[-1] khi i bằng 0, tức truy cập ngoài vùng mảng.
Mở trang câu hỏi này →
Achar arr[] = "Hello";
Bchar arr[] = ['H', 'e', 'l', 'l', 'o','/e'];
CChar[] arr = "Hello";
DChar[] arr = {'H', 'e', 'l', 'l', 'o','/0'};
Lời giải
Đáp án đúng: "char arr[] = "Hello";". Hằng chuỗi trong dấu nháy kép đã mang sẵn ký tự rỗng kết thúc, nên khai báo này tạo mảng sáu phần tử gồm năm chữ và một ký tự kết thúc, kích thước do trình biên dịch tự đếm vì cặp ngoặc vuông để trống. "char arr[] = ['H', 'e', 'l', 'l', 'o','/e'];" sai hai chỗ: danh sách khởi tạo phải nằm trong ngoặc nhọn chứ không phải ngoặc vuông, và ký tự kết thúc viết bằng dấu chéo ngược với số 0, không phải dấu chéo xuôi với chữ e. "Char[] arr = "Hello";" sai vì C phân biệt chữ hoa chữ thường nên không có kiểu tên Char, lại đặt cặp ngoặc vuông sai chỗ, trong C nó đi sau tên biến. "Char[] arr = {'H', 'e', 'l', 'l', 'o','/0'};" mắc đúng hai lỗi vừa nêu, thêm nữa dấu chéo xuôi với 0 chỉ là hai ký tự thường, không phải ký tự rỗng.
Mở trang câu hỏi này →
Astrcat()
Bstrcomb()
Cstrmerge()
Dstrconnect()
Lời giải
Đáp án đúng: "strcat()". Thư viện chuỗi của C khai báo strcat trong string.h: nó tìm ký tự kết thúc của chuỗi đích, ghi tiếp chuỗi nguồn từ đúng chỗ đó rồi đặt lại ký tự kết thúc, nên người dùng phải tự bảo đảm mảng đích còn đủ chỗ cho cả phần cộng thêm và một byte kết thúc. Ý "strcomb()" sai vì không có hàm nào tên như vậy trong thư viện chuẩn, gọi nó sẽ gây lỗi lúc liên kết. Ý "strmerge()" sai vì đó cũng là một cái tên tự nghĩ ra, chuẩn C không định nghĩa. Ý "strconnect()" sai vì nó cũng không tồn tại; cần nhớ rằng tên các hàm chuỗi trong C đều rất ngắn và cố định, như strcpy để sao chép, strlen để đo độ dài, strcmp để so sánh và strcat để nối.
Mở trang câu hỏi này →
ATrue
B1
C0
D-1
Lời giải
Đáp án đúng: "0". Hàm strcmp so sánh hai chuỗi theo từng cặp ký tự dựa trên mã của chúng và trả về một số nguyên thể hiện quan hệ thứ tự: âm khi chuỗi thứ nhất bé hơn, dương khi lớn hơn, và đúng 0 khi hai chuỗi trùng nhau tới ký tự kết thúc. Vì thế phép thử hai chuỗi giống nhau phải viết là strcmp bằng 0, một cách diễn đạt thoạt nghe trái trực giác. Ý "True" sai vì strcmp trả về int, trong C không có giá trị nào mang tên như vậy; hơn nữa đem kết quả dùng trực tiếp làm điều kiện thì hai chuỗi bằng nhau lại bị coi là sai. Ý "1" sai vì giá trị dương chỉ xuất hiện khi chuỗi thứ nhất lớn hơn, và chuẩn cũng không hứa đúng con số 1. Ý "-1" sai vì giá trị âm ứng với trường hợp chuỗi thứ nhất bé hơn, chuẩn chỉ hứa dấu chứ không hứa độ lớn.
Mở trang câu hỏi này →
A'\0'
B'\n'
C'\t'
D'\'
Lời giải
Đáp án đúng: "'\0'". Chuỗi trong C không mang theo độ dài, nó chỉ là một dãy ký tự nằm liên tục và kết thúc bằng một byte giá trị 0; mọi hàm như strlen, strcpy hay printf với đặc tả %s đều dò tới byte đó để biết chỗ dừng. Đây là lý do mảng chứa chuỗi phải khai báo thừa một ô so với số ký tự thật. Ý "'\n'" sai vì đó là ký tự xuống dòng, nó chỉ là một ký tự nội dung bình thường có thể nằm giữa chuỗi. Ý "'\t'" sai vì đó là ký tự tab, cũng là nội dung chứ không phải dấu kết thúc. Ý "'\'" sai vì cách viết này còn không hợp lệ: dấu gạch chéo ngược mở đầu một chuỗi thoát nên muốn biểu diễn chính nó phải viết gấp đôi.
Mở trang câu hỏi này →
Đề bài
char words[4][11];
strcpy(words[0], "apple");
strcat(words[0], "juice");
printf("%s\n", words[0]);
Aapplejuice
Bapple
Cjuice
Djuiceapple
Lời giải
Đáp án đúng: "applejuice". Khai báo words là mảng hai chiều gồm 4 hàng, mỗi hàng là một mảng 11 ký tự, nên words[0] dùng được như một chuỗi. Hàm strcpy đặt apple cùng ký tự kết thúc vào đầu hàng đó; sau đó strcat tìm tới ký tự kết thúc ấy và ghi tiếp juice từ đúng chỗ đó, rồi đặt lại ký tự kết thúc. Kết quả là một chuỗi mười ký tự, cộng byte kết thúc là vừa đủ 11 ô của hàng. Ý "apple" sai vì nó bỏ qua tác dụng của strcat. Ý "juice" sai vì strcat nối thêm vào phía sau, nó không ghi đè từ đầu hàng; muốn thay hẳn nội dung thì phải gọi strcpy lần nữa. Ý "juiceapple" sai vì trật tự nối luôn là chuỗi đích trước rồi chuỗi nguồn sau, đối số thứ nhất là nơi nhận và nó giữ nguyên phần đầu của mình.
Mở trang câu hỏi này →
Aif (strcmp(s1, s2) >= 0)
Bif (strcmp(s1, s2) < 0)
Cif (strlen(s1) >= strlen(s2))
Dif (s1 >= s2)
Lời giải
Đáp án đúng: "if (strcmp(s1, s2) >= 0)". Thứ tự giữa hai chuỗi trong C do strcmp quyết định: hàm này so từng cặp ký tự theo mã, dừng ở chỗ đầu tiên khác nhau và trả về số dương khi chuỗi thứ nhất lớn hơn, số âm khi bé hơn, 0 khi trùng nhau; vậy điều kiện lớn hơn hoặc bằng tương ứng với kết quả không âm. Ý "if (strcmp(s1, s2) < 0)" sai vì nó thử điều ngược lại, chuỗi thứ nhất bé hơn. Ý "if (strlen(s1) >= strlen(s2))" sai vì nó chỉ đo độ dài, trong khi thứ tự từ điển phụ thuộc nội dung từng ký tự; một chuỗi dài hơn vẫn có thể bé hơn. Ý "if (s1 >= s2)" sai vì tên mảng chuỗi được chuyển thành địa chỉ phần tử đầu, nên phép so sánh đó đối chiếu hai địa chỉ trong bộ nhớ, không liên quan gì tới nội dung.
Mở trang câu hỏi này →
Acopy strings
Bcontcatenate (joins) two strings
Ccompare two strings
Lời giải
Đáp án đúng: "copy strings". Hàm strcpy trong string.h nhận con trỏ đích rồi con trỏ nguồn, sao chép lần lượt từng byte của chuỗi nguồn sang vùng nhớ đích và chép luôn ký tự kết thúc chuỗi, nên sau lệnh gọi thì vùng đích mang đúng nội dung của chuỗi nguồn; chính cái tên cpy đã là viết tắt của copy. Cách hiểu "contcatenate (joins) two strings" mô tả việc nối hai chuỗi, đó là việc của strcat: hàm đó đi tìm ký tự kết thúc của chuỗi đích rồi ghi tiếp chuỗi nguồn từ chỗ ấy, giữ lại nội dung cũ, khác hẳn kiểu ghi đè từ byte đầu tiên của strcpy. Cách hiểu "compare two strings" mô tả việc so sánh, đó là việc của strcmp: hàm này không ghi gì vào bộ nhớ mà chỉ trả về số nguyên âm, bằng không hay dương theo thứ tự từ điển. Bản chất phải nhớ là C không có kiểu chuỗi thật, strcpy chỉ chép byte nên vùng đích phải tự đủ chỗ cho cả ký tự kết thúc.
Mở trang câu hỏi này →
A1
B0
C-1
Lời giải
Đáp án đúng: "-1". Hàm strcmp so sánh hai chuỗi theo từng byte cho tới vị trí đầu tiên khác nhau rồi trả về dấu của hiệu hai mã ký tự tại vị trí đó. Hai chuỗi abcdef và abdc trùng nhau ở hai ký tự đầu, đến vị trí thứ ba thì một bên là c có mã 99, bên kia là d có mã 100, hiệu là số âm nên hàm trả về giá trị âm, và trong danh sách chỉ có đúng một số âm. Giá trị "1" ứng với trường hợp chuỗi thứ nhất lớn hơn theo thứ tự từ điển, tức ký tự khác nhau đầu tiên của nó phải có mã lớn hơn, điều không xảy ra ở đây. Giá trị "0" chỉ xuất hiện khi hai chuỗi giống nhau hoàn toàn kể cả độ dài, còn abcdef và abdc đã lệch ngay ký tự thứ ba nên hàm dừng tại đó mà không cần xét phần còn lại. Bản chất cần nhớ: chuẩn C chỉ bảo đảm dấu của kết quả, trị tuyệt đối do thư viện quyết định, nên luôn đọc kết quả theo dấu.
Mở trang câu hỏi này →
Astrcat()
Bstrcpy()
Cputs()
Dscanf()
Lời giải
Đáp án đúng: "strcpy()". Trong C, phép gán không chép được nội dung mảng ký tự, nên muốn nhân bản một chuỗi phải tự chạy vòng lặp hoặc gọi hàm chuyên dụng; strcpy đi từ byte đầu của chuỗi nguồn, ghi sang vùng đích cho tới khi chép xong ký tự kết thúc chuỗi, nhờ đó vùng đích trở thành một chuỗi hợp lệ. Hàm "strcat()" cũng ghi vào đích nhưng là nối thêm: nó bỏ qua phần nội dung cũ, bắt đầu ghi đúng tại ký tự kết thúc của đích, nên không thay thế được việc chép. Hàm "puts()" chỉ đẩy một chuỗi ra màn hình kèm ký tự xuống dòng, không tạo bản sao nào trong bộ nhớ. Hàm "scanf()" là hàm đọc dữ liệu có định dạng, nguồn của nó là dòng nhập từ bàn phím chứ không phải một chuỗi đã có trong chương trình, nên nó không làm việc nhân bản nội dung giữa hai vùng nhớ.
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 →
A9
B10
C8
DIt depends on the contents of the array
Lời giải
Đáp án đúng: "9". Chỉ số mảng trong C đếm từ 0, nên mảng khai với kích thước 10 có các ô mang chỉ số từ 0 tới 9 và ô cuối cùng là 9; đây là hệ quả trực tiếp của cách ngôn ngữ tính địa chỉ, vì ô thứ k nằm cách đầu mảng đúng k lần kích thước một phần tử. Giá trị "10" là số phần tử chứ không phải chỉ số cuối; chạm vào ô mang chỉ số 10 là đọc ghi ra ngoài mảng, lỗi mà trình biên dịch không chặn giúp. Giá trị "8" là chỉ số của ký tự cuối khi mảng đang chứa một chuỗi dùng hết chỗ, vì khi đó ô cuối phải để dành cho ký tự kết thúc, nhưng câu hỏi hỏi chỉ số lớn nhất của mảng chứ không hỏi chuỗi. Mô tả "It depends on the contents of the array" không đúng: kích thước mảng cố định ngay từ lúc khai báo nên dải chỉ số không phụ thuộc nội dung đang chứa.
Mở trang câu hỏi này →
ACompare two s1 strings and s2 string
BCopy s2 string to s1 string
CCopy s1 string to s2 string
DConcatenate string s2 to the end of s1
EFind the address of a substring
Lời giải
Đáp án đúng: "Copy s2 string to s1 string". Thứ tự tham số của nhóm hàm chuỗi trong C luôn là đích trước, nguồn sau, cùng chiều với phép gán; vì vậy lời gọi strcpy(s1, s2) chép nội dung của s2 sang vùng nhớ s1, ghi đè từ byte đầu tiên và chép cả ký tự kết thúc. Mô tả "Compare two s1 strings and s2 string" là việc của strcmp, hàm đó chỉ đọc hai chuỗi rồi trả về một số nguyên theo thứ tự từ điển, không ghi vào đâu cả. Mô tả "Copy s1 string to s2 string" đảo chiều, hiểu như thế thì dữ liệu đi sai hướng và vùng lẽ ra phải được cập nhật vẫn nguyên như cũ. Mô tả "Concatenate string s2 to the end of s1" là việc của strcat, hàm đó giữ nội dung cũ của s1 và ghi tiếp từ ký tự kết thúc. Mô tả "Find the address of a substring" là việc của strstr, hàm trả về con trỏ tới chỗ tìm thấy hoặc con trỏ rỗng.
Mở trang câu hỏi này →
A13
B14
C15
D16
Lời giải
Đáp án đúng: "15". Chuỗi trong C không mang theo độ dài, thư viện nhận ra chỗ hết chuỗi nhờ một ký tự có mã 0 đặt ngay sau ký tự cuối, và ký tự đó cũng chiếm trọn một ô của mảng. Mảng khai 16 ô nên nhiều nhất 15 ô dành cho nội dung, ô còn lại để dành cho dấu kết thúc. Giá trị "16" là tổng số ô; dùng hết cho nội dung thì không còn chỗ cho dấu kết thúc, và các hàm như strlen hay printf sẽ đọc tràn sang bộ nhớ bên cạnh. Giá trị "14" trừ đi hai ô, tức đếm thừa một dấu kết thúc, trong khi chuẩn chỉ đòi đúng một ô cho dấu đó. Giá trị "13" trừ ba ô, không khớp với cách tính nào của ngôn ngữ. Chính quy ước này là lý do các hàm như strncpy hay snprintf luôn phải tính thêm một byte cho dấu kết thúc.
Mở trang câu hỏi này →
A1
B0
C-1
D32
Lời giải
Đáp án đúng: "0". Ký tự kết thúc chuỗi, viết trong mã nguồn bằng một dấu thoát đi kèm chữ số 0, có mã số đúng bằng 0 trong bảng mã; nhờ giá trị này mà vòng lặp duyệt chuỗi viết được theo kiểu chạy cho tới khi gặp giá trị sai, vì 0 là giá trị sai duy nhất của một byte. Giá trị "1" là mã của một ký tự điều khiển khác, không mang vai trò kết thúc chuỗi. Giá trị "-1" không phải mã ký tự hợp lệ của bảng mã bảy bit, con số âm này hay bị nhớ lẫn với hằng báo hết tệp mà các hàm đọc trả về. Giá trị "32" là mã của dấu cách, một ký tự hiển thị được và hoàn toàn hợp lệ giữa chuỗi, coi nó là dấu kết thúc thì mọi câu có khoảng trắng đều bị cắt ngắn. Cũng cần phân biệt ký tự mã 0 với chữ số 0, vì chữ số 0 có mã 48.
Mở trang câu hỏi này →
17What does this code do?4 lựa chọncó code
Đề bài
char names[10][31];
gets(names[0]);
ATakes a line of input into names[0]
BTakes input into all 10 strings
CFails to compile
DOnly stores 1 character
Lời giải
Đáp án đúng: "Takes a line of input into names[0]". Khai báo names là mảng hai chiều gồm 10 hàng, mỗi hàng 31 ô ký tự, nên names[0] là hàng đầu tiên và khi dùng trong biểu thức nó suy biến thành con trỏ tới ký tự đầu của hàng ấy. Hàm gets đọc một dòng từ dòng nhập chuẩn, bỏ ký tự xuống dòng rồi đặt dấu kết thúc chuỗi, nên nội dung người dùng nhập nằm trong hàng đầu. Mô tả "Takes input into all 10 strings" cần một vòng lặp gọi mười lần, còn một lời gọi chỉ ghi vào đúng hàng được truyền. Mô tả "Fails to compile" không đúng về cú pháp: dòng mã hợp lệ và kiểu đối số khớp, dù phải biết rằng gets đã bị loại khỏi chuẩn từ bản năm 2011 vì không chặn được tràn khi dòng nhập dài hơn 30 ký tự. Mô tả "Only stores 1 character" lẫn chỉ số hàng với số ký tự: số 0 là chỉ số hàng, còn mỗi hàng chứa được tới 30 ký tự cùng dấu kết thúc.
Mở trang câu hỏi này →
AThe null terminator in C strings
BA whitespace character
CA printable character
DA NULL pointer value
Lời giải
Đáp án đúng: "The null terminator in C strings". Chuỗi trong C là dãy ký tự nằm liền nhau và kết thúc bằng một byte giá trị 0; chính byte đó cho mọi hàm chuỗi biết chỗ dừng, thiếu nó thì strlen hay printf cứ đọc tiếp sang vùng nhớ bên cạnh. Mô tả "A whitespace character" sai: nhóm ký tự trắng gồm dấu cách, dấu tab, ký tự xuống dòng và vài ký tự nữa, còn hàm isspace trả về 0 cho byte giá trị 0. Mô tả "A printable character" cũng sai, byte này không in ra hình gì và không nằm trong dải ký tự hiển thị bắt đầu từ mã 32. Mô tả "A NULL pointer value" lẫn hai khái niệm khác hẳn nhau: đây là một ký tự giá trị 0 nằm trong mảng, còn con trỏ rỗng là giá trị của một biến con trỏ không trỏ vào đâu; hai thứ khác kiểu, khác kích thước và dùng ở hai chỗ khác nhau.
Mở trang câu hỏi này →
AConverts a string to an integer
BConverts an integer to a string
CCopy a string
DConverts a string to a number
Lời giải
Đáp án đúng: "Converts a string to an integer". Tên hàm atoi viết tắt cho cụm ASCII to integer: nó đọc chuỗi ký tự số, bỏ khoảng trắng đầu, nhận dấu rồi dựng ra một số nguyên. Cần công bố một khuyết điểm của đề: nguyên mẫu thật trong stdlib.h là int atoi(const char *str) chứ không phải void, vì nếu trả về void thì hàm không có cách nào đưa số nguyên ra cho nơi gọi. Lựa chọn "Converts an integer to a string" là chiều ngược lại, việc của sprintf. Lựa chọn "Copy a string" là việc của strcpy, không liên quan tới chuyển kiểu. Lựa chọn "Converts a string to a number" nghe gần đúng nhưng không nêu được kiểu đích: họ hàm này còn có atof cho số thực, còn atoi riêng ở chỗ cho ra số nguyên và cắt bỏ phần thập phân, nên cách diễn đạt chung chung ấy không phân biệt được hai hàm.
Mở trang câu hỏi này →
Đề bài
int a = 0;
char line1[] = "Hi";
char line2[] = "Hello";
a = strcmp(line1, line2);
A0
BA positive value
CA negative value
DNAN
Lời giải
Đáp án đúng: "A positive value". Hàm strcmp so từng cặp ký tự theo mã của chúng và trả về chênh lệch tại vị trí đầu tiên khác nhau. Hai chuỗi cùng mở đầu bằng một chữ hoa giống nhau, sang vị trí thứ hai thì chuỗi ngắn có ký tự i mã 105 còn chuỗi dài có ký tự e mã 101; vì 105 lớn hơn 101 nên hàm cho ra số dương, nghĩa là chuỗi thứ nhất đứng sau theo thứ tự từ điển. Chú ý việc so sánh dừng ngay tại cặp lệch đầu tiên, độ dài chuỗi không quyết định. Lựa chọn "0" chỉ đúng khi hai chuỗi giống nhau hoàn toàn tới ký tự kết thúc. Lựa chọn "A negative value" sẽ đúng nếu ký tự lệch đầu tiên của chuỗi thứ nhất nhỏ hơn, tức khi đổi thứ tự hai đối số. Lựa chọn "NAN" không có nghĩa ở đây vì strcmp trả về int, không phải số thực, nên không bao giờ sinh giá trị không phải số.
Mở trang câu hỏi này →