Tại sao được sizeof
coi là toán tử mà không phải là hàm?
Thuộc tính nào là cần thiết để đủ điều kiện làm nhà điều hành?
Câu trả lời:
Bởi vì tiêu chuẩn C nói như vậy, và nó nhận được phiếu bầu duy nhất.
Do hậu quả:
sizeof (int)
, thay vì một biểu thức đối tượng.int a; printf("%d\n", sizeof a);
hoàn toàn ổn. Chúng thường được nhìn thấy, thứ nhất vì chúng cần thiết như một phần của biểu thức ép kiểu và thứ hai vì sizeof có mức độ ưu tiên rất cao, vì vậy sizeof a + b
không giống với sizeof (a+b)
. Nhưng chúng không phải là một phần của lệnh gọi sizeof, chúng là một phần của toán hạng.sizeof a++
không sửa đổi a).Một chức năng sẽ khác nhau về tất cả những điểm đó. Có thể có những khác biệt khác giữa hàm và toán tử một ngôi, nhưng tôi nghĩ điều đó đủ để cho thấy tại sao sizeof không thể là một hàm ngay cả khi có lý do để muốn nó như vậy.
sizeof
có tác dụng phụ nếu có VLA trong biểu thức.
(int)
không có gì là lạ mắt - chỉ là tên của một kiểu bên trong dấu ngoặc đơn. Dấu ngoặc đơn ở đây là một phần của cú pháp sizeof
- chúng được yêu cầu khi lấy kích thước của một kiểu, nhưng không bắt buộc khi lấy kích thước của một biểu thức. Xem ví dụ ở đây
sizeof
: sizeof unary-expression
và sizeof ( type-name )
- vì vậy trong tiêu chuẩn C11, nó không được coi là 'kiểu đúc' mà là một tên kiểu được đặt trong ngoặc đơn. Kết quả thực là giống nhau. (Để so sánh, một biểu thức diễn viên là ( type-name ) cast-expression
.) Và tôi ghét cách nhận xét đó Markdown hoạt động khác với Q&A Markdown!
Nó có thể được sử dụng như một hằng số thời gian biên dịch, điều này chỉ khả thi nếu nó là một toán tử hơn là một hàm. Ví dụ:
union foo {
int i;
char c[sizeof(int)];
};
Về mặt cú pháp, nếu nó không phải là một toán tử thì nó sẽ phải là một macro tiền xử lý vì các hàm không thể nhận kiểu làm đối số. Đó sẽ là một macro khó thực hiện vì sizeof
có thể lấy cả kiểu và biến làm đối số.
Bởi vì tiêu chuẩn C nói như vậy, và nó nhận được phiếu bầu duy nhất.
Và tiêu chuẩn có thể đúng vì sizeof
có một loại và
Nói chung, nếu miền hoặc miền đồng (hoặc cả hai) của một hàm chứa các phần tử phức tạp hơn đáng kể so với số thực, thì hàm đó được gọi là toán tử. Ngược lại, nếu cả miền và miền của một hàm đều không chứa các phần tử phức tạp hơn số thực, thì hàm đó có thể được gọi đơn giản là một hàm. Các hàm lượng giác như cosin là ví dụ của trường hợp sau.
Ngoài ra, khi các hàm được sử dụng thường xuyên đến mức chúng đã phát triển nhanh hơn hoặc dễ dàng hơn so với dạng F (x, y, z, ...) chung, các dạng đặc biệt thu được cũng được gọi là toán tử. Ví dụ bao gồm các toán tử tiền tố như phép cộng "+" và phép chia "/", và các toán tử hậu tố như giai thừa "!". Việc sử dụng này không liên quan đến sự phức tạp của các thực thể liên quan.
Bởi vì nó không phải là một chức năng. Bạn có thể sử dụng nó như vậy:
int a;
printf("%d\n", sizeof a);
Chức năng có điểm nhập, mã, v.v. Chức năng sẽ được chạy trong thời gian chạy (hoặc nội tuyến), kích thước của nó phải được xác định tại thời điểm biên dịch.
toán tử sizeof là thực thể thời gian biên dịch không phải thời gian chạy và không cần dấu ngoặc đơn như một hàm. Khi mã được biên dịch thì nó thay thế giá trị bằng kích thước của biến đó tại thời điểm biên dịch nhưng trong hàm sau khi hàm được thực thi thì chúng ta sẽ biết giá trị trả về.
Bởi vì:
sizeof
"hàm" sẽ không có cách nào xác định kích thướcCó một sự khác biệt nhỏ từ hàm - giá trị của sizeof được giải quyết trong thời gian biên dịch, nhưng không phải trong thời gian chạy!
Bởi vì nó là một toán tử thời gian biên dịch , để tính toán kích thước của một đối tượng, yêu cầu thông tin kiểu chỉ có sẵn tại thời gian biên dịch. Điều này không phù hợp với C ++.
Sizeof (), tôi nghĩ rõ ràng nó vừa là một hàm vừa là một toán tử. Tại sao? Bởi vì một hàm giữ dấu ngoặc đơn cho mục nhập ở giai đoạn nhập. Nhưng chủ yếu cũng là một toán tử nguyên nhân các toán tử là ký tự hành động, do đó sizeof là một câu lệnh hành động hoạt động trên toán hạng trong dấu ngoặc đơn.