For a start, you don't close() a file that you opened with fopen(), you have to fclose() it. You're mixing two levels of abstraction here, file handles and file pointers.
On top of that, I think you'll find that the two file pointers are maintaining independent file offsets and buffers. Whichever one closes the file last will write their data last, overwriting the other.
Change the order of your fclose() statements and you should see what I mean:
#include<stdio.h>
int main (void) {
FILE *fp,*fs;
fs=fopen("c.dat","w");
fp=fopen("c.dat","w");
fputc('a',fp);
fputc('1',fs);
fclose(fp); // Try changing these
fclose(fs); // two around.
return 0;
}
I did that and consistently got the contents based on the last file closed.
And, before you say that you should have gotten a because fp was the last one you closed, you did not close fp (with an fclose()).
What you did do was try to close() a file handle that was almost certainly invalid, because file handles are generally relatively small values (e.g., 0, 1, 2) while file pointers are generally relatively large values (e.g., 0xdeadbeef, 0xcaf3f00d).
So the closure of both those files was left up to the C runtime environment when you exited (and that would most likely have done it in a deterministic way, which is why you always got the same value in the file).