2015-10-04 15 views
11

Trong C, trình biên dịch có con trỏ đến đầu chuỗi và có ký hiệu kết thúc ('\0'). Nếu người dùng muốn tính toán độ dài của chuỗi, trình biên dịch phải tính các phần tử của mảng chuỗi cho đến khi nó tìm thấy '\0'.Làm thế nào để các chuỗi nhìn từ quan điểm của trình biên dịch?

Trong UCSD-strings, trình biên dịch có độ dài của chuỗi trong ký hiệu đầu tiên.

Và trình biên dịch nghĩ gì về C#-strings? Có, từ quan điểm của người dùng String là một số object có trường Length, tôi không nói về nội dung cấp cao. Tôi muốn biết các thuật toán sâu; ví dụ: trình biên dịch tính toán độ dài của chuỗi như thế nào?

+4

Giả định C của bạn sai. Trình biên dịch C biết ** chính xác ** mỗi chuỗi là bao lâu. Để thấy điều này, hãy gọi 'sizeof' trên chuỗi (không phải trên _pointer đến_ chuỗi!). – MSalters

+1

Thông thường, tôi sẽ đóng tài khoản này làm bản dupe nhưng các bản sao bị lỗi. http://www.codeproject.com/Articles/3377/Strings-UNDOCUMENTED – usr

+0

@MSalters Bạn là những khái niệm khó hiểu. Mảng và chuỗi các thực thể khác nhau và chúng có các hoạt động khác nhau liên kết với chúng. Chúng có liên quan, nhưng chúng là những trừu tượng khác nhau và chúng không nên trộn lẫn. –

Trả lời

21

Hãy thực hiện đoạn mã sau:

string s = "123"; 
string s2 = "234"; 
string s3 = s + s2; 
string s4 = s2 + s3; 
Console.WriteLine(s + s2); 

Bây giờ chúng ta hãy đặt một breakpoint ở dòng cuối cùng và mở cửa sổ bộ nhớ:

Strings

Viết s3 trong cửa sổ bộ nhớ, chúng ta có thể thấy các đường 2 (s3s4) ing được phân bổ cái khác với 4 byte kích thước lúc đầu.

Ngoài ra, bạn có thể thấy rằng bộ nhớ khác được phân bổ như mã thông báo loại lớp strings và các dữ liệu lớp khác string.

Các string class chính nó chứa một thành viên private int m_stringLength; chứa chiều dài của string, điều này cũng làm cho string.Concat() thực hiện siêu nhanh (bằng cách phân bổ toàn bộ chiều dài ngay từ đầu):

int totalLength = str0.Length + str1.Length + str2.Length; 

String result = FastAllocateString(totalLength); 
FillStringChecked(result, 0, str0); 
FillStringChecked(result, str0.Length, str1); 
FillStringChecked(result, str0.Length + str1.Length, str2); 

Những gì tôi tìm thấy một chút lạ là việc triển khai IEnumerable<char>.Count() cho string được thực hiện bằng cách thực hiện mặc định có nghĩa là lặp lại từng mục một không giống như ICollection<T> s như List<T> trong đó IEnumerable<char>.Count() được thực hiện bằng cách lấy thuộc tính ICollection<T>.Count.

+2

@homk Nếu đó là điều bạn muốn biết, câu hỏi thực sự của bạn không liên quan gì đến 'từ quan điểm của trình biên dịch'. – EJP

6

Trong C# độ dài của chuỗi được lưu trữ trong đối tượng trong trường riêng tư ([NonSerialized]private int m_stringLength;), nó không phải được tính toán trong thời gian chạy.

The source code of String class is available online.

Các vấn đề liên quan