Chuyển đổi kiểu ngầm định
Chuyển đổi kiểu xảy ra tự động nếu một kiểu được sử dụng tại một thời điểm nào đó trong mã nguồn, nhưng một kiểu khác được mong đợi và có các quy tắc chuyển đổi giữa chúng. Chuyển đổi như vậy được gọi là chuyển đổi kiểu ngầm định và có thể không phải lúc nào cũng tương ứng với ý định của lập trình viên. Ngoài ra, một số hoạt động chuyển đổi có tác dụng phụ và trình biên dịch, không biết liệu việc sử dụng chúng có cố ý hay không, sẽ làm nổi bật các dòng mã tương ứng bằng các cảnh báo. Để giải quyết các vấn đề này, có một cú pháp chuyển đổi kiểu rõ ràng (xem Explicit type casting).
Chúng ta đã thấy một số quy tắc chuyển đổi kiểu ngầm định khi nghiên cứu kiểu và biến.
Cụ thể, nếu một giá trị có kiểu khác boolean
được gán cho một biến bool
, thì giá trị 0
được coi là false
và tất cả các giá trị còn lại là true
. Trong trường hợp tổng quát hơn, tất cả các biểu thức giả định sự hiện diện của các điều kiện logic đều được chuyển đổi thành kiểu bool
. Ví dụ, toán hạng đầu tiên của toán tử điều kiện ba ngôi luôn được chuyển đổi thành bool
.
Nhưng nếu giá trị kiểu bool được gán cho kiểu số thì true
sẽ trở thành 1
và false
sẽ trở thành 0
.
Khi một số thực được gán cho một biến kiểu số nguyên, phần phân số sẽ bị loại bỏ (trình biên dịch sẽ đưa ra cảnh báo). Mặt khác, khi một số nguyên được gán cho một biến kiểu số thực, độ chính xác có thể bị mất (trình biên dịch cũng đưa ra cảnh báo). Chúng ta đã nói về điều này trong các phần về Số nguyên và Số thực.
Nếu chúng ta có số nguyên và số dấu phẩy động, mọi thứ sẽ được chuyển đổi thành số dấu phẩy động có kích thước tối đa được sử dụng (thường là double
, trừ khi bạn chỉ định rõ ràng là float
hoặc số nguyên có hậu tố f
, ví dụ 1234.56789f
).
Đối với các số nguyên có kích thước khác nhau, cũng có các quy tắc chuyển đổi: chúng sẽ mở rộng nếu cần, nghĩa là chúng tăng lên kích thước của kiểu số nguyên lớn nhất được sử dụng trong biểu thức (xem Chuyển đổi kiểu số học).
Ngoài các biểu thức, chúng ta thường cần chuyển đổi ngầm các kiểu trong quá trình khởi tạo và gán, khi các kiểu bên phải và bên trái dấu =
không khớp. Các quy tắc chuyển đổi tương tự được áp dụng khi truyền giá trị qua các tham số hàm và trả về kết quả từ các hàm (để biết thêm chi tiết, vui lòng xem phần Hàm).
Xem xét những điều trên, một số lượng lớn các chuyển đổi có thể được thực hiện trong một dòng mã. Nếu điều này gây ra cảnh báo cho trình biên dịch, bạn nên đảm bảo rằng việc chuyển đổi là cố ý và loại bỏ các cảnh báo bằng cách chèn một chuyển đổi kiểu rõ ràng.
short s = 10;
long n = 10;
int p = s * n + 1.0;
2
3
Trong ví dụ này, khi thực hiện phép nhân, kiểu của biến s
được mở rộng thành kiểu của toán hạng thứ hai long
và thu được kết quả trung gian kiểu long
. Vì hằng số 1.0
có kiểu double
, nên kết quả của tích được chuyển đổi thành double
trước khi cộng. Kết quả chung cũng có kiểu double
; tuy nhiên, biến p
có kiểu int
và do đó thực hiện chuyển đổi ngầm định từ double
sang int
.
Các kiểu đặc biệt datetime
và color
được xử lý theo quy tắc của số nguyên có độ dài lần lượt là 8
và 4
byte. Nhưng đối với date và time, có giới hạn chặt chẽ hơn về giá trị tối đa - 32535244799
, tương ứng với D'3000.12.31 23:59:59'
.
Hầu hết các kiểu có thể được chuyển đổi ngầm sang và từ chuỗi, nhưng kết quả không phải lúc nào cũng đầy đủ, do đó trình biên dịch đưa ra cảnh báo "chuyển đổi ngầm từ 'số' sang 'chuỗi'" và "chuyển đổi ngầm từ 'chuỗi' sang 'số'" để lập trình viên có thể kiểm tra chúng. Ví dụ, chuyển đổi chuỗi thành số nguyên cho phép chuỗi chỉ chứa các chữ số và ký tự +
/-
ở đầu. Chuyển đổi từ chuỗi thành số thực cho phép, ngoài các số, sự hiện diện của dấu chấm .
và ký hiệu với "số mũ" (e
hoặc E
, ví dụ +1.2345e-1
). Nếu gặp một ký tự không được hỗ trợ (ví dụ: một chữ cái) trong chuỗi, phần còn lại của chuỗi sẽ bị loại bỏ hoàn toàn.
Ví dụ, chuỗi ngày và giờ ("2021.12.12 00:00"
) không thể được gán mà không có tổn thất cho một biến kiểu datetime
vì datetime
là một số nguyên (số giây). Trong trường hợp này, việc đọc số từ chuỗi sẽ kết thúc khi đạt đến điểm đầu tiên, tức là số sẽ nhận được giá trị 2021
. Số giây này tương ứng với phút thứ 34 của năm 1970.
Có những hàm đặc biệt cho những chuyển đổi như vậy (xem phần Chuyển đổi dữ liệu).
Hướng duy nhất của chuyển đổi kiểu ngầm định và rõ ràng bị cấm là từ chuỗi sang bool
. Trong những trường hợp như vậy, trình biên dịch hiển thị thông báo lỗi "không thể chuyển đổi ngầm định kiểu 'chuỗi' sang 'bool'".
Các ví dụ từ chương này được cung cấp trong TypeConversion.mq5
.