Toán tử sizeof
không đánh giá đối số của nó, chỉ looks at the type toán hạng của nó.
Giả sử bạn có một mảng a
với loại "mảng [N] loại T". Sau đó, trong hầu hết các trường hợp, loại tên a
là "con trỏ đến T" (T *
) và giá trị của con trỏ là địa chỉ của phần tử đầu tiên của mảng (&a[0]
). Tức là, tên của một mảng "phân rã" thành con trỏ đến phần tử đầu tiên của nó. Các "mục nát" không xảy ra trong các trường hợp sau đây:
- khi
a
được sử dụng với địa chỉ-of (&
) điều hành,
- trong việc khởi tạo
a
(nó là bất hợp pháp để gán cho mảng trong C) và
- khi
a
là toán hạng của toán tử sizeof
.
Vì vậy, sizeof a
cung cấp cho bạn N
lần sizeof(T)
.
Khi bạn làm sizeof(a-3)
, loại toán hạng thành sizeof
được xác định theo biểu thức a-3
. Kể từ a
trong a-3
được sử dụng trong một value context (tức là, không có ba ngữ cảnh nào ở trên), loại của nó là "con trỏ đến int" và tên a
phân rã thành con trỏ thành a[0]
. Như vậy, tính toán a-3
là hành vi không xác định, nhưng vì sizeof
không đánh giá đối số của nó, a-3
chỉ được sử dụng để xác định loại toán hạng, vì vậy mã là OK (xem liên kết đầu tiên ở trên để biết thêm).
Từ trên, sizeof(a-3)
tương đương với sizeof(int *)
, là 4 trên máy tính của bạn.
"Chuyển đổi" là do toán tử trừ. Bạn có thể thấy một tương tự, và có lẽ đáng ngạc nhiên hơn, cho kết quả với toán tử dấu phẩy:
printf("%zu\n", sizeof(1, a));
cũng sẽ in sizeof(int *)
, vì các nhà điều hành dấu phẩy dẫn đến a
làm quen trong một bối cảnh giá trị.
Nguồn
2010-02-05 15:23:29
Thực tế thứ hai in 'sizeof (int *)', không phải 'sizeof (int)'. 'sizeof (int *)' chỉ xảy ra là 4 trên nền tảng của bạn. – AnT
Ngoài ra, cách thích hợp để in một giá trị 'size_t' (giá trị được trả về bởi' sizeof') là với '"% zu "', giả sử trình biên dịch của bạn hỗ trợ tính năng C99 cụ thể đó. Nếu không, đặt cược tốt hơn sẽ là đưa nó vào một 'unsigned' hoặc' unsigned long'. –