2009-10-09 42 views
34

tôi đã đi qua đoạn mã sau:C typedef của con trỏ đến cấu trúc

typedef struct { 
     double x; 
     double y; 
     double z; 
} *vector; 

Đây có phải là một định nghĩa kiểu hợp lệ? Mã biên dịch và chạy tốt. Tôi chỉ tò mò nếu đây là thực tế phổ biến.

Trả lời

51

Hoàn toàn hợp lệ. Thông thường, bạn có thể tận dụng tối đa theo cách này bằng cách định nghĩa hai loại với nhau:

typedef struct 
{ 
int a; 
int b; 
} S1, *S1PTR; 

đâu S1 là một struct và S1PTR là con trỏ đến struct này.

+1

Cảm ơn rất nhiều ý nghĩa hoàn hảo. –

+0

... và có thể 'const * S1CPTR'. – alecov

+0

Chỉ để xác nhận tôi hiểu. Điều đó tương đương với 'typedef struct {...} S1; typedef S1 * S1PTR; '? – DCShannon

-2

có ... giúp bạn khắc phục sự cố liên tục gõ từ 'struct' mỗi khi bạn khai báo cấu trúc vectơ hoặc con trỏ đến nó.

+1

Tôi nghĩ rằng câu hỏi phải làm nhiều hơn với typedef'ing để * vector chứ không chỉ là vector. –

2

Đây là một hợp lệ, điều nó làm là xác định loại mới. Như @Alex đã nói, sẽ hữu ích khi xác định loại và loại con trỏ.

Bạn có thể tạo ra nhiều con trỏ chỉ bằng cách sử dụng

S1PTR ptr1, ptr2, ptr3, ...; 

thay vì

S1 *ptr1, *ptr2, *ptr3, ...; 
3

Có nó là hợp lệ. Nếu bạn cần "bảo mật" hơn bạn cũng có thể làm

typedef struct vector_{ 
     double x; 
     double y; 
     double z; 
} *vector; 

sau đó bạn có thể sử dụng cả hai

struct vector_ *var; 
vector var; 

Nhưng đừng quên kết thúc dấu chấm phẩy.

Chỉ sử dụng typedef có nghĩa là bạn đặt tên theo cách đó. bằng không nó sẽ ít nhiều ẩn danh.

+1

Tôi tin rằng bạn có thể sử dụng cùng một tên cho cả hai (nghĩa là, bạn không cần gạch dưới nhưng có thể để mọi thứ khác trong mã của bạn giống nhau, vì không gian tên riêng biệt). – RastaJedi

1

Có giá trị như được mô tả trong các câu trả lời ở trên. Một gợi ý nhỏ, nó sẽ tốt hơn nếu bạn cung cấp một tên thẻ quá, như sau. Điều này sẽ giúp một số IDE để phân tích cú pháp mã của bạn tốt hơn.

typedef struct vactor_tag { 
     double x; 
     double y; 
     double z; 
} *vector; 
24

Có đúng vậy. Nhưng đó là phong cách xấu xa. Không phải khai báo trực tiếp cấu trúc, mà là khai báo trực tiếp của một kiểu con trỏ. Đó là obfuscation, các thông tin mà một biến hoặc tham số nhất định là một con trỏ (và đến một mức độ thấp hơn cho mảng) là cực kỳ quan trọng khi bạn muốn đọc mã.

Khi xem lại mã, thường rất khó để nhìn thấy ở cái nhìn đầu tiên chức năng nào có thể có tác dụng phụ hay không. Nếu các loại được sử dụng ẩn thông tin này, nó sẽ thêm một gánh nặng ghi nhớ cho người đọc.

int do_fancy(vector a, vector b); 

hoặc

int do_fancy(vector *a, vector *b); 

trong trường hợp đầu tiên tôi có thể bỏ lỡ một cách dễ dàng mà chức năng đó có thể thay đổi nội dung của một hoặc b. Trong lần thứ hai tôi được cảnh báo.

Và khi thực sự viết mã tôi cũng biết trực tiếp để viết a->x và không có trình biên dịch cho tôi biết error: request for member x 'trong một cái gì đó không phải là một cấu trúc hoặc union`.

Tôi biết, nó trông giống như một sở thích cá nhân, nhưng đã làm việc với rất nhiều mã bên ngoài, tôi có thể đảm bảo với bạn rằng nó cực kỳ khó chịu khi bạn không nhận ra mức độ biến đổi của các biến. Đó là một lý do tôi cũng không thích tài liệu tham khảo C++ (trong Java nó không phải vì tất cả các đối tượng được truyền theo tham chiếu, nó nhất quán) và loại LPCSTR của Microsoft.

+6

+1 cho quan sát rằng 'typedef struct {...} * obj' dẫn đến một kiểu yêu cầu bí ẩn' -> 'thay vì' .' để truy cập phần tử. – Michael

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