In C, the most appropriate model of a variable that the programmer should adopt is one that very closely follows what is going on in the hardware. Later generation languages idealize a variable in order to give a programmer an advantage over the bare silicon, or to enforce safety mechanisms. C was designed for writing operating systems, and operating systems are designed for dealing with the hardware. Such idealizations are contrary to the purpose of C.
The three properties of a variable are its type, scope, and lifetime. Variables also have names, but the names are inconsequential. A running C program no longer knows the names of the variables, unless the symbol table has been retained. The compiler arranges the variables into memory, and then refers to the variable by its numerical address in memory.
The type of a variable determines the interpretation of the memory location or locations at the address of the variable. The coercion notation can force the compiler to interpret the same piece of memory in different ways. This is a strength of C, allowing variables to be manipulated in any way desired; although all caution is with the programmer to do this properly.
The scope of a variable is the text region in the code in which the variable is known. This takes into account that different variables can have the same name. The scope will determine to which variable the name refers. In traditional C, the scope of a variable is delimited by a block, or the entire file (block scope versus file scope). Newer C standards allow a variable to be introduced in the middle of a block. This complicates things, and has no real advantage. A programmer must always know the type, scope and lifetime of every variable, and the more complication in keeping track of these properties, the greater the possibility of error.
The lifetime of a variable is the time period during the of the program that the variable exists. Scope is entirely a compile-time property, and lifetime is an entirely run-time property. The lifetime of named variables is that of the run of the procedure in which the variable is somewhere declared. Local variables are created when the procedure is entered and destroyed when the procedure returns. Static variables and variables in file scope have more extensive lifetimes. They can persist outside of the procedure in which they were declared.
A programmer must always know the type, scope and lifetime of every variable. These properties are as important as the variable's purpose. In fact, from the type, scope and lifetime of a variable, the variable's purpose can often be inferred; but given a variable's purpose, it still must decided where the variable will be used (scope), when it will be used (lifetime), and how it will be used (type).