Page 100 - Programming Microcontrollers in C
P. 100
Multidimensional Arrays 85
states that array_ptr is a pointer to an array of char. The declaration
char* array[];
states that array is an array of pointers to the type char. Although
you will rarely find it used, these declarations can be combined to
create very complicated declarations.
One construct from the general area of complicated declarations is
so important to microcontroller code that it must be covered. C sup
ports variable types called lvalues. As mentioned earlier, an lvalue
is a type of variable that can be the destination for an assignment. Most
variables in C are lvalues. Notable exceptions are function names
and array names. If a program deals with a number that can be a memory
address, it can be made accessible to the language by casting the ad
dress to an appropriate type. For example, suppose that a special table
is located at the address 0x1000 in memory. Further, suppose that the
type to be stored at that address is an integer. Here, the code sequence
(int *) 0x1000
forces the number 0x1000 to be a pointer to a type int. Often this
idea must be carried further, and the programmer wants to put a value
into a specific address. The above representation is a pointer to the
type int. Therefore, a value can be assigned to that int by
*(int *) 0x1000 = integer_value;
which will place integer_value into the location 0x1000 in the
computer memory.
Frequently, control registers, data registers, and input/output port
registers are placed at specific locations in memory. These register
locations can be converted to tractable C names by use of the #de
fine macro capability of C. Suppose that an I/O port is located at
the address.
#define PORTA (*(char *) 0x1000)
allows the use of the name PORTA in the computer program. I define
PORTA as a pseudo-variable. It is created by a macro expansion and
such things are usually constants or function-like expansions. The
above is neither. PORTA can be assigned to, or its value read. You
can even do operations like