Das ist jetzt nicht konkret auf deine Frage bezogen, aber http://www.eskimo.com/~scs/C-faq/top.html ist recht interessant. Und falls du deinem Buch nicht so ganz traust oder es mit einem anderen ergänzen willst: http://users.powernet.co.uk/eton/clc/cbooks.html
Zu deinem Code: Es ist nicht gerade hilfreich, wenn du unkompilierbaren Code postest. Etwas wie struct object p {...}; kann es in C zum Beispiel nicht geben. Du meinst vielleicht
struct object /* Definition des Typs "struct object" */
{
...
};
struct object p; /* Deklaration des Objekts p vom obigen Typ */
oder gleich zusammengezogen
struct object
{
...
} p; /* Typdefinition und Deklaration eines Objekts dieses Typs */
Und zu deiner Frage: Deklarationen sind sowohl außerhalb von Funktionen als auch zu Beginn jedes Blocks erlaubt. Zuweisungen und sonstige Statements sind nur innerhalb von Funktionen erlaubt.
Eine nackte Deklaration außerhalb einer Funktion deklariert ein Objekt, das über die gesamte Laufzeit des Programms exisitert. Werden solche file-scope-Variablen nicht explizit initialisiert, so initialisiert sie der Compiler mit 0 (vom richtigen Typ, also 0 oder '\0' oder 0.0 oder NULL). Explizit dürfen sie nur mit bestimmten Arten von konstanten Ausdrücken initialisiert werden, deren Wert der Compiler zur Übersetzungszeit berechnen kann.
Nackte Deklarationen innerhalb von Funktionen deklarieren Variablen, die am Beginn des Blocks erzeugt und am Ende des Blocks zerstört werden. Diese werden nicht implizit initialisiert, explizit dürfen sie auch mit nichtkonstanten Ausdrücken initialisiert werden.
D.h.
int i = 3; /* Deklaration mit konstanter Initialisierung */
ist sowohl innerhalb als außerhalb von Funktionen erlaubt.
int i; /* Deklaration */
i = 3; /* Zuweisung */
sowie
int i = 3; /* Deklaration mit konstanter Initialisierung */
int j = i; /* Deklaration mit nichtkonstanter Initialisierung */
sind nur innerhalb einer Funktion erlaubt.