Escolar Documentos
Profissional Documentos
Cultura Documentos
How can I declare an array with only one element and still access elements beyon
d the first element (in a valid fashion)?
There is a way to do this. Using structures.
struct mystruct {
intvalue;
int length;
char string[1];
};
Now, when allocating memory to the structure using malloc(), allocate more memor
y than what the structure would normally require!. This way, you can access beyo
nd string[0] (till the extra amount of memory you have allocated, ofcourse).
But remember, compilers which check for array bounds carefully might throw warni
ngs. Also, you need to have a length field in the structure to keep a count of h
ow big your one element array really is :).
A cleaner way of doing this is to have a pointer instead of the one element arra
y and allocate memory for it seperately after allocating memory for the structur
e.
struct mystruct {
intvalue;
char *string;// Need to allocate memory using malloc() after allocating memory for t
he strucure.
};
Is char a[3] = "abc"; legal?
It declares an array of size three, initialized with the three characters 'a', '
b', and 'c', without the usual terminating '\0' character. The array is therefor
e not a true C string and cannot be used with strcpy, printf %s, etc. But its le
gal.
What is the difference between enumeration variables and the preprocessor #defin
es?
Functionality
Enumerations#defines
u were accessing a hardware port at a fixed memory address and promised only to
read from it, then it would be declared to be const but not initialized.
* volatile tells the compiler that other programs will be modifying this variable in
addition to the program being compiled. For example, an I/O device might need w
rite directly into a program or data space. Meanwhile, the program itself may ne
ver directly access the memory area in question. In such a case, we would not wa
nt the compiler to optimize-out this data area that never seems to be used by th
e program, yet must exist for the program to function correctly in a larger cont
ext. It tells the compiler that the object is subject to sudden change for reaso
ns which cannot be predicted from a study of the program itself, and forces ever
y reference to such an object to be a genuine reference.
* const volatile - Both constant and volatile.
The "volatile" modifier
The volatile modifier is a directive to the compiler?s optimizer that operations
involving this variable should not be optimized in certain ways. There are two
special cases in which use of the volatile modifier is desirable. The first case
involves memory-mapped hardware (a device such as a graphics adaptor that appea
rs to the computer?s hardware as if it were part of the computer?s memory), and
the second involves shared memory (memory used by two or more programs running s
imultaneously). Most computers have a set of registers that can be accessed fast
er than the computer?s main memory. A good compiler will perform a kind of optim
ization called ?redundant load and store removal.? The compiler looks for places
in the code where it can either remove an instruction to load data from memory
because the value is already in a register, or remove an instruction to store da
ta to memory because the value can stay in a register until it is changed again
anyway.
If a variable is a pointer to something other than normal memory, such as memory
-mapped ports on a
peripheral, redundant load and store optimizations might be detrimental. For ins
tance, here?s a piece of code that might be used to time some operation:
time_t time_addition(volatile const struct timer *t, int a)
{
int n;
int x;
time_t then;
x = 0;
then = t->value;
for (n = 0; n < 1000; n++)
{
x = x + a;
}
return t->value - then;
}
In this code, the variable t->value is actually a hardware counter that is being
incremented as time passes. The function adds the value of a to x 1000 times, a
nd it returns the amount the timer was incremented by while the 1000 additions w
ere being performed. Without the volatile modifier, a clever optimizer might ass
ume that the value of t does not change during the execution of the function, be
cause there is no statement that explicitly changes it. In that case, there?s no
need to read it from memory a second time and subtract it, because the answer w
ill always be 0. The compiler might therefore ?optimize? the function by making
it always return 0. If a variable points to data in shared memory, you also don?
t want the compiler to perform redundant load and store optimizations. Shared me
mory is normally used to enable two programs to communicate with each other by h
aving one program store data in the shared portion of memory and the other progr
am read the same portion of memory. If the compiler optimizes away a load or sto
re of shared memory, communication between the two programs will be affected.
What does the typedef keyword do?