2009-10-09 8 views
34

я наткнулся на следующий код:C ЬурейеЕ указателя на структуру

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

Является ли это действительное определение типа? Код компилируется и работает нормально. Мне было просто любопытно, если это обычная практика.

ответ

51

Абсолютно верно. Как правило, вы можете в полной мере воспользоваться этим способом определения двух типов вместе:

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

Где S1 является структура и S1PTR является указателем на этой структуры.

+1

Большое спасибо, что имеет смысл. – 2009-10-09 13:40:41

+0

... и, возможно, 'const * S1CPTR'. – alecov

+0

Просто для подтверждения, я понимаю. Это эквивалентно 'typedef struct {...} S1; typedef S1 * S1PTR; '? – DCShannon

-2

Да ... избавляет вас от необходимости постоянно печатать слово «struct» каждый раз, когда вы объявляете векторную структуру или указатель на нее.

+1

Я думаю, что вопрос должен был сделать больше с помощью typedef'ing to * vector, а не только с вектором. –

2

Это действительный, то, что он делает, определяет новый тип. Как сказал @Alex, было бы полезно определить тип и тип указателя.

Вы можете создать несколько указателей только с помощью

S1PTR ptr1, ptr2, ptr3, ...; 

вместо

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

Да действительно. Если вам нужно больше «безопасность» вы можете также сделать

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

, то вы можете использовать как

struct vector_ *var; 
vector var; 

Но не забудьте окончание запятой.

Использование только typedef означает, что вы так называете его. в противном случае это было бы более или менее анонимным.

+1

Я считаю, что вы можете использовать одно и то же имя для обоих (т. Е. Вам не нужен символ подчеркивания, но он может оставить все остальное в вашем коде тем же, потому что пространства имен являются отдельными). – RastaJedi

1

Да, это действительно так, как описано в приведенных выше ответах. Небольшое предложение, было бы лучше, если бы вы указали название тега, как показано ниже. Это поможет некоторым IDE лучше разобрать ваш код.

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

Да, это так. Но это плохой стиль. Не прямое объявление структуры, а прямое объявление типа указателя. Это обфускация, информация о том, что данная переменная или параметр является указателем (и в меньшей степени для массивов), крайне важна, когда вы хотите прочитать код.

При просмотре кода часто бывает трудно увидеть на первый взгляд, какая функция может иметь побочный эффект или нет. Если используемые типы скрывают эту информацию, это добавляет бремени запоминания для читателя.

int do_fancy(vector a, vector b); 

или

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

в первом случае можно пропустить легко, что эта функция может изменить содержание или б. Во втором я предупрежден.

И когда на самом деле писать код, я также знаю непосредственно, чтобы написать a->x, и у меня нет компилятора error: request for member x 'в чем-то не структура или объединение`.

Я знаю, это похоже на личную вещь вкуса, но, работая с большим количеством внешнего кода, я могу заверить вас, что это очень раздражает, когда вы не понимаете уровень переменных в пространстве. Это одна из причин, по которой мне также не нравятся ссылки на C++ (в Java это происходит не потому, что все объекты передаются по ссылке, это непротиворечиво) и типы LPCSTR от Microsoft.

+6

+1 для наблюдения, что 'typedef struct {...} * obj' приводит к типу, который загадочно требует' -> 'вместо' .' для доступа к элементу. – Michael

Смежные вопросы