Trong C, bạn có thể bỏ con trỏ void trả về malloc
. C làm điều này cho bạn nhưng bạn cũng có thể rõ ràng.
malloc
trả lại con trỏ void *
hoặc void, giá trị trả về này sau đó có thể được một lập trình viên đưa vào các loại con trỏ khác. Hoặc lập trình viên có thể dựa vào C để thực hiện chuyển đổi kiểu. Chuyển đổi loại C bằng cách sử dụng phôi sẽ không thay đổi.
Tuy nhiên, mã C dựa trên trình biên dịch C có thể gây trở ngại và khó đọc. Một lập trình viên phát triển có thể giúp các lập trình viên bảo trì, những người cuối cùng sẽ phải đọc mã.
Thêm diễn viên rõ ràng vào giá trị trả về malloc
giúp những người sẽ có để đọc mã và xác định ý định của tác giả. Đây là lợi ích thực sự của việc đúc con trỏ rỗng một cách rõ ràng bởi malloc
. Thực hành lập trình này không KHÔNG chỉ định sai trình biên dịch hoặc sử dụng một số tính năng biên dịch phức tạp có thể thay đổi.
Ba ví dụ sau làm nổi bật thực hành lập trình này. Trong ví dụ đầu tiên, malloc
(được xác định trong <stdlib.h>
) được truyền một cách rõ ràng và một số công việc nhỏ nhặt được thực hiện .
#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
Trong ví dụ thứ hai này, khác biệt duy nhất là <stdlib.h>
được nhận xét. Mã số vẫn chạy và tạo ra kết quả tương tự. Bây giờ, "lý do" tại sao công trình này lại khá trực tiếp. Khi C KHÔNG tìm nguyên mẫu cho hàm, nó giả định rằng hàm trả về một số int
, nhưng malloc
trả về một con trỏ rỗng.Trong trường hợp này diễn viên rõ ràng đã nói với trình biên dịch C, cũng như đơn vị carbon của nguồn, giá trị trả về bởi malloc
phải được chuyển đổi thành một con trỏ ký tự.
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = (char *) malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// prints abc at the console
}
Ví dụ cuối cùng (vd) KHÔNG phát hành và không bao gồm <stdlib.h>
. Cả trình soạn thảo Eclipse và trình biên dịch đều phàn nàn về mã này (như chúng cần). Thông điệp biên dịch là
..\main.c(18) : warning C4047: '=' : 'char *' differs in levels of indirection from 'int'
Và mã nguồn là:
//#include <stdlib.h>
#define nr_chars 4
main()
{
char *data;
data = malloc(nr_chars*sizeof(char));
*data++ = 'a';
*data++ = 'b';
*data++ = 'c';
*data++ = '\0'; // it is allowed to go one past an array
data -= nr_chars; // back to the front of data
printf("%s\n", data);
// compiler displays a "warning" and prints abc at the console
}
Thay đổi ví dụ 3 để bao gồm kết quả trong không có cảnh báo và chương trình chạy như dự định. Tuy nhiên, cả hai ví dụ 2 và 3 thiếu diễn xuất rõ ràng và trong suốt thời gian mã được viết theo kiểu này, mã này sẽ đắt hơn và có nhiều khả năng bị thay đổi không chính xác bởi con người (do đó chi phí bổ sung). C-trình biên dịch.
bản sao có thể có của [chuyển đổi không hợp lệ từ 'void \ *' thành 'node \ *' \ [-fpermissive \]] (http://stackoverflow.com/questions/16793587/invalid-conversion-from-void-to -node-fpermissive) –
Tôi không nghĩ rằng thông báo lỗi là 'void không thể được sử dụng để khởi tạo kiss_fft_ctx'. Tôi nghĩ đó là 'void *' và 'kss_fft_ctx *'. Những dấu sao đó tạo nên sự khác biệt ** BIG ** trong ý nghĩa và sự hiểu biết của bạn về ngôn ngữ. – abelenky