Что означает этот указатель определения структуры типа (в C)?
В K & R Chapter 6 выражение упоминается следующим образом:
struct{
int len;
char *str;
} *p;
Я не мог понять, к какой структуре относится этот указатель p, и если такое определение указателя даже справедливо, потому что во всех других примерах, приведенных в книге, и тех, которые я видел иначе, при определении указателя на структуру, необходимо указать название структуры, то есть тип, который определяется. Например,
struct example{
int a;
...
}s1;
а затем
struct example *ptr = &s1;
поэтому упоминается, что ptr указывает на пример структуры типа, а не только на структуру.
Кроме того, особенно интересным было следующее:
* p- > str извлекает любые str-точки; * P- > ул ++ увеличивает str после доступа к тому, на что он указывает (точно так же, как * s ++);
Я не мог следить за тем, что p в первую очередь, следовательно, а не приростом и разыменованием.
Что здесь происходит?
Спасибо заранее!
P.S. Я новичок здесь, поэтому любые отзывы о формате вопроса также будут оценены.
Ответы
Ответ 1
Ключевое слово struct
работает как расширенная версия typedef
, за исключением того, что вы создаете сложный настраиваемый тип (называемый структурой) вместо наложения существующего типа. Если у вас есть только одна вещь, которая должна использовать объявленный тип, вам не нужно указывать явное имя для этого типа.
Первое утверждение, которое вы ищете, объявляет структуру с двумя полями, но не называет ее. Это называется анонимной структурой. Однако объявление содержит указатель этого типа.
Один возможный прецедент для такого объявления - это когда вы создаете заголовок для внешней библиотеки, возможно, тот, который даже не написан на C. В этом случае тип структуры может быть непрозрачным или неполным, а вы просто нужно иметь удобную ссылку на некоторые ее части. Создание анонимности структуры не позволяет вам легко выделять ее, но позволяет вам взаимодействовать с ней через указатель.
Чаще всего вы увидите это обозначение, используемое в сочетании с именованными или, по крайней мере, псевдонимами. Второе утверждение можно было бы переписать как
struct example { ... } s1, *ptr;
В этом случае struct example *ptr = &s1;
будет просто ptr = &s1;
.
Еще более распространенным явлением является использование анонимных структур с помощью typedef
, создание пользовательских имен типов, которые не включают ключевое слово struct
. Второй пример можно переписать как
typedef struct { ... } example, *pexample;
example s1;
pexample ptr; // alternatively example *ptr;
ptr = &s1;
Обратите внимание, что тип s1
равен example
, а не struct example
в этом случае.
Ответ 2
Для начала рассмотрим следующую простую программу
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
struct {
int len;
char *str;
} *p;
p = malloc( sizeof( *p ) );
p->str = "Hello Nihal Jain";
p->len = strlen( p->str );
while ( *p->str ) putchar( *p->str++ );
putchar( '\n' );
free( p );
return 0;
}
Его вывод
Hello Nihal Jain
Итак, в этом объявлении
struct {
int len;
char *str;
} *p;
объявлен указатель типа неназванной структуры. Сам указатель не инициализирован. Например, вы можете написать
struct {
int len;
char *str;
} *p = malloc( sizeof( *p ) );
Для этой простой программы имя структуры не требуется, потому что ни одно объявление объекта типа структуры не присутствует или не требуется в программе.
Таким образом, вы не можете объявить объект типа структуры, но в этом случае он не требуется.
В соответствии со структурой или объединением C Standard объявляются как
struct-or-union-specifier:
struct-or-union identifieropt { struct-declaration-list }
struct-or-union identifier
Видно, что идентификатор является необязательным, если существует список struct-declaration-list. Таким образом, неназванная структура может использоваться как спецификатор типа.
Еще один пример использования перечислений. Вы можете объявлять счетчики без объявления типа перечисления. Например
enum { EXIT_SUCCESS = 0, EXIT_FAILURE = -1 };
Вы можете использовать перечисления, которые имеют тип int
, не объявляя объект типа перечисления, если в программе нет такого требования.
Ответ 3
Еще одно использование (анонимных структур) было бы использовать их внутри союзов или других структур, что в основном ограничивает использование этой структуры для этого конкретного союза или структуры родителей ничем иным, что весьма полезно с точки зрения программиста, потому что глядя на такой код, он предоставляет нам информацию о том, что он используется локально в контексте структуры или объединения внутри него -
не более того. (также избавляет нас от именования).
Также, если вы используете эту анонимную структуру, вы не сможете выделить один ее экземпляр, отличный от того, который уже существует.
Пример:-( громкий комментарий: как его использовать?)
struct {
int a;
int b;
} p;
scanf("%d",&p.a);
Ответ 4
Если вам понадобилось одноразовое одноразовое определение структуры (или объединения), которое не будет полезно вне области, в которой оно было объявлено, вы должны использовать то, что называется анонимные или неназванные структуры и объединения. Это избавит вас от необходимости объявлять структуру до ее использования, а в случае сложных типов - объявлять внутренние типы, такие как здесь.