2013-01-05 34 views
23

Tôi đã cố gắng thực hiện điều hành sizeof .. Tôi đã làm theo cách này ..thực hiện điều hành sizeof

#define my_sizeof(x) ((&x + 1) - &x) 

Nhưng nó luôn luôn kết thúc trong việc đưa ra kết quả là '1' cho một trong các kiểu dữ liệu ..

tôi đã sau đó googled nó cho việc này .. và tôi tìm thấy mã typecasted

#define my_size(x) ((char *)(&x + 1) - (char *)&x) 

và mã đang làm việc nếu nó được typecasted .. tôi d ont hiểu tại sao .. Mã này cũng được đệm một cách hoàn hảo CƠ CẤU ..

Nó cũng đang làm việc cho

#define my_sizeof(x) (unsigned int)(&x + 1) - (unsigned int)(&x) 

bất cứ ai có thể vui lòng giải thích làm thế nào là nó làm việc nếu typecasted và nếu không typecasted?

Thanks in advance ..

+3

Truyền tới 'không dấu int' là một ý tưởng tồi. 'uintptr_t' là tốt hơn nhưng vẫn liên quan đến một chuyển đổi ẩn gây khó chịu nhưng không thể tránh khỏi. –

Trả lời

26

Kết quả của phép trừ con trỏ nằm trong các thành phần và không theo byte. Vì vậy, biểu thức đầu tiên đánh giá là 1 theo định nghĩa.

này sang một bên, bạn thực sự phải sử dụng dấu ngoặc trong macro:

#define my_sizeof(x) ((&x + 1) - &x) 
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x) 

Nếu không cố gắng sử dụng my_sizeof() trong một biểu thức có thể dẫn đến sai sót.

+0

tôi đã đặt dấu ngoặc đơn .. Nhưng nó cũng làm việc nếu tôi dint .. :) –

+12

Các macro là vô vọng như một phương tiện thay thế 'sizeof'. Họ đánh giá các đối số (hai lần quá) ... Hãy suy nghĩ của 'my_sizeof (x + +)'. – Mat

+0

@Mat: yes .. Tôi hiểu rồi .. :) –

5

Nhưng nó luôn luôn kết thúc trong việc đưa ra kết quả là '1' cho một trong các kiểu dữ liệu

Vâng, đó là cách thức hoạt động số học con trỏ. Nó hoạt động trong các đơn vị thuộc loại được chỉ đến. Vì vậy, hãy đúc tới char * đơn vị hoạt động của char, đó là những gì bạn muốn.

5

Toán tử sizeof là một phần của đặc tả ngôn ngữ C (và C++) và được triển khai bên trong trình biên dịch (front-end). Không có cách nào để thực hiện nó với các cấu trúc C khác (trừ khi bạn sử dụng các phần mở rộng GCC như typeof) vì nó có thể chấp nhận một trong hai kiểu hoặc biểu thức dưới dạng toán hạng, mà không gây ra bất kỳ tác dụng phụ nào (ví dụ: sizeof((i>1)?i:(1/i)) sẽ không sụp đổ khi i==0 nhưng macro của bạn my_sizeof sẽ sụp đổ với một bộ phận bằng không). Xem thêm C coding guidelineswikipedia.

Bạn nên hiểu C pointer arithmetic. Xem ví dụ this question. Sự khác biệt con trỏ được thể hiện trong các phần tử không phải là byte.

-2

# define my_sizeof (x) ((& x + 1) - & x)

& x cho địa chỉ của biến của bạn và incrementing nó với một (& x + 1), sẽ cung cấp địa chỉ, nơi một biến loại x khác có thể được lưu trữ. Bây giờ nếu chúng ta tính số học qua các địa chỉ này như ((& x + 1) - & x), thì nó sẽ cho biết trong ((& x + 1) - & x) phạm vi địa chỉ 1 biến loại x có thể được lưu trữ.

Bây giờ, nếu chúng ta đánh số lượng bộ nhớ đó bằng (char *) [vì kích thước của char là 1 byte và tăng một char * sẽ di chuyển chỉ với một byte], thì chúng ta sẽ nhận được số byte loại x là tiêu thụ

5
#define my_sizeof(x) ((char *)(&x + 1) - (char *)&x) 

my_sizeof() macro này sẽ không làm việc trong các trường hợp sau:

  1. sizeof 1 - 4 byte (đối với một nền tảng với 4-byte int)
    my_sizeof(1) - sẽ không biên dịch chút nào.

  2. sizeof (int) - 4 byte (đối với một nền tảng với 4-byte int)
    my_sizeof(int) - sẽ không biên dịch mã ở tất cả.

Nó sẽ chỉ hoạt động đối với các biến. Nó sẽ không hoạt động đối với các loại dữ liệu như int, float, char v.v., đối với các chữ như 2, 3.4, 'A', v.v., cũng như đối với các biểu thức rvalue như a+b hoặc foo().

+1

Điều này sẽ đưa ra một bình luận tuyệt vời, bởi vì nó không trả lời câu hỏi, nhưng nó là ["phê bình mang tính xây dựng để hướng dẫn tác giả trong việc cải thiện bài viết"] (http: // stackoverflow.com/help/privilege/comment) ... – Sebivor

+0

Làm thế nào để chúng tôi giải quyết nó? –

5
#define my_sizeof(x) ((&x + 1) - &x) 

&x cung cấp cho các địa chỉ của biến (cho phép nói đôi x) tuyên bố trong chương trình và incrementing nó với 1 cung cấp cho các địa chỉ mà biến tiếp theo của các loại x có thể được lưu trữ (ở đây addr_of(x) + 8, cho kích thước của một đôi là 8Byte).

Sự khác biệt cho kết quả là có bao nhiêu biến loại x có thể được lưu trữ trong số lượng bộ nhớ đó rõ ràng là 1 cho loại x (để tăng nó bằng 1 và lấy sự khác biệt là những gì chúng ta đã làm).

#define my_size(x) ((char *)(&x + 1) - (char *)&x) 

typecasting nó vào char* và lấy sự khác biệt sẽ cho chúng ta biết bao nhiêu biến kiểu char có thể được lưu trữ trong bộ nhớ không gian nhất định (sự khác biệt). Vì mỗi char chỉ yêu cầu 1 Byte bộ nhớ (số lượng bộ nhớ)/1 sẽ cung cấp số byte giữa hai vị trí bộ nhớ kế tiếp của loại biến được chuyển vào macro và do đó số lượng bộ nhớ mà biến loại x đòi hỏi.

Nhưng bạn sẽ không thể chuyển bất kỳ chữ nào cho macro này và biết kích thước của chúng.

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