2009-03-10 21 views

Trả lời

151

Nó không phải là ma thuật.

Hành vi của mã này trong C được mô tả trong phần 6.7.8.21 của đặc điểm kỹ thuật C (online draft of C spec): đối với các phần tử không có giá trị được chỉ định, trình biên dịch khởi tạo con trỏ tới NULL và số học loại bằng không (và đệ quy áp dụng điều này cho tập hợp).

Hành vi của mã này trong C++ được mô tả trong phần 8.5.1.7 của đặc tả C++ (online draft of C++ spec): trình biên dịch tổng hợp-khởi tạo các phần tử không có giá trị được chỉ định.

Ngoài ra, lưu ý rằng trong C++ (nhưng không phải C), bạn có thể sử dụng một danh sách initializer trống, làm cho trình biên dịch để tổng hợp-khởi tạo tất cả các yếu tố của mảng:

char array[100] = {}; 

Đối với những gì sắp xếp mã trình biên dịch có thể tạo ra khi bạn làm điều này, hãy nhìn vào câu hỏi này: Strange assembly from array 0-initialization

+0

Làm tất cả các trình biên dịch C làm điều này? Tôi đã dẫn đến tin rằng chỉ Visual Studio thực hiện điều này. – JFA

+1

bản nháp trực tuyến của C++ thông số kỹ thuật bị hỏng, ai cũng có liên kết mới? – bkarj

32

Thực hiện tùy thuộc vào nhà phát triển trình biên dịch.

Nếu câu hỏi của bạn là "điều gì sẽ xảy ra với tuyên bố như vậy" - trình biên dịch sẽ đặt phần tử mảng đầu tiên thành giá trị bạn đã cung cấp (0) và tất cả các phần tử khác sẽ được đặt thành 0 vì đó là giá trị mặc định cho mảng bị bỏ qua các yếu tố.

+0

Tôi không có nguồn, nhưng tôi khá chắc chắn rằng tôi đọc ở đâu đó mà không có giá trị mặc định cho khai báo mảng; bạn nhận được bất kỳ rác thải đã có ở đó. Không có ý nghĩa gì trong việc lãng phí thời gian thiết lập các giá trị này khi bạn có thể ghi đè lên chúng. –

+10

Ryan, nếu bạn không đặt giá trị cho phần tử đầu tiên toàn bộ mảng là chưa được khởi tạo và thực sự chứa rác, nhưng nếu bạn đặt giá trị cho ít nhất một phần tử thì toàn bộ mảng sẽ được khởi tạo để các phần tử không xác định được khởi tạo ngầm đến 0. – qrdl

+0

@qrdl bạn đang phải – mahesh

26

Nếu trình biên dịch của bạn là GCC bạn cũng có thể sử dụng cú pháp sau:

int array[256] = {[0 ... 255] = 0}; 

Vui lòng xem http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Designated-Inits.html#Designated-Inits và lưu ý rằng đây là tính năng dành riêng cho trình biên dịch.

+0

Chào mừng bạn! Vì bạn đã yêu cầu Tìm kiếm nhiều loại thủ thuật như vậy, tôi đã cung cấp – lakshmanaraj

+1

Bạn chắc chắn có thể làm điều này nếu bạn chọn, nhưng có những nhược điểm rõ ràng để dựa vào các phần mở rộng của trình biên dịch cụ thể như thế này. –

+0

@Dan Olson, câu hỏi của anh ta chính là hỏi về trình biên dịch cụ thể và do đó đã đăng bài này. Nếu bạn cảm thấy nó là vô ích, tôi sẽ xóa. – lakshmanaraj

16

Nó phụ thuộc vào nơi bạn đặt khởi tạo này.

Nếu mảng là tĩnh như trong

char array[100] = {0}; 

int main(void) 
{ 
... 
} 

sau đó nó là trình biên dịch mà giữ 100 0 byte trong segement dữ liệu của chương trình. Trong trường hợp này, bạn có thể đã bỏ qua trình khởi tạo.

Nếu mảng của bạn là tự động, thì đó là một câu chuyện khác.

int foo(void) 
{ 
char array[100] = {0}; 
... 
} 

Trong trường hợp này ở mọi cuộc gọi của hàm, bạn sẽ có một bộ nhớ ẩn.

Đoạn mã trên là tương đương với

int foo(void) 
{ 
char array[100]; 

memset(array, 0, sizeof(array)); 
.... 
} 

và nếu bạn bỏ qua initializer mảng của bạn sẽ chứa dữ liệu ngẫu nhiên (các dữ liệu của ngăn xếp).

Nếu mảng cục bộ của bạn được khai báo tĩnh như trong

int foo(void) 
{ 
static char array[100] = {0}; 
... 
} 

sau đó nó là về mặt kỹ thuật các trường hợp tương tự như cái đầu tiên.

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