1. Hằng và biến là gì?
Trong lập trình, hằng (constant) dùng để lưu trữ dữ liệu mà giá trị của nó luôn không thay đổi trong suốt quá trình thực thi chương trình.
Biến (variable) cũng dùng để lưu trữ dữ liệu, nhưng giá trị của biến có thể thay đổi trong khi chương trình đang chạy.
2. Các ví dụ về hằng và biến
2.1. Ví dụ về hằng
Dưới đây là ví dụ về việc định nghĩa một hằng có tên SITE_DOMAIN:
Trong trường hợp này, bạn có thể sử dụng giá trị của TEMP_FOLDER nhưng không thể thay đổi nó.
Lưu ý:
Thêm vào đó, trong ngôn ngữ C, bạn có thể khai báo một hằng số bằng cách sử dụng macro như sau:
2.2. Ví dụ về biến
Dưới đây là ví dụ về việc khai báo một biến có tên là 'year', với kiểu dữ liệu là int:
Trong ví dụ này, giá trị của biến 'year' có thể thay đổi khi chương trình đang chạy, như đã được trình bày trước đó.
3. Kiểu dữ liệu của biến
Dữ liệu trong lập trình được phân loại thành nhiều kiểu khác nhau như kiểu số (bao gồm số nguyên), kiểu chuỗi (gồm các ký tự liên tiếp), và kiểu số thực (float). Trong một số ngôn ngữ lập trình như C, bạn cần phải chỉ định kiểu dữ liệu khi khai báo biến. Ví dụ, biến 'year' ở đây được khai báo với kiểu dữ liệu integer.
Khi khai báo kiểu dữ liệu cho biến, trình biên dịch của C sẽ biết lượng bộ nhớ RAM cần cấp phát để lưu trữ giá trị của biến đó. Ví dụ, kiểu dữ liệu số có thể cần từ 2 đến tối đa 4 byte bộ nhớ để lưu trữ.
Những ngôn ngữ yêu cầu khai báo kiểu dữ liệu cho biến khi khai báo được gọi là ngôn ngữ kiểu tĩnh hoặc static typing language.
Ngược lại, một số ngôn ngữ lập trình như PHP và Ruby không yêu cầu khai báo kiểu dữ liệu cho biến. Trình biên soạn interpreter sẽ tự động gán bộ nhớ cho biến dựa trên giá trị mà biến chứa:
Những ngôn ngữ cho phép không cần định nghĩa kiểu dữ liệu cho biến được gọi là ngôn ngữ kiểu động hoặc dynamic typing language.
4. Ngôn ngữ kiểu động
Một ngôn ngữ lập trình được coi là có kiểu gõ động, hay đơn giản là 'động', khi phần lớn các kiểm tra được thực hiện tại thời điểm chạy thay vì biên dịch. Trong kiểu gõ động, kiểu dữ liệu liên kết với giá trị chứ không phải với biến. Các ngôn ngữ gõ động bao gồm Groovy, JavaScript, Lisp, Lua, Objective-C (liên quan đến các kiểu do người dùng xác định nhưng không phải các kiểu tích hợp sẵn). So với gõ tĩnh, gõ động có thể linh hoạt hơn, ví dụ như cho phép chương trình tạo các loại và hàm dựa trên dữ liệu thời gian chạy, mặc dù có thể không đảm bảo chính xác như gõ tĩnh. Điều này là vì một ngôn ngữ gõ động có thể thực thi những chương trình mà chương trình kiểm tra kiểu tĩnh có thể coi là không hợp lệ.
Gõ động có thể dẫn đến lỗi loại trong thời gian chạy, khi một giá trị có thể có kiểu không mong muốn và thao tác không hợp lệ với kiểu đó được thực hiện. Những lỗi này có thể xảy ra rất lâu sau khi lỗi lập trình ban đầu, làm cho việc xác định lỗi trở nên khó khăn hơn.
Các ngôn ngữ gõ động thực hiện ít kiểm tra 'thời gian biên dịch' hơn so với các ngôn ngữ gõ tĩnh. Ví dụ, chúng có thể chỉ kiểm tra cú pháp của mã nguồn. Kiểm tra thời gian chạy có thể phức tạp hơn vì chúng dựa vào thông tin động và thông tin trong quá trình dịch. Ngược lại, kiểm tra thời gian chạy chỉ đảm bảo các điều kiện đúng trong một lần thực thi cụ thể của chương trình và phải được lặp lại cho mỗi lần thực hiện chương trình.
Phát triển phần mềm trong các ngôn ngữ gõ động thường được hỗ trợ bởi các thực tiễn lập trình như kiểm thử đơn vị. Kiểm thử là một phần quan trọng của phát triển phần mềm chuyên nghiệp và đặc biệt quan trọng trong các ngôn ngữ gõ động. Thực tế, kiểm thử có thể phát hiện lỗi rộng hơn nhiều so với kiểm tra kiểu tĩnh, nhưng lại không thể phát hiện tất cả các lỗi mà kiểm tra loại tĩnh có thể tìm thấy. Kiểm thử có thể được tích hợp vào quy trình xây dựng phần mềm, trong đó người dùng không phải thực hiện kiểm tra thủ công.
Ngược lại với kiểu gõ động là kiểu gõ tĩnh. Kiểu gõ này thực hiện kiểm tra trong thời gian biên dịch thay vì thời gian chạy. Trong gõ tĩnh, các kiểu dữ liệu liên kết với biến chứ không phải với giá trị. Các ngôn ngữ gõ tĩnh bao gồm Ada, C, C++, C#, Java,... (liên quan đến các phân biệt vô hướng, mảng, băm và chương trình con) và Scala. Gõ tĩnh là một hình thức xác minh chương trình hạn chế (xem loại an toàn), cho phép phát hiện lỗi kiểu sớm hơn trong chu kỳ phát triển. Trình kiểm tra loại tĩnh chỉ đánh giá thông tin kiểu có thể xác định tại thời điểm biên dịch, nhưng có thể đảm bảo các điều kiện kiểm tra giữ cho tất cả các lần thực thi của chương trình, giảm cần lặp lại kiểm tra mỗi khi chương trình được chạy. Thực hiện chương trình cũng có thể hiệu quả hơn (nhanh hơn và giảm bộ nhớ) bằng cách bỏ qua kiểm tra loại thời gian chạy và cho phép tối ưu hóa khác.
Vì trình kiểm tra loại tĩnh đánh giá thông tin kiểu trong quá trình biên dịch và không có thông tin kiểu chỉ có sẵn khi chạy, nó thường bị coi là bảo thủ. Nó có thể từ chối một số chương trình mà thực tế có thể hoạt động tốt trong thời gian chạy nhưng không thể xác định được một cách tĩnh. Ví dụ, nếu một biểu thức luôn đúng khi chạy, một chương trình chứa mã có thể bị từ chối khi nhập sai do không thể đảm bảo chắc chắn rằng nhánh khác sẽ không được thực hiện.
Trình kiểm tra kiểu tĩnh có tính bảo thủ và có thể phát hiện lỗi loại trong những đoạn mã hiếm khi được sử dụng. Nếu không có kiểm tra kiểu tĩnh, ngay cả khi mã được kiểm tra với độ bao phủ 100%, lỗi kiểu vẫn có thể không được phát hiện. Các kiểm tra phạm vi mã cần xem xét tất cả các vị trí nơi giá trị được tạo ra và nơi giá trị đó được sử dụng để phát hiện lỗi loại.
Nhiều ngôn ngữ gõ tĩnh phổ biến không phải là loại an toàn chính thức. Chúng có những 'lỗ hổng' trong đặc tả ngôn ngữ cho phép lập trình viên viết mã mà vượt qua các kiểm tra kiểu tĩnh, dẫn đến nhiều vấn đề.
Đây là bài viết của Mytour về hằng số và biến trong tin học. Hy vọng bài viết sẽ hữu ích cho bạn đọc. Cảm ơn bạn đã theo dõi!