Nội dung chính
1. Kích thước đối tượng
Như bạn đã học trong bài 4.0 – Giới thiệu về các kiểu dữ liệu cơ bản, bộ nhớ trên các máy hiện đại thường được tổ chức thành các đơn vị có kích thước byte, với mỗi byte bộ nhớ có một địa chỉ duy nhất. Cho đến thời điểm này, thật hữu ích khi nghĩ về bộ nhớ như một bó các khối hoặc hộp thư nơi chúng ta có thể đặt và truy xuất thông tin, và các biến có tên để truy cập vào các khối hoặc hộp thư đó.
Tuy nhiên, sự tương tự này không hoàn toàn chính xác về một khía cạnh – hầu hết các đối tượng thực sự chiếm hơn 1 byte bộ nhớ. Một đối tượng có thể sử dụng 2, 4, 8 hoặc thậm chí nhiều địa chỉ bộ nhớ liên tiếp. Dung lượng bộ nhớ mà đối tượng sử dụng dựa trên kiểu dữ liệu của nó.
Vì chúng ta thường truy cập bộ nhớ thông qua tên biến (và không trực tiếp qua địa chỉ bộ nhớ), trình biên dịch có thể ẩn chi tiết về số lượng byte mà một đối tượng đã dùng. Khi chúng ta truy cập một số biến x, trình biên dịch sẽ biết có bao nhiêu byte dữ liệu cần truy xuất (dựa trên loại biến x) và có thể xử lý tác vụ đó cho chúng ta.
Thậm chí, có một số lý do rất hữu ích để biết đối tượng sử dụng bao nhiêu bộ nhớ.
Đầu tiên, một đối tượng sử dụng càng nhiều bộ nhớ thì càng có nhiều thông tin.
Một bit đơn có thể chứa 2 giá trị có thể là 0 hoặc 1:
bit 0 |
---|
0 |
1 |
2 bit có thể chứa 4 giá trị:
bit 0 | bit 1 |
---|---|
0 | 0 |
0 | 1 |
1 | 0 |
1 | 1 |
3 bit có thể chứa 8 giá trị:
bit 0 | bit 1 | bit 2 |
---|---|---|
0 | 0 | 0 |
0 | 0 | 1 |
0 | 1 | 0 |
0 | 1 | 1 |
1 | 0 | 0 |
1 | 0 | 1 |
1 | 1 | 0 |
1 | 1 | 1 |
Để khái quát hóa, một đối tượng có n bit (trong đó n là số nguyên) có thể chứa 2n (2 với mũ của n, cũng thường được viết 2 ^ n) các giá trị duy nhất. Do đó, với byte 8 bit, một đối tượng có kích thước byte có thể chứa 28 (256) giá trị khác nhau. Một đối tượng sử dụng 2 byte có thể chứa các giá trị khác nhau 2 ^ 16 (65536)!
Do đó, kích thước của đối tượng đặt giới hạn về số lượng giá trị duy nhất mà nó có thể lưu trữ – các đối tượng sử dụng nhiều byte hơn có thể lưu trữ số lượng lớn hơn các giá trị duy nhất. Chúng ta sẽ khám phá điều này nhiều hơn nữa khi chúng ta nói nhiều hơn về số nguyên.
Thứ hai, máy tính có một lượng bộ nhớ trống hữu hạn. Mỗi khi chúng ta định nghĩa một đối tượng thì một phần nhỏ của bộ nhớ trống sẽ được sử dụng cho đối tượng đó. Bởi vì máy tính hiện đại có rất nhiều bộ nhớ nên việc phát bộ nhớ này thường không đáng kể. Tuy nhiên, đối với các chương trình cần một lượng lớn đối tượng hoặc dữ liệu (ví dụ: một trò chơi đang hiển thị hàng triệu đa giác), thì đó là một vấn đề khác. Sự khác biệt giữa việc sử dụng các đối tượng 1 byte và 8 byte có thể là tạo ra sự khác biệt rất lớn.
Các lập trình viên mới thường tập trung quá nhiều vào việc tối ưu hóa code của họ để sử dụng ít bộ nhớ nhất có thể. Trong hầu hết các trường hợp, điều này không tạo ra một sự khác biệt không đáng kể. Thay vào đó chúng ta tập trung vào viết thói quen viết code tốt, sạch và chỉ tối ưu hóa thì thiết thực hơn
2. Kích thước của kiểu dữ liệu cơ bản
Câu hỏi tiếp là kích thước của kiểu dữ liệu dữ liệu cơ bản như thế nào? Bạn có thể ngạc nhiên khi thấy rằng kích thước của một kiểu dữ liệu nhất định phụ thuộc vào trình biên dịch và / hoặc kiến trúc máy tính!
C ++ chỉ đảm bảo rằng mỗi kiểu dữ liệu cơ bản sẽ có kích thước tối thiểu:
Category | Type | Minimum Size | Note |
---|---|---|---|
boolean | bool | 1 byte | |
character | char | 1 byte | Always exactly 1 byte |
wchar_t | 1 byte | ||
char16_t | 2 bytes | C++11 type | |
char32_t | 4 bytes | C++11 type | |
integer | short | 2 bytes | |
int | 2 bytes | ||
long | 4 bytes | ||
long long | 8 bytes | C99/C++11 type | |
floating point | float | 4 bytes | |
double | 8 bytes | ||
long double | 8 bytes |
Tuy nhiên, kích thước thực tế của các biến có thể khác nhau trên máy của bạn (đặc biệt là int, thường là 4 byte).
3. Toán tử sizeof
Để xác định kích thước của các kiểu dữ liệu trên một máy cụ thể, C ++ cung cấp một toán tử có tên sizeof. Toán tử sizeof là toán tử đơn nguyên lấy một kiểu hoặc một biến và trả về kích thước của nó theo byte. Bạn có thể biên dịch và chạy chương trình sau để tìm hiểu mức độ lớn của một số kiểu dữ liệu của bạn:
#include <iostream>
int main()
{
std::cout << "bool:\t\t" << sizeof(bool) << " bytes\n";
std::cout << "char:\t\t" << sizeof(char) << " bytes\n";
std::cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes\n";
std::cout << "char16_t:\t" << sizeof(char16_t) << " bytes\n"; // C++11 only
std::cout << "char32_t:\t" << sizeof(char32_t) << " bytes\n"; // C++11 only
std::cout << "short:\t\t" << sizeof(short) << " bytes\n";
std::cout << "int:\t\t" << sizeof(int) << " bytes\n";
std::cout << "long:\t\t" << sizeof(long) << " bytes\n";
std::cout << "long long:\t" << sizeof(long long) << " bytes\n"; // C++11 only
std::cout << "float:\t\t" << sizeof(float) << " bytes\n";
std::cout << "double:\t\t" << sizeof(double) << " bytes\n";
std::cout << "long double:\t" << sizeof(long double) << " bytes\n";
return 0;
}
Đây là đầu ra từ máy x64, sử dụng Visual Studio:
bool: 1 bytes
char: 1 bytes
wchar_t: 2 bytes
char16_t: 2 bytes
char32_t: 4 bytes
short: 2 bytes
int: 4 bytes
long: 4 bytes
long long: 8 bytes
float: 4 bytes
double: 8 bytes
long double: 8 bytes
Kết quả của bạn có thể thay đổi nếu bạn đang sử dụng một loại máy khác hoặc trình biên dịch khác. Lưu ý rằng bạn không thể sử dụng toán tử sizeof trên kiểu void, vì nó không có kích thước (làm như vậy sẽ gây ra lỗi biên dịch).
Bạn cũng có thể sử dụng toán tử sizeof trên một tên biến:
#include <iostream>
int main()
{
int x{};
std::cout << "x is " << sizeof(x) << " bytes\n";
return 0;
}
x is 4 bytes
4. Hiệu suất của kiểu dữ liệu cơ bản
Trên các máy hiện đại, Hiệu xuất của các kiểu dữ liệu cơ bản là nhanh, do đó hiệu suất trong khi sử dụng các kiểu này thường không phải là một mối quan tâm.
Bạn có thể cho rằng các kiểu dữ liệu sử dụng ít bộ nhớ sẽ nhanh hơn các kiểu sử dụng nhiều bộ nhớ hơn. Điều nay không phải lúc nào cũng đúng. CPU thường được tối ưu hóa để xử lý dữ liệu có kích thước nhất định (ví dụ: 32 bit) và các loại phù hợp với kích thước đó có thể được xử lý nhanh hơn. Trên một máy như vậy, int 32 bit có thể nhanh hơn so với 16 bit ngắn hoặc char 8 bit.
[…] định là bao nhiêu đó, chứ không phải là chúng sẽ có kích thước cụ thể. Xem bài – Kích thước đối tượng và toán tử sizeof để biết thông tin về cách xác định độ lớn của từng kiểu dữ liệu trên […]
Bình luận bị đóng.