Chris Bradshaw said:
I have been reading in my c book something about how C references
memory addresses but it's a little bit tricky.
It helps to know what book this is. For one thing, some people will be
able to follow along.
so for example if I have
int num;
and the address of num is 100 then the compiler would treat that
variable internally as (int *)100 so
an address &num IS the same as (int *)100.
So the compiler treats the statement int num = 3; as *(int *)100 = 3
right?
That's one way to start looking at these things, but it does not suit
every situation, so it may be a case of an author trying to be helpful
but missing the mark. I'd only stick with this view of things as far as
you find it helpful but bear in mind that it very often fails.
For example, the compiler may put a variable in a register or it may
simply not know the address to be used at the time the code is
generated. At some point (if you want a rounded education in this area)
you'll have to start considering these things.
But why do I need a pointer type and not for example (int)100 or
unsigned int(100)?
(int)100 means the same as 100 -- the cast of an integer constant to int
type does nothing. int(100) is a syntax error. If it is not treated as
one by your compiler then you are probably using C++ by accident.
What this means is that I can't answer your question. You must think
that (int)100 or int(100) mean something other than what they do mean so
unless I can guess what that is, I am stumped.
I prefer to think of variables as named boxes -- boxes whose content can
be changed by assignment. This is powerful metaphor that can be
extended to many more advanced areas of the language. The notion that
num can be thought of as *(int *)100 will soon run into trouble. It
already has for you since it relies on a concept that you are not yet
comfortable with -- pointers.
Unfortunately this is not much help if the only book you have uses this
very idea that has got you puzzled. Can you mix and match and read some
other book at the same time?
Second question: we are told in this book to "check the return value of
all memory and I/O functions and handle failure conditions gracefully",
one example given being f_close().
(you mean fclose())
My quesiton is: apart from returning EOF -- where there is nothing the
programmer can do -- under what circumstances will fclose() fails?
Just to clarify: EOF is not a circumstance under which fclose fails.
fclose signals every failure (no matter what the circumstances where) by
returning EOF.
The most common reason for an fclose failure is that there was data that
had not yet made it to the file when something went seriously wrong.
Imagine a hammer hitting the device the file is on, or unplugging the
network/USB device/power cord at the critical moment. There can be lots
of other problems, but the exact nature of them hardly matters.
Books often contain advice like this and it really helps if they tell
you what you might do. Critical data might be saved to some other
device, for example, or the user might be asked to plug in some other
storage device. The trouble is that all of these rely on a much deeper
knowledge of the system than most C books are prepared to rely on. The
best you can do in general is to report the failure to the user of your
program (if there is one).