Что такое прямая ссылка в C?
-
11-07-2019 - |
Вопрос
Что такое прямая ссылка в C относительно указателей?
Могу ли я получить пример?
Решение
Смотрите эту страницу на прямые ссылки . Я не вижу, как прямая ссылка будет отличаться с указателями и с другими типами PoD.
Обратите внимание, что вы можете пересылать объявления типов и объявлять переменные, которые являются указателями на этот тип:
struct MyStruct;
struct MyStruct *ptr;
struct MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
// Or:
typedef struct MyStruct MyStruct;
MyStruct *ptr;
MyStruct var; // ILLEGAL
ptr->member; // ILLEGAL
struct MyStruct {
// ...
};
Я думаю, это то, что вы просите, когда имеете дело с указателями и предварительным объявлением.
Другие советы
Я думаю, что "прямая ссылка" в отношении указателей означает что-то вроде этого:
struct MyStruct *ptr; // this is a forward reference.
struct MyStruct
{
struct MyStruct *next; // another forward reference - this is much more useful
// some data members
};
Указатель объявляется до определения структуры, на которую он указывает.
Компилятор может обойтись без этого, потому что указатель хранит адрес, и вам не нужно знать, что находится по этому адресу, чтобы зарезервировать память для указателя.
Прямая ссылка - это когда вы объявляете тип, но не определяете его. Р>
Он позволяет вам использовать тип по указателю (или по ссылке на C ++), но вы не можете объявить переменную.
Это способ сказать компилятору, что что-то существует
Скажите, что у вас есть структура Plop, определенная в Plop.h :
struct Plop
{
int n;
float f;
};
Теперь вы хотите добавить некоторые служебные функции, которые работают с этой структурой. Вы создаете другой файл PlopUtils.h (допустим, вы не можете изменить Plop.h):
struct Plop; // Instead of including Plop.h, just use a forward declaration to speed up compile time
void doSomething(Plop* plop);
void doNothing(Plop* plop);
Теперь, когда вы реализуете эту функцию, вам понадобится определение структуры, поэтому вам нужно включить файл Plop.h в ваш PlopUtils.cpp :
#include "PlopUtils.h"
#include "Plop.h" // now we need to include the header in order to work with the type
void doSomething(Plop* plop)
{
plop->n ...
}
void doNothing(Plop* plop);
{
plop->f ...
}
Я думаю, что у компилятора C изначально был этап, в котором он вместе делал построение таблицы символов и семантический анализ. Так, например:
....
... foo(a,b) + 1 ... // assumes foo returns int
....
double foo(double x, double y){ ... } // violates earlier assumption
чтобы предотвратить это, вы говорите:
double foo(double x, double y); // this is the forward declaration
....
... foo(a,b) + 1 ... // correct assumptions made
....
double foo(double x, double y){ ... } // this is the real declaration
Паскаль придерживался той же концепции.
Добавление к предыдущим ответам. Типичная ситуация, в которой прямая ссылка является обязательной, - это когда структура foo содержит указатель на строку структуры, а панель содержит указатель на foo (циклическая зависимость между объявлениями). Единственный способ выразить эту ситуацию в C - это использовать предварительное объявление, т. Е.
struct foo;
struct bar
{
struct foo *f;
};
struct foo
{
struct bar *b;
};
Прямые ссылки позволяют компилятору C выполнять меньше проходов и значительно сокращают время компиляции. Вероятно, это было важно около 20 лет назад, когда компьютеры были намного медленнее и компиляторы менее эффективны.