Câu trả lời:
Không.
#define
là một mã thông báo tiền xử lý: chính trình biên dịch sẽ không bao giờ nhìn thấy nó.
typedef
là một mã thông báo của trình biên dịch: bộ tiền xử lý không quan tâm đến nó.
Bạn có thể sử dụng cách này hoặc cách khác để đạt được hiệu quả tương tự, nhưng tốt hơn là sử dụng loại phù hợp với nhu cầu của bạn
#define MY_TYPE int
typedef int My_Type;
Khi mọi thứ trở nên "xơ xác", sử dụng công cụ thích hợp sẽ làm cho nó trở nên đúng đắn
#define FX_TYPE void (*)(int)
typedef void (*stdfx)(int);
void fx_typ(stdfx fx); /* ok */
void fx_def(FX_TYPE fx); /* error */
void fx_def(void (*)(int) fx);
; khai báo đúng là void fx_def(void (*fx)(int));
.
#define FX_TYPE(f) void (*f)(int)
. Sau đó, bạn sẽ khai báo hàm của mình là:void fx_def(FX_TYPE(fx));
typedef
tuân theo các quy tắc xác định phạm vi giống như các biến, trong khi define
vẫn hợp lệ cho đến khi kết thúc đơn vị biên dịch (hoặc cho đến khi khớp undef
).
Ngoài ra, một số điều có thể được thực hiện với những typedef
điều không thể được thực hiện với define
.
Ví dụ:
typedef int* int_p1;
int_p1 a, b, c; // a, b, c are all int pointers
#define int_p2 int*
int_p2 a, b, c; // only the first is a pointer, because int_p2
// is replaced with int*, producing: int* a, b, c
// which should be read as: int *a, b, c
typedef int a10[10];
a10 a, b, c; // create three 10-int arrays
typedef int (*func_p) (int);
func_p fp; // func_p is a pointer to a function that
// takes an int and returns an int
Không, họ không giống nhau. Ví dụ:
#define INTPTR int*
...
INTPTR a, b;
Sau khi xử lý trước, dòng đó mở rộng thành
int* a, b;
Hy vọng rằng bạn nhìn thấy vấn đề; chỉ a
sẽ có loại int *
; b
sẽ được khai báo là đơn giản int
(vì *
được liên kết với bộ khai báo, không phải từ chỉ định kiểu).
Đối lập điều đó với
typedef int *INTPTR;
...
INTPTR a, b;
Trong trường hợp này, cả hai a
và b
sẽ có loại int *
.
Có toàn bộ các lớp typedef không thể được mô phỏng bằng macro bộ xử lý trước, chẳng hạn như con trỏ đến các hàm hoặc mảng:
typedef int (*CALLBACK)(void);
typedef int *(*(*OBNOXIOUSFUNC)(void))[20];
...
CALLBACK aCallbackFunc; // aCallbackFunc is a pointer to a function
// returning int
OBNOXIOUSFUNC anObnoxiousFunc; // anObnoxiousFunc is a pointer to a function
// returning a pointer to a 20-element array
// of pointers to int
Hãy thử làm điều đó với macro bộ xử lý trước.
#define xác định macro.
typedef xác định các loại.
Bây giờ nói rằng, đây là một vài khác biệt:
Với #define, bạn có thể xác định các hằng số có thể được sử dụng trong thời gian biên dịch. Các hằng số có thể được sử dụng với #ifdef để kiểm tra cách mã được biên dịch và chuyên biệt hóa mã nhất định theo các tham số biên dịch.
Bạn cũng có thể sử dụng #define để khai báo các hàm Macro thu nhỏ tìm và thay thế .
typedef có thể được sử dụng để cung cấp bí danh cho các loại (bạn cũng có thể làm với #define ), nhưng sẽ an toàn hơn vì tính chất tìm và thay thế của hằng #define .
Bên cạnh đó, bạn có thể sử dụng khai báo chuyển tiếp với typedef cho phép bạn khai báo một kiểu sẽ được sử dụng, nhưng chưa được liên kết với tệp bạn đang viết.
Macro tiền xử lý (" #define
s") là một công cụ thay thế từ vựng được gọi là "tìm kiếm và thay thế". Họ hoàn toàn không hiểu về ngôn ngữ lập trình và không hiểu bạn đang cố gắng làm gì. Bạn có thể coi chúng như một thợ sao chép / dán được tôn vinh - đôi khi điều đó hữu ích, nhưng bạn nên sử dụng nó một cách cẩn thận.
Typedefs là một tính năng ngôn ngữ C cho phép bạn tạo bí danh cho các loại. Điều này cực kỳ hữu ích để làm cho các kiểu phức hợp phức tạp (như cấu trúc và con trỏ hàm) có thể đọc và xử lý được (trong C ++ thậm chí có những trường hợp bạn phải gõ một kiểu).
Đối với (3): Bạn nên luôn thích các tính năng ngôn ngữ hơn các macro tiền xử lý khi có thể! Vì vậy, hãy luôn sử dụng typedef cho các kiểu và các giá trị không đổi cho các hằng số. Bằng cách đó, trình biên dịch thực sự có thể tương tác với bạn một cách có ý nghĩa. Hãy nhớ rằng trình biên dịch là bạn của bạn, vì vậy bạn nên nói với nó càng nhiều càng tốt. Macro tiền xử lý làm ngược lại hoàn toàn bằng cách ẩn ngữ nghĩa của bạn khỏi trình biên dịch.
Chúng rất khác nhau, mặc dù chúng thường được sử dụng để triển khai các kiểu dữ liệu tùy chỉnh (đó là những gì tôi đang giả định câu hỏi này là tất cả về).
Như pmg đã đề cập, #define
được xử lý bởi bộ xử lý trước (giống như hoạt động cắt và dán) trước khi trình biên dịch nhìn thấy mã và typedef
được trình biên dịch giải thích.
Một trong những điểm khác biệt chính (ít nhất là khi nói đến việc xác định kiểu dữ liệu) là typedef
cho phép kiểm tra kiểu cụ thể hơn. Ví dụ,
#define defType int
typedef int tdType
defType x;
tdType y;
Ở đây, trình biên dịch xem biến x là một int, nhưng biến y là một kiểu dữ liệu được gọi là 'tdType' có cùng kích thước với một int. Nếu bạn đã viết một hàm nhận tham số kiểu defType, trình gọi có thể chuyển một int bình thường và trình biên dịch sẽ không biết sự khác biệt. Nếu thay vào đó, hàm nhận một tham số kiểu tdType, trình biên dịch sẽ đảm bảo rằng một biến có kiểu thích hợp được sử dụng trong các lần gọi hàm.
Ngoài ra, một số trình gỡ lỗi có khả năng xử lý typedef
s, điều này có thể hữu ích hơn nhiều so với việc có tất cả các kiểu tùy chỉnh được liệt kê là kiểu nguyên thủy cơ bản của chúng (như nó sẽ như vậy nếu #define
được sử dụng thay thế).
Không.
Typedef là một từ khóa C tạo bí danh cho một loại.
#define là một hướng dẫn xử lý trước, tạo sự kiện thay thế văn bản trước khi biên dịch. Khi trình biên dịch nhận được mã, từ "#defined" ban đầu không còn ở đó nữa. #define chủ yếu được sử dụng cho macro và hằng số toàn cục.
AFAIK, không.
typedef
giúp bạn thiết lập "bí danh" cho kiểu dữ liệu hiện có. Ví dụ. typedef char chr
;
#define
là một chỉ thị tiền xử lý được sử dụng để xác định macro hoặc thay thế mẫu chung. Ví dụ. #define MAX 100
, thay thế tất cả các lần xuất hiện MAX
với 100
Như đã đề cập ở trên, có một sự khác biệt chính giữa #define
typedef và typedef. Cách đúng đắn để nghĩ về điều đó là xem typedef là một kiểu "được đóng gói" hoàn chỉnh. Nó có nghĩa là bạn không thể thêm vào nó sau khi bạn đã khai báo nó.
Bạn có thể mở rộng tên kiểu macro với các từ chỉ định kiểu khác, nhưng không phải tên kiểu typedef'd:
#define fruit int
unsigned fruit i; // works fine
typedef int fruit;
unsigned fruit i; // illegal
Ngoài ra, tên typedef'd cung cấp kiểu cho mọi người khai báo trong một khai báo.
#define fruit int *
fruit apple, banana;
Sau khi mở rộng macro, dòng thứ hai trở thành:
int *apple, banana;
Apple là một con trỏ đến một int, trong khi banana là một int. Trong sự so sánh. một typedef như thế này:
typedef char *fruit;
fruit apple, banana;
tuyên bố cả táo và chuối giống nhau. Tên ở mặt trước khác nhau, nhưng cả hai đều là con trỏ đến một ký tự.
Như mọi người đã nói ở trên, chúng không giống nhau. Hầu hết các câu trả lời chỉ ra typedef
là có lợi hơn #define
. Nhưng hãy để tôi đặt một điểm cộng là #define
:
khi mã của bạn cực kỳ lớn, nằm rải rác trên nhiều tệp, thì tốt hơn nên sử dụng #define
; nó giúp dễ đọc - bạn có thể đơn giản xử lý trước tất cả mã để xem định nghĩa kiểu thực tế của một biến tại vị trí của chính nó.
stdfx
, các đối tượng hợp lệ của kiểu đó là con trỏ đến các hàm nhận int và không trả về giá trị.