2013-05-14 31 views
5

§6.5.8\6 (liên quan>, <, < =,> =)từ ngữ lạ trong tiêu chuẩn, liên quan đến so sánh các con trỏ

Nếu các điểm biểu P để một phần tử của một đối tượng mảng và các điểm Q biểu đối với phần tử cuối cùng của cùng một đối tượng mảng, biểu thức con trỏ Q + 1 so sánh lớn hơn P. Trong tất cả các trường hợp khác, hành vi không xác định.

Một số phần ở trên, §6.5.8, được giải thích về cơ bản, số học con trỏ hoạt động như mong đợi trên các mảng. Đó là int a[3]; int *p = a; int *q = &a[2]; //q-p == 3 hợp lệ. Tuy nhiên, như tôi đã đọc ở trên q > p là UB.

Tôi đang thiếu gì?

+6

Bạn đang bỏ lỡ câu trước đó: "con trỏ trỏ tới phần tử mảng có giá trị chỉ số lớn hơn so với con trỏ tới các phần tử của cùng mảng với chỉ số dưới".Những gì bạn đã trích dẫn là một ngoại lệ cho phép các phạm vi nửa mở như ['a',' a + 3'). – dyp

+0

@DyP, Ồ, tốt. Tôi phải đọc thêm 5 lần nữa để hiểu nó. Một câu hỏi ngớ ngẩn khác hình thành phía tôi: ( – Vorac

+1

Đó là tiêu chuẩn, một số người cho rằng đó là tiêu chuẩn cho công thức khó khăn và không trực quan;) – dyp

Trả lời

1

Thứ nhất, bạn đã trích dẫn một phần của một đoạn, phần đầu tiên giải thích điều này là tham khảo, tôi bao gồm các đoạn ở đây:

Khi hai con trỏ được so sánh, kết quả phụ thuộc vào vị trí tương đối trong không gian địa chỉ của các đối tượng được trỏ tới. Nếu hai con trỏ tới các loại đối tượng vừa trỏ tới đối tượng cùng một, hoặc cả hai điểm qua phần tử cuối cùng của cùng một đối tượng mảng, thì chúng sẽ là số so sánh bằng nhau. Nếu các đối tượng được trỏ đến là các thành viên của cùng một đối tượng tổng hợp, thì con trỏ đến các thành viên cấu trúc được khai báo sau đó so sánh lớn hơn con trỏ cho các thành viên được khai báo trước đó trong cấu trúc và trỏ đến phần tử mảng có chỉ số lớn hơn cùng một mảng với các giá trị subscript thấp hơn. Tất cả các con trỏ tới các thành viên của cùng một đối tượng công đoàn đều giống nhau. Nếu biểu thức P trỏ đến phần tử của đối tượng mảng và biểu thức Q trỏ tới phần tử cuối cùng của cùng một đối tượng mảng, biểu thức con trỏ Q + 1 so sánh lớn hơn P. Trong tất cả các trường hợp khác, hành vi không xác định.

Về cơ bản, các bit bạn đã tham khảo đề cập đến thực tế là bình thường một con trỏ phải luôn điểm hoặc để một mình đối tượng đứng, để một phần tử của một mảng của các đối tượng hoặc một quá khứ cuối của một mảng đối tượng. Như bạn có thể thấy, thường tăng một con trỏ đã trỏ đến phần tử cuối cùng của một mảng sẽ mang lại một con trỏ không hợp lệ, và con trỏ này trong tiêu chuẩn không bao giờ bị bỏ qua, tuy nhiên nó có thể được sử dụng cho một trường hợp đặc biệt. có thể được đặt hoặc so sánh với một con trỏ khác.

Điều này rất hữu ích trong một chương trình mà trong đó bạn tăng một con trỏ, sau đó kiểm tra xem nó có nằm trong phần cuối của mảng và chấm dứt nếu nó không. Ví dụ.

int foo = 0; 
int ArrSize = 6; 
int bar[ArrSize]; 
while(foo < ArrSize) 
{ 
    foo++; 
    printf("%d", bar + 3 < bar + foo); 
} 

Sẽ hợp pháp, ngay cả trong trường hợp cuối cùng mà điểm foo vượt quá điểm kết thúc của mảng.

Lưu ý ví dụ này rất giả tạo nhưng thể hiện quan điểm.

Nếu không cho quy tắc này, chương trình này sẽ là hành vi không xác định.

+0

Lần lặp cuối cùng gây ra hành vi không xác định trong mã mẫu của bạn. 'bar + 7' làm cho UB theo phần về' + 'có nghĩa là gì đối với con trỏ cộng với số nguyên. –

+0

@MattMcNabb Argh, bạn nói đúng, tôi đã sử dụng toán tử sai, có nghĩa là sử dụng <. Tôi thực sự đã trộn hai thứ đó lên hàng trăm lần, tôi đã nghĩ sau gần 15 năm C tôi đã tránh được sai lầm ngớ ngẩn đó. Tuy nhiên, cảm ơn cho bình luận, tôi nghĩ rằng nó cố định ngay bây giờ. – Vality

+1

@MattMcNabb Tôi đã nhận ra rằng không có ngoại lệ đối với Q + 2, lỗi mà tôi đã tạo và luôn tạo ra vấn đề đó là độ dài của mảng! = Chỉ mục của phần tử cuối cùng. Tôi luôn luôn đếm từ 1 và không phải số không :( – Vality

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