Переименовать переменные, когда typedef? - PullRequest
1 голос
/ 08 марта 2012

Можно ли переименовать переменные структуры при использовании typedef?

typedef struct {
    float x;
    float y;
    float z;
} Vector;

typedef Vector {
    float r;
    float g;
    float b;
} Color;

Ответы [ 5 ]

2 голосов
/ 08 марта 2012

Предположительно, вы имеете в виду некий typedef, который позволил бы вам сказать: «Цвет такой же, как у вектора, но с именами x, y и z, измененными на r, g и b соответственно "?

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

Редактировать: вы можете, однако, заставить функцию работать с любой из них довольно легко:

typedef union { 
    Color c;
    Vector v;
} cv;

int my_func(cv *value);

C гарантирует, что начальная последовательность элементов с одинаковыми типами в одном и том же порядке (который в данном случае является всеми из них) может обрабатываться одинаково с помощью любого селектора. Другими словами, если вы вставите Vector в свой cv и передадите его функции, функция может работать с этими тремя элементами: r, g и b или x, y и z без проблем (например, при записи в g это изменит y, если вы просматриваете его как Vector вместо Color).

Редактировать: C99, §6.5.2.3 / 5:

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

В этом случае все члены c и v имеют одинаковые типы в одном и том же порядке, поэтому это правило применяется ко всему члену. Перечитывая вещи, однако, это только позволяет вам «проверять» общую начальную последовательность, которая, вероятно, не включает в себя запись в нее (хотя мне трудно представить, как вы могли бы сделать чтение из любого члена, не заставляя писать работу как хорошо).

1 голос
/ 08 марта 2012

Нет, вы не можете этого сделать. Вам необходимо объявить новый тип структуры:

typedef struct {
    float x;
    float y;
    float z;
} Vector;

typedef struct {
    float r;
    float g;
    float b;
} Color;
0 голосов
/ 08 марта 2012

Как сказали другие ответы, НЕТ.Но я слышал, что C11 поддерживает анонимные структуры, поэтому старые добрые

typedef union
{
    struct
    {
        float x, y, z;
    };
    struct
    {
        float r, g, b;
    };
} Vector;

typedef Vector Color;

тоже могут это сделать.

Конечно, сильно смешивая использование x, y и z с r, g и b могут демонстрировать неопределенное поведение, но, конечно, не существует реализации, где чтение r не дает надежного значения, только что записанного в x.

0 голосов
/ 08 марта 2012

Нужно иметь функциональную абстракцию.

Суть:

typedef Vector Color; /* a color is a kind of vector */

float color_red(Color *c)
{ 
  return c->x;
}

В других местах вы используете color_red (c), а не c-> x.

Я постоянно сталкиваюсь с этим в программировании на Лиспе.Я хочу пару вещей, и лучший инструмент - клетка против.Минус ячейка имеет поля, называемые CAR и CDR.Это нормально, просто напишите некоторые другие функции, которые обертывают их под разными именами.(CAR и CDR также называются FIRST и REST для разъяснения очевидного использования списка.)

0 голосов
/ 08 марта 2012

Я не думаю, что это возможно ... самым близким было бы просто сделать второе и скопировать первое во второе, но в C. нет никакого отражения (ближайшая концепция AFAIK).

Edit-Вы говорите о переименовании членов структуры, верно? Эти символы отображаются во время компиляции. Вы могли бы возможно связываться с таблицей символов, но я сомневаюсь в этом, и это кажется огромным излишним, не говоря уже об опасности.

...