C typedef указателя на структуру - PullRequest
35 голосов
/ 09 октября 2009

Я встречал следующий код:

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

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

Ответы [ 6 ]

54 голосов
/ 09 октября 2009

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

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

Где S1 - это структура, а S1PTR - указатель на эту структуру.

25 голосов
/ 13 января 2012

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

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

int do_fancy(vector a, vector b); 

или

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

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

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

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

3 голосов
/ 09 октября 2009

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

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

тогда вы можете использовать оба

struct vector_ *var;
vector var;

Но не забывайте конечную точку с запятой.

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

2 голосов
/ 09 октября 2009

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

Вы можете создать больше указателей, просто используя

S1PTR ptr1, ptr2, ptr3, ...;  

вместо

S1 *ptr1, *ptr2, *ptr3, ...;
1 голос
/ 10 октября 2009

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

typedef struct vactor_tag {
        double x;
        double y;
        double z;
} *vector;
0 голосов
/ 09 октября 2009

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

...