To address the question you've posted in several comments(which I think you should edit into your post):
What I don't understand is how does the computer know lets when it reads a variable's value from and address such as 10001 if is an int or char. Imagine I click on a program called anyprog.exe. Immediately the code starts executing. Does this exe file include information about if the variables are stored as in or char?
So lets put some code to it. Let's say you write:
int x = 4;
And let's assume that it gets stored in RAM:
The first part being the address, the second part being the value. When your program(which executes as machine code) runs, all it sees at
0x00010004 is the value
0x000000004. It doesn't 'know' the type of this data, and it doesn't know how it is 'supposed' to be used.
So, how does your program figure out the right thing to do? Consider this code:
int x = 4;
x = x + 5;
We have a read and a write here. When your program reads
x from memory, it finds
0x00000004 there. And your program knows to add
0x00000005 to it. And the reason your program 'knows' this is a valid operation, is because the compiler ensures that the operation is valid through type-safety. Your compiler has already verified that you can add
5 together. So when your binary code runs(the exe), it doesn't have to make that verification. It just executes each step blindly, assuming everything is OK(bad things happen when they are in fact, not OK).
Another way to think of it is like this. I give you this information:
Same format as before - address on the left, value on the right. What type is the value? At this point, you know just as much information about that value as your computer does when it's executing code. If I told you to add 12743 to that value, you could do it. You have no idea what the repercussions of that operation will be on the whole system, but adding two numbers is something you're really good at, so you could do it. Does that make the value an
int? Not necessarily - All you see is two 32-bit values and the addition operator.
Perhaps some of the confusion is then getting the data back out. If we have:
char A = 'a';
How does the computer know to display
a in the console? Well, there are a lot of steps to that. The first is to go to
As location in memory and read it:
The hex value for
a in ASCII is 0x61, so the above might be something you'd see in memory. So now our machine code knows the integer value. How does it know to turn the integer value into a character to display it? Simply put, the compiler made sure to put in all of the necessary steps to make that transition. But your computer itself(or the program/exe) has no idea what the type of that data is. That 32-bit value could be anything -
char, half of a
double, a pointer, part of an array, part of a
string, part of an instruction, etc.
Here's a brief interaction your program (exe) might have with the computer/operating system.
Program: I want to start up. I need 20 MB of memory.
Operating System: finds 20 free MB of memory that aren't in use and hands them over
(The important note is that this could return any 20 free MB of memory, they don't even have to be contiguous. At this point, the program can now operate within the memory it has without talking to the OS)
Program: I'm going to assume that the first spot in memory is a 32-bit integer variable
(The compiler makes sure that accesses to other variables will never touch this spot in memory. There's nothing on the system that says the first byte is variable
x, or that variable
x is an integer. An analogy: you have a bag. You tell people that you will only put yellow colored balls in this bag. When someone later pulls something out of the bag, then it would be shocking that they would pull out something blue or a cube - something has gone horribly wrong. The same goes for computers: your program is now assuming the first memory spot is variable x and that it is an integer. If something else is ever written over this byte of memory or it's assumed to be something else - something horrible has happened. The compiler ensures these kinds of things don't happen)
Program: I will now write
2 to the first four bytes where I'm assuming
x is at.
Program: I want to add 5 to
Reads the value of X into a temporary register
Adds 5 to the temporary register
Stores the value of the temporary register back into the first byte, which is still assumed to be
Program: I'm going to assume the next available byte is the char variable
Program: I will write
a to variable
Program: I want to display the contents of
Reads the value in the second memory spot
Uses a library to convert from the byte to a character
Uses graphics libraries to alter the console screen(setting pixels from black to white, scrolling one line, etc)
(And it goes on from here)
What you're probably getting hung up on is - what happens when the first spot in memory is no longer
x? or the second is no longer
y? What happens when someone reads
x as a
y as a pointer? In short, bad things happen. Some of these things have well-defined behavior, and some have undefined behavior. Undefined behavior is exactly that - anything can happen, from nothing at all, to crashing the program or the operating system. Even well-defined behavior can be malicious. If I can change
x to a pointer to my program, and get your program to use it as a pointer, then I can get your program to start executing my program - which is exactly what hackers do. The compiler is there to help make sure we don't use
int x as a
string, and things of that nature. The machine code itself is not aware of types, and it will only do what the instructions tell it to do. There is also a large amount of information that's discovered at run-time: which bytes of memory is the program allowed to use? Does
x start at the first byte or the 12th?
But you can imagine how horrible it would be to actually write programs like this(and you can, in the assembly language). You start off by 'declaring' your variables - you tell yourself that byte 1 is
x, byte 2 is
y, and as you write each line of code, loading and storing registers, you (as a human) have to remember which one is
x and which one is
y, because the system has no idea. And you (as a human) have to remember what types
y are, because again - the system has no idea.