(1) No, you don't copy the EOF marker. You close the file and leave it to the operating system and compiler library system to work out the details of how that is handled.
(2) Pre-ANSI, there was no standard for prototypes. Some pre-ANSI C compilers, including the ones from AT&T that I used in the 1970's, didn't even have prototypes, at all. Later, they were added. For example, Microsoft C compilers operating under DOS did have them. But there is "pre-ANSI" standard method for prototypes. Just varying ways. Some accepted no parameter types in the prototype, at all, simply instead doing the "usual conversions" for parameters based upon the expressions and rules for parameter passing (no float, only double; etc.) Some accepted parameter typing. Some didn't even accept prototypes, at all, as I said. Pre-ANSI where prototypes did exist almost always interpreted an untyped return value as int, though.
For example,
int magnitude( int a ); /* ANSI and some pre-ANSI */
int magnitude( int ); /* ANSI and some pre-ANSI */
magnitude(); /* some pre-ANSI */
int magnitude(); /* some pre-ANSI */
When 'extern' was added to the pre-ANSI compilers, you could prefix the above with 'extern', too.
Of course, you have to decide what your teacher is looking for. One thing is certain, your teacher isn't expecting anyone in class with experience going back into the 1970's using early AT&T C compilers under Unix.
Now, your question says "declaration" not "definition." So the teacher isn't looking for pre-ANSI function definitions, I'd suppose. If you are curious, a pre-ANSI function definition often for the above might look like:
int magnitude( a )
int a;
{
/* ... some code goes here ... */
}
or,
magnitude( a )
int a;
{
/* ... some code goes here ... */
}
But that's a definition, not a declaration. If your teacher wanted one of those, the teacher should have said 'definition.'
Skipping (3) and (4)....
(5) The calling routine passes values to the called routine. Any expression is competent for creating a 'value' to pass and the caller can compute it before it is passed as a value to the called routine. Of course, this assumes that the called routine is looking for pass-by-value. Since an expression isn't an l-value, it's not possible (or shouldn't be) to pass the result of an expression to a function expecting a pointer. So not all expressions can be passed to all types of parameters. The called routine expects to have a "name" that represents the value passed. An expression wouldn't make much sense there.
(6) A pointer variable is a typed name (used at compile time only) and a run-time instance of memory necessary to hold a physical representation of a memory address of the appropriate type. They are used for arrays, matrices, function pointers, as well as for allowing functions to modify values in the calling routine.
(7)
int * size;
(8)
float * water_temperature;