Tôi đã đọc cuốn sách của K & R trên C và thấy rằng số học con trỏ trong C cho phép truy cập vào một phần tử ngoài phần cuối của mảng. Tôi biết C cho phép làm hầu như bất cứ điều gì với bộ nhớ nhưng tôi chỉ không hiểu, mục đích của đặc thù này là gì?C - phần tử nằm ngoài phần đầu của một mảng
Trả lời
C không cho phép truy cập vào bộ nhớ ngoài phần cuối của mảng. Tuy nhiên, nó cho phép một con trỏ trỏ tới một phần tử nằm ngoài phần cuối của mảng. Sự khác biệt là quan trọng.
Như vậy, đây là OK:
char array[N];
char *p;
char *end;
for (p = array, end = array + N; p < end; ++p)
do_something(p);
(Làm *end
sẽ là một lỗi.)
Và đó cho thấy lý do tại sao tính năng này rất hữu ích: a trỏ trỏ vào (không tồn tại) phần tử sau khi kết thúc mảng là hữu ích để so sánh, chẳng hạn như trong vòng lặp.
Về mặt kỹ thuật, đó là mọi thứ mà chuẩn C cho phép. Tuy nhiên, trong thực tế, việc triển khai C (trình biên dịch và thời gian chạy) không kiểm tra xem bạn có truy cập vào bộ nhớ ngoài phần cuối của mảng hay không, cho dù đó là một phần tử hay nhiều hơn. Sẽ phải kiểm tra giới hạn và điều đó sẽ làm chậm quá trình thực thi chương trình. Các loại chương trình C là phù hợp nhất cho (hệ thống lập trình, thư viện đa năng) có xu hướng hưởng lợi nhiều hơn từ tốc độ hơn so với kiểm tra giới hạn an ninh và an toàn sẽ cung cấp.
Điều đó có nghĩa C có lẽ không phải là công cụ tốt cho lập trình ứng dụng có mục đích chung.
Thông thường, nó rất hữu ích để biểu thị "kết thúc" vị trí, đó là một trong quá khứ phân bổ thực tế, vì vậy bạn có thể viết mã như:
char * end = begin + size;
for (char * curr = begin; curr < /* or != */ end ; ++curr) {
/* do something in the loop */
}
Tiêu chuẩn C một cách rõ ràng nói rằng yếu tố này là một hợp lệ địa chỉ bộ nhớ, nhưng dereferencing nó vẫn sẽ không được một ý tưởng tốt.
Tại sao nó có bảo lãnh này? Giả sử bạn có một máy có bộ nhớ 2^16 byte, địa chỉ 0000-FFFF, con trỏ 16 bit. Giả sử bạn đã tạo một mảng 16 byte. Bộ nhớ có thể được cấp phát tại FFF0 không?
Có 16 byte miễn phí liên tục kế nhau, nhưng:
begin + size == FFF0 + 10 (16 in hex) == 10000
mà kết thúc tốt đẹp đến 0000 vì kích thước con trỏ. Bây giờ điều kiện vòng lặp:
curr < end == FFF0 < 0000 == false
Thay vì lặp qua mảng, vòng lặp sẽ không làm gì cả. Điều này sẽ phá vỡ rất nhiều mã, vì vậy tiêu chuẩn C nói rằng phân bổ không được phép.
bạn có thể đi xa hơn 1 quá khứ mảng cho example`
int main()
{
char *string = "string";
int i = 0;
for(i=0; i< 10;i++)
{
printf("%c\n", string[i]);
}
return 0;
}
sẽ in rác sau khi kết thúc của chuỗi văn bản, bất cứ điều gì đang ngồi trong bộ nhớ trước khi tay.
Nó có thể in rác, định dạng ổ đĩa cứng của bạn, hoặc gây ra quỷ để bay ra khỏi mũi của bạn; đó là bản chất của hành vi không xác định. – aib
Vâng, chỉ cần đọc từ vị trí bộ nhớ là không thể định dạng ổ đĩa cứng của bạn hoặc gây ra quỷ để bay ra khỏi mũi của bạn. Viết cho nó, tuy nhiên ... –
Ngay cả khi đọc một con trỏ xấu có thể khiến chương trình của bạn bị lỗi trong tương lai. Xem http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx – Eclipse
- 1. C - số phần tử trong một mảng?
- 2. xoá phần tử đầu tiên khỏi mảng
- 3. Thêm các phần tử của một mảng
- 4. Thêm phần tử vào phần tử cuối cùng của mảng
- 5. Nhận tất cả các phần tử, nhưng phần tử đầu tiên từ một mảng
- 6. C++ Xóa một phần của mảng động
- 7. đăng ký lần nhấp vào một phần tử nằm trong một phần tử khác
- 8. Kiểm tra xem mọi phần tử trong một mảng có nằm trong mảng thứ hai không
- 9. Phần tử trống trong mảng C#
- 10. Kiểm tra xem mỗi phần tử trong một mảng có nhiều mảng nằm trong một mảng khác
- 11. C: tìm số phần tử trong một mảng []
- 12. Thuật toán Javascript để tìm các phần tử trong mảng không nằm trong mảng khác
- 13. Cách thay thế các phần tử trong mảng bằng các phần tử của mảng khác
- 14. PHP: Di chuyển phần tử kết hợp thành phần bắt đầu của mảng
- 15. C# Mảng chứa một phần
- 16. Python: tìm phần tử trong một mảng
- 17. Remove phần tử từ mảng
- 18. mảng Một phần tử trong struct
- 19. làm cho các phần tử của một mảng rỗng
- 20. Xóa phần tử của một mảng thông thường
- 21. Chu kỳ thông qua các phần tử của một mảng
- 22. Lấy 5 phần tử cuối cùng của một mảng php
- 23. Lấy phần tử cuối cùng của một mảng trong CoffeeScript
- 24. Thêm phần tử vào đầu phần tử nhóm
- 25. Đưa phần tử đầu tiên ra khỏi mảng
- 26. phần tử mảng Đi qua bởi ref
- 27. Xóa phần tử kết hợp đầu tiên khỏi mảng
- 28. đèo tham chiếu đến phần tử trong C# Mảng
- 29. Tạo một mảng chỉ tới một phần của mảng khác?
- 30. Trong một mảng javascript, làm cách nào để có được 5 phần tử cuối cùng, trừ phần tử đầu tiên?
Xem thêm câu hỏi này: http://stackoverflow.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by- các –