2011-12-15 35 views
7

Đây là mã trong câu hỏiC Pointer Arithmetic sizeof (struct)

#include <stdio.h> 

struct test { 
    unsigned char t; 
    unsigned short u; 
    unsigned char v; 
}; 


int main() 
{ 
    struct test * a = (void *) 0x1000; 

    printf("%x %p %p\n", 
      sizeof(struct test), 
      a + sizeof(struct test), 
      a - sizeof(struct test)); 

    return 0; 
} 

Các sizeof (thử nghiệm struct) in 6, vì vậy tôi sẽ mong đợi để xem:

6 0xffa 0x1006

Thay vào đó, tôi nhận được

6 0x1024 0xfdc 

Thời gian qua tôi c hecked, 0x24, hoặc 36, không bằng 6. Nó thậm chí không liên kết với bất cứ điều gì mà tôi có thể nói. Tôi đang thua lỗ hoàn toàn.

Ai đó có thể giải thích cho tôi lý do tôi nhận được các giá trị này không?

Trả lời

16

Vấn đề là khi bạn làm số học con trỏ, nó sẽ tăng thêm nhiều kích thước của kiểu dữ liệu.

Vì vậy, những gì bạn đang thực hiện hiệu quả là thêm vào hình vuông sizeof(struct test).

Kể từ sizeof(struct test) = 6, bạn đang tăng địa chỉ theo 6 * 6 = 36. Do đó, tại sao bạn nhận được 0x10240xfdc thay vì 0x10060xffa. (Bạn cũng có chuyển sang các +-, nhưng đó là một điều nhỏ.)

Thay vào đó, chỉ cần làm điều này:

printf("%x %p %p\n", 
     sizeof(struct test), 
     a + 1, 
     a - 1); 
1

Bạn có một con trỏ đã nhập.

Vì vậy, khi bạn tăng nó 1 của tôi (tức là a + 1), nó có nghĩa là a + sizeof(type).

Vì vậy a + sizeof(type) = a + sizeof(type) * sizeof(type) = a + 6 * 6 (trong trường hợp của bạn như sizeof (thử nghiệm) = 6)

Đó là nơi mà bạn đang nhận được 0x24 hoặc 36 từ.

2

Tôi nghĩ rằng bạn đang tìm kiếm a + 1a - 1.

(a + x) giống nhau là &a[x].

+2

Bạn có thể muốn nói rằng '* (a + x)' giống với 'a [x]' hoặc '(a + x)' giống với '& a [x]'. –

4

Khi bạn làm số học con trỏ như thế này, bạn di chuyển về phía trước hoặc sau bởi số lượng phần tử đó, như thể biến đó nằm trong một mảng. Vì vậy, bạn thực sự muốn chỉ sử dụng a + 1a - 1, nên tăng 6 byte mỗi lần.

QUAN TRỌNG: Hãy nhớ rằng trình biên dịch có thể thêm phần đệm vào cấu trúc của bạn để giúp căn chỉnh. Đừng chỉ giả định rằng bởi vì bạn có hai ký tự một byte và một đoạn ngắn hai byte mà cấu trúc của bạn sẽ có kích thước 4 byte --- đây không phải là trường hợp ở đây. (Trên thực tế, đừng cho rằng bạn biết kích thước của char hoặc ngắn; tôi đã thấy các ký tự 2 byte trước đó).

+3

Thực ra điều đó không hoàn toàn chính xác.Nó _can't_ thêm phần đệm giữa các phần tử mảng. Những gì nó có thể làm là pad ở giữa các phần tử của một cấu trúc và sau phần tử cuối cùng của một cấu trúc (đây có thể là bit mà bạn đang đề cập đến). Nhưng bản thân cấu trúc được đệm thành kích thước chính xác nếu nó có yêu cầu căn chỉnh - sáu byte ở đây có thể là 'char (1), pad (1), short (2), char (1), pad (1)' nhưng rằng phần đệm cuối cùng thuộc về một phần tử cấu trúc đơn, nó không phải là các phần tử _between_ trong một mảng được tạo thành từ cấu trúc đó. Chế độ Nitpick tắt :-) – paxdiablo

+1

Cảm ơn, tôi đã viết lại phản hồi của mình sau khi xem lại thông số C99. –