Можно ли только объявить тип в начале, но определить его позже в C? - PullRequest
0 голосов
/ 01 марта 2019

В этом примере полное определение Book перед его использованием в main().Есть ли способ объявить Book как тип без указания деталей, но определить детали после main().Спасибо.

https://www.tutorialspoint.com/cprogramming/c_typedef.htm

#include <stdio.h>
#include <string.h>

typedef struct Books {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
} Book;

int main( ) {

   Book book;

   strcpy( book.title, "C Programming");
   strcpy( book.author, "Nuha Ali"); 
   strcpy( book.subject, "C Programming Tutorial");
   book.book_id = 6495407;

   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);

   return 0;
}

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Вы можете заранее объявить об этом и ввести typedef:

typedef struct Books Book;

Это позволит вам использовать указатели типа Book*, но не позволит разыменовать их (будь то с помощью * 1005).* или с помощью ->), или объявите объекты этого типа (как с Book book;).

Ближайшая вещь для достижения ваших заявленных целей, вероятно, будет с функцией, которая возвращает указатель на выделенный Book а затем с функциями доступа.

Компилируется:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Books Book; //forward declare + typedef
Book *Book__alloc(void);
//accessor functions:
char*Book__title(Book*);
char*Book__author(Book*);
char*Book__subject(Book*);
int *Book__id(Book*);


int main( ) {

   Book *book = Book__alloc();
   if(!book) return EXIT_FAILURE;

   strcpy( Book__title(book), "C Programming");
   strcpy( Book__author(book), "Nuha Ali"); 
   strcpy( Book__subject(book), "C Programming Tutorial");
   *Book__id(book) = 6495407;

   printf( "Book title : %s\n", Book__title(book));
   printf( "Book author : %s\n", Book__author(book));
   printf( "Book subject : %s\n", Book__subject(book));
   printf( "Book book_id : %d\n", *Book__id(book));

   free(book);

   return 0;
}

//provide definitions after the fact
struct Books {
   char title[50];
   char author[50];
   char subject[100];
   int book_id;
};
Book *Book__alloc(void){ return malloc(sizeof(Book)); }
char*Book__title(Book*X){ return X->title; }
char*Book__author(Book*X){ return X->author; }
char*Book__subject(Book*X){ return X->subject; }
int *Book__id(Book*X) { return &X->book_id; }
0 голосов
/ 01 марта 2019

Хотя было отмечено, что это возможно, я не вижу этого, поэтому мой ответ - Нет. Просто потому, что тип Book уже используется в main (), например, как

strcpy( book.author, "Nuha Ali");

на самом деле лечиться компилятором, если он не знает о структуре Книги?
Это возможно в объявлениях функций, например:

typedef struct Books Book;
void foo(struct Books *aBookPtr); 

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

...