2009-05-18 6 views
17

Làm thế nào để tự động thiết lập một mảng cấp phát động phao số không (0.0) trong quá trình phân bổđộng phân bổ và thiết lập về không một mảng phao

Đây có phải là OK

float* delay_line = new float[filter_len]; 

//THIS 
memset(delay_line, 0.0, filter_len); //can I do this for a float?? 

//OR THIS 
for (int i = 0; i < filter_len; i++) 
    delay_line[i] = 0.0; 

nào là hiệu quả nhất cách

Cảm ơn

Trả lời

15

sử dụng

#include <algorithm> 
... 
std::fill_n(delay_line, filer_len, 0) 
+0

Nếu không, bạn không thể sử dụng véc tơ, đây là cách C++ hiện đại, an toàn nhất để thực hiện. memset có thể nhanh hơn, nhưng nó chỉ là 0 byte không có kiểm tra kiểu, nếu bạn nhận được toán học của bạn sai bạn đang gặp rắc rối. – iain

+0

Tôi đồng ý về fill_n là phương thức ưa thích, ngay cả khi nó hơi chậm hơn (và tôi chỉ tin rằng khi tôi nhìn thấy nó;) Trái ngược với memset, phương pháp này vừa an toàn vừa dễ dàng hơn. có thể sử dụng phương pháp này để khởi tạo 4.2 ví dụ) – Pieter

32

Sử dụng sizeof(float) * filter_len trừ khi bạn đang làm việc trong một số triển khai lẻ tại đây sizeof(float) == sizeof(char).

memset(delay_line, 0, sizeof(float) * filter_len); 

Edit: Theo Stephan202 điểm ra trong các ý kiến, 0.0 là một giá trị dấu chấm động đặc biệt dễ dàng để mã cho memset kể từ khi tiêu chuẩn đại diện IEEE cho 0.0 là tất cả zero bit.

memset đang hoạt động trong lĩnh vực bộ nhớ chứ không phải là lĩnh vực số. Tham số thứ hai, khai báo một int, được gán cho một unsigned char. Nếu việc bạn triển khai C++ sử dụng bốn byte cho mỗi phao, các mối quan hệ sau đây giữ:

  • Nếu bạn nhớ phao bằng 0, giá trị sẽ là 0,0.
  • Nếu bạn ghi nhớ phao bằng 1, giá trị sẽ là 2,36943e-38.
  • Nếu bạn ghi nhớ phao với 42, giá trị sẽ là 1.51137e-13.
  • Nếu bạn ghi nhớ phao với 64, giá trị sẽ là 3.00392.

Vì vậy, số không là trường hợp đặc biệt.

Nếu điều này dường như đặc biệt, nhớ lại memset được khai báo trong <CString> hoặc <string.h>, và thường được sử dụng để làm những thứ như "***************" hoặc là "------------------". Rằng nó có thể cũng được sử dụng để bộ nhớ zero là một tác dụng phụ tiện lợi.

Như Milan Babuškov chỉ ra trong các nhận xét, có một chức năng bzero (không chuẩn và không được chấp nhận), có sẵn cho thời điểm trên Mac và Linux nhưng không phải Microsoft, vì nó được thiết kế đặc biệt để đặt bộ nhớ về không, an toàn bỏ qua một vài hướng dẫn. Nếu bạn sử dụng nó, và một bản phát hành trong tương lai của trình biên dịch của bạn sẽ bỏ sót nó, bạn không thể tự mình thực hiện bzero trong bản vá tương thích cục bộ, trừ khi bản phát hành tương lai có sử dụng lại tên cho một số mục đích khác.

+0

Cảm ơn, điều này sẽ đặt mỗi giá trị trong delay_line thành 0.0? –

+0

+1, lựa chọn đúng. memset() là cách nhanh nhất. –

+6

Có, điều này sẽ đặt mỗi giá trị thành 0.0: nếu dấu, số mũ và phần là 0, thì dấu phẩy đại diện cho 0.0: http://en.wikipedia.org/wiki/IEEE_754-1985 – Stephan202

3

Bây giờ chúng ta đang ở đó: tốt hơn là sử dụng lớp vector.

std::vector<float> delay_line(filter_len, 0.0); 
+0

Nhưng hãy xem câu trả lời của Neil: bạn sẽ không cần đối số 0.0: đây là giá trị đối số khởi tạo mặc định. – xtofl

11

Sử dụng std :: vector thay vì:

std::vector<float> delay_line(filter_len); 

Các vector sẽ không được khởi tạo.

+0

Không phải là cách hiệu quả nhất, nhưng chắc chắn là thanh lịch nhất. –

+3

Đó là hiệu quả nhất về mặt nỗ lực lập trình (không cần phải quản lý sự hủy diệt) và đó thường là điều quan trọng nhất để tối ưu hóa. –

+1

Không cần quản lý sự phá hủy hoặc xây dựng cho một mảng trên ngăn xếp :-) –

2

Đó là cách hiệu quả nhất

memset có lẽ một chút nhanh hơn, NHƯNG WHO CARES!?!? Tối ưu hóa vi mô xuống mức này là tổng thời gian, trừ khi bạn đang lập trình một máy tính, và có lẽ thậm chí không phải lúc đó.

Tôi nghĩ rằng cách ghi nhớ rõ ràng hơn, NHƯNG tôi nghĩ bạn thực sự đã kiểm tra trang người đàn ông của bạn để biết thêm ... Tôi sẽ ngạc nhiên nếu phiên bản thư viện chuẩn của bạn có chức năng ghi nhớ mất float làm đối số thứ hai.

PS: Mẫu bit biểu thị bằng không là giống nhau cho cả số nguyên và phao nổi ... điều này là do thiết kế, không chỉ là may mắn.

Chúc may mắn ;-)

Chúc mừng. Keith.

+3

Bashing vi tối ưu hóa là tổng lãng phí thời gian. Nếu QS không cần tối ưu hóa, tại sao anh ta lại hỏi đó là cách hiệu quả nhất? –

+1

Tôi thích memset nhưng không chắc chắn nếu đại diện nhị phân của một điểm 0 bằng không giống như số nguyên không Cảm ơn bạn đã giải phóng mặt bằng –

12

Các yếu tố của một mảng được cấp phát động có thể được khởi tạo với giá trị mặc định của các loại nguyên tố bằng cách làm theo kích thước mảng bởi một cặp trống ngoặc:

float* delay_line = new float[filter_len](); 
+1

Hiện đại-C++ khôn ngoan: điều này không nên được trả lời tốt nhất? –

3

Một lựa chọn khác là sử dụng calloc để phân bổ và không cùng một lúc:

float *delay_line = (float *)calloc(sizeof(float), filter_len); 

Ưu điểm ở đây là, tùy thuộc vào thực hiện malloc của bạn, nó có thể có thể để tránh zeroing mảng nếu nó biết được phân bổ từ bộ nhớ đó là đã zeroed (như các trang được phân bổ từ các sys hoạt động thường là)

Hãy nhớ rằng bạn phải sử dụng miễn phí() thay vì xóa [] trên một mảng như vậy.