CodeGym /Các khóa học /C# SELF /Địa chỉ bộ nhớ và biến

Địa chỉ bộ nhớ và biến

C# SELF
Mức độ , Bài học
Có sẵn

1. Cấu trúc bộ nhớ

Mỗi máy tính đều có bộ nhớ truy cập ngẫu nhiên (RAM). Vậy nó là gì, có đặc điểm gì và quan trọng nhất là, nó giúp ích gì cho tụi mình?

Mỗi chương trình (kể cả chương trình viết bằng C#) trước khi chạy đều được nạp vào RAM. Trong RAM sẽ có mã chương trình (được CPU thực thi) và dữ liệu chương trình (do chính chương trình đưa vào bộ nhớ).

Vậy RAM là gì và nó giống cái gì nhỉ?

Hãy tưởng tượng bạn đang dùng Excel 😎 Một sheet trong Excel gồm các ô, mỗi ô có số hiệu duy nhất (A1, A2, ... B1, B2). Biết số hiệu ô là bạn có thể ghi giá trị vào đó hoặc lấy giá trị ra. Bộ nhớ máy tính cũng hoạt động kiểu kiểu vậy.

memory-excel

Chương trình và dữ liệu của nó khi chạy sẽ được lưu trong bộ nhớ. Toàn bộ bộ nhớ máy tính được chia thành các ô nhỏ – byte. Mỗi ô có số hiệu riêng – 0, 1, 2, 3, ...; (đánh số bắt đầu từ 0). Biết số hiệu ô, bạn có thể lưu dữ liệu vào đó hoặc lấy ra. Một số ô chứa mã chương trình – tập lệnh cho CPU, số khác chứa dữ liệu của chương trình. Số hiệu ô còn gọi là địa chỉ ô nhớ.

CPU có thể thực thi lệnh từ chương trình đã nạp vào bộ nhớ. Gần như mọi lệnh của CPU đều kiểu như: lấy dữ liệu từ một số ôlàm gì đó với chúng → kết quả lưu vào các ô khác.

Kết hợp hàng trăm lệnh đơn giản, ta có được các lệnh phức tạp và hữu ích.

Khi bạn khai báo biến trong code, nó sẽ được cấp một phần bộ nhớ chưa dùng. Thường là vài byte. Khi khai báo biến, bạn phải chỉ rõ kiểu dữ liệu mà chương trình sẽ lưu: số, text, hay gì khác. Nếu không biết kiểu thì không biết phải cấp bao nhiêu byte cho biến đó.

Ngày xưa, chương trình chỉ làm việc với số hiệu ô nhớ, nhưng sau này để tiện cho lập trình viên, người ta đặt tên cho các ô. Tên biến duy nhất – chủ yếu là để lập trình viên dễ nhớ thôi, chứ chương trình chạy thì chỉ cần số hiệu là đủ rồi.

2. Biến trong bộ nhớ

Trong C# có 4 kiểu dữ liệu cơ bản để lưu số nguyên: byte, short, intlong.

Kiểu Kích thước, byte Nguồn gốc tên
byte 1 Byte, vì chiếm đúng 1 byte bộ nhớ
short 2 Viết tắt của Short Integer
int 4 Viết tắt của Integer
long 8 Viết tắt của Long Integer

Ngoài ra trong C# còn có 2 kiểu số thực — floatdouble:

Kiểu Kích thước, byte Nguồn gốc tên
float 4 Viết tắt của Floating Point Number
double 8 Viết tắt của Double Float

Mỗi lần chương trình chạy đến lệnh tạo biến, nó sẽ cấp một vùng bộ nhớ nhỏ (kích thước tùy kiểu biến).

int a = 10;
Khai báo biến a kiểu int và cấp bộ nhớ cho nó
Quan trọng!

Địa chỉ của biến chính là địa chỉ ô đầu tiên trong vùng bộ nhớ được cấp cho nó.

Chương trình C# không được phép truy cập trực tiếp vào bộ nhớ. Mọi thao tác với bộ nhớ đều bị kiểm soát chặt chẽ bởi C#.NET.

3. Kiểu string trong bộ nhớ

Kiểu string có thể lưu trữ lượng dữ liệu lớn, nên nó không chỉ là kiểu dữ liệu đơn giản mà là một object thực thụ.

Bản thân dữ liệu kiểu string (text) sẽ được lưu trong một object đặc biệt, được cấp bộ nhớ riêng, còn địa chỉ của object đó sẽ được lưu trong biến, biến này cũng được cấp bộ nhớ.

  • Biến a kiểu int chiếm 4 byte và lưu giá trị 1.
  • Biến b kiểu int chiếm 4 byte và lưu giá trị 10,555. Dấu phẩy này không phải phần thập phân mà là để phân tách hàng. Phần thập phân thì dùng dấu chấm.
  • Biến d kiểu double chiếm 8 byte và lưu giá trị 13.001.
  • Biến str kiểu string chiếm 4 byte và lưu giá trị D12 — địa chỉ ô đầu tiên của object chứa text.

Object kiểu string (chứa text) được lưu ở một vùng bộ nhớ riêng. Địa chỉ ô đầu tiên của nó được lưu trong biến str.

4. Chuyện gì xảy ra khi gán giá trị

Một điều quan trọng nữa — gán giá trị hoạt động thế nào. Ví dụ:

int a = 10;
int b = a;
b = 20;
Console.WriteLine(a); // 10

Trong ví dụ này, bộ nhớ sẽ có hai ô: một cho a, một cho b. Khi bạn viết b = a;, giá trị (10) được copy, chứ không phải cái "hộp" đó. Thay đổi b không ảnh hưởng gì đến a.

Bây giờ thử với string:

string s1 = "Hello";
string s2 = s1;
s2 = s2 + " World";
Console.WriteLine(s1); // "Hello"
Console.WriteLine(s2); // "Hello World"

Ở đây cả hai biến s1s2 trỏ đến cùng một chuỗi "Hello" cho đến khi có thay đổi. Nhưng khi bạn thực hiện s2 = s2 + " World", một chuỗi mới "Hello World" được tạo cho s2, còn s1 vẫn trỏ về chuỗi cũ "Hello".

5. Tại sao lập trình lại đếm từ số 0

Nhiều người hay thắc mắc tại sao trong lập trình hầu như mọi thứ đều đếm từ 0. Thật ra có rất nhiều trường hợp đếm từ 0 tiện hơn (dù cũng có lúc đếm từ 1 lại tiện).

Trường hợp đơn giản nhất là địa chỉ bộ nhớ. Nếu biến của bạn được cấp 4 byte và bạn có X – địa chỉ byte đầu tiên, thì các byte còn lại sẽ có địa chỉ là gì? X+0, X+1, X+2, X+3. Vậy là ta có nhóm byte với chỉ số 0, 1, 2, 3.

Khi bạn nghĩ về địa chỉ tương đối trong một block dữ liệu, bạn luôn nhận được đánh số từ 0. Đó là lý do đầu tiên và phổ biến nhất cho việc đếm từ 0.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION