Static typed programming languages are those in which variables need not be defined before they’re used. This implies that static typing has to do with the explicit declaration (or initialization) of variables before they’re employed. Java is an example of a static typed language; C and C++ are also static typed languages. Note that in C (and C++ also), variables can be cast into other types, but they don’t get converted; you just read them assuming they are another type.
Static typing does not imply that you have to declare all the variables first, before you use them; variables maybe be initialized anywhere, but developers have to do so before they use those variables anywhere. Consider the following example:
/* C code */
static int num, sum; // explicit declaration
num = 5; // now use the variables
sum = 10;
sum = sum + num;
The above code fragment is an example of how variable declaration in static typed languages generally appears. Note that in the above code, static has nothing to do with static typing; it has been used along with int only to initialize num and sum to zero.
Dynamic typed programming languages are those languages in which variables must necessarily be defined before they are used. This implies that dynamic typed languages do not require the explicit declaration of the variables before they’re used. Python is an example of a dynamic typed programming language, and so is PHP. Consider the following example:
/* Python code */
num = 10 // directly using the variable
In the above code fragment, we have directly assigned the variable num the value 10 before initializing it. This is characteristic to dynamic typed programming languages.
A lot of people define static typing and dynamic typing with respect to the point at which the variable types are checked. Using this analogy, static typed languages are those in which type checking is done at compile-time, whereas dynamic typed languages are those in which type checking is done at run-time.
This analogy leads to the analogy we used above to define static and dynamic typing. I believe it is simpler to understand static and dynamic typing in terms of the need for the explicit declaration of variables, rather than as compile-time and run-time type checking.