2009-03-22 28 views

Trả lời

55

sizeof(array) được thực hiện hoàn toàn bởi trình biên dịch C. Vào thời điểm chương trình được liên kết, những gì trông giống như một cuộc gọi sizeof() cho bạn đã được chuyển đổi thành một hằng số.

Ví dụ: khi bạn biên dịch mã C này:

#include <stdlib.h> 
#include <stdio.h> 
int main(int argc, char** argv) { 
    int a[33]; 
    printf("%d\n", sizeof(a)); 
} 

bạn nhận được

.file "sz.c" 
    .section  .rodata 
.LC0: 
    .string "%d\n" 
    .text 
.globl main 
    .type main, @function 
main: 
    leal 4(%esp), %ecx 
    andl $-16, %esp 
    pushl -4(%ecx) 
    pushl %ebp 
    movl %esp, %ebp 
    pushl %ecx 
    subl $164, %esp 
    movl $132, 4(%esp) 
    movl $.LC0, (%esp) 
    call printf 
    addl $164, %esp 
    popl %ecx 
    popl %ebp 
    leal -4(%ecx), %esp 
    ret 
    .size main, .-main 
    .ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)" 
    .section  .note.GNU-stack,"",@progbits 

Các $132 ở giữa là kích thước của mảng, 132 = 4 * 33. Chú ý rằng có không có hướng dẫn call sizeof - không giống như printf, là một chức năng thực sự.

+1

lol! Điều đó sẽ dạy tôi không kiểm tra rằng tôi đặt tay mình vào đúng nơi ...Cảm ơn vì sửa chữa Rob –

+1

Ah, tôi thấy bây giờ, David phải là một người đánh máy mù chạm với một rối loạn chức năng xúc giác ở đầu ngón tay của mình :-) Hài hước như thế nào c và e là okay - Tôi đã phải kiểm tra xem mọi chữ cái khác là một bên trái của vị trí chính xác. – paxdiablo

+1

Tôi đoán bàn tay trái của tôi ở đúng vị trí nhưng tay phải của tôi đã bị dời đi một phím ở bên trái ... có vẻ như một sai lầm dễ gây ra - nếu bạn đang gõ câu trả lời trong khi xem TV ;-) –

7

sizeof() sẽ chỉ hoạt động cho một mảng kích thước cố định (có thể là tĩnh, xếp chồng dựa trên hoặc trong cấu trúc).

Nếu bạn áp dụng nó vào một mảng được tạo với malloc (hoặc mới trong C++), bạn sẽ luôn nhận được kích thước của một con trỏ.

Và có, điều này được dựa trên thông tin thời gian biên dịch.

+0

mảng kích thước cố định không nhất thiết phải dựa trên xếp chồng. C không có toán tử mới. – ysth

+0

Bạn nói đúng, tôi sẽ chỉnh sửa một chút. –

+3

Bạn đã quên khoảng C99 VLA - các mảng có độ dài thay đổi. –

2

sizeof (Mảng) được tra cứu tại thời gian biên dịch, không phải lúc chạy. Thông tin không được lưu trữ.

Bạn có thể quan tâm đến việc triển khai kiểm tra giới hạn không? Nếu vậy, có một số cách khác nhau để đi về điều đó.

5

sizeof cho biết kích thước của biến, không phải kích thước của đối tượng bạn trỏ đến (nếu có.) sizeof(arrayVar) sẽ trả về kích thước mảng theo byte nếu và chỉ khi arrayVar được khai báo trong phạm vi mảng và không phải là một con trỏ.

Ví dụ:

char myArray[10]; 
char* myPtr = myArray; 

printf("%d\n", sizeof(myArray)) // prints 10 
printf("%d\n", sizeof(myPtr)); // prints 4 (on a 32-bit machine) 
17

sizeof là thời gian biên dịch thuần túy trong C++ và C trước C99. Bắt đầu với C99 có biến mảng chiều dài:

// returns n + 3 
int f(int n) { 
    char v[n + 3]; 

    // not purely a compile time construct anymore 
    return sizeof v; 
} 

Điều đó sẽ đánh giá sizeof toán hạng, vì n vẫn chưa được biết tại thời gian biên dịch. Chỉ chỉ áp dụng cho các mảng độ dài thay đổi: Các toán hạng hoặc loại khác vẫn thực hiện tính toán sizeof tại thời gian biên dịch. Đặc biệt, các mảng có kích thước được biết đến tại thời gian biên dịch vẫn được xử lý như trong C++ và C89. Kết quả là, giá trị trả về bởi sizeof không phải là hằng số thời gian biên dịch (biểu thức liên tục) nữa. Bạn không thể sử dụng nó khi một giá trị như vậy được yêu cầu - ví dụ khi khởi tạo biến tĩnh, trừ khi phần mở rộng của trình biên dịch cụ thể cho phép nó (chuẩn C cho phép triển khai có phần mở rộng cho những gì nó xử lý như hằng số).

+4

Tốt bạn đề cập đến VLA C99. Tuy nhiên, câu trả lời của bạn nên nhấn mạnh rằng ngay cả trong C99, các mảng kích thước cố định có kích thước của chúng được tính toán tại thời gian biên dịch - nó chỉ là các VLA có kích thước của chúng được tính khi chạy. Và có thể, kết quả là bạn không thể luôn sử dụng 'sizeof (mảng)' làm hằng số trong C99. –

+0

ồ phải. không thấy sự mơ hồ đó trong câu trả lời của tôi. –

+0

ok, giờ ngủ cho tôi. sau đó tôi sẽ thức dậy và hét lên về tất cả những lỗi chính tả trong câu trả lời của tôi: p –

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