static randx = 1;
rand( )
{
Немного позже мы приведем пример, в котором будет необходим этот тип переменной.

РИС. 10.1. Внешние и внешние статические переменные.
Обычно переменные хранятся в памяти машины. К счастью, регистровые переменные запоминаются в регистрах центрального процессора, где доступ к ним и работа с ними выполняются гораздо быстрее, чем в памяти. В остальном регистровые переменные аналогичны автоматическим переменным. Они создаются следующим образом:
main( )
{
register int quick;
Мы сказали "к счастью", потому что описание переменной как регистровой, является скорее просьбой, чем обычным делом. Компилятор должен сравнить ваши требования с количеством доступных регистров, поэтому вы можете и не получить то, что хотите. В этом случае переменная становится простой автоматической переменной.
Какой класс памяти применять?
Ответ на вопрос почти всегда один - "автоматический". В конце концов почему этот класс памяти выбран по умолчанию? Мы знаем, что на первый взгляд использование внешних переменных очень соблазнительно. Опишите все ваши переменные как внешние, и у вас никогда не будет забот при использовании аргументов и указателей для связи между функциями в прямом и обратном направлениях. К сожалению, у вас возникнет проблема с функцией С, коварно изменяющей переменные в функции А, а это совсем не входит в паши интересы. Неоспоримый совокупный опыт использования машин, накопленный в течение многих лет, свидетельствует о том, что такая проблема значительно перевешивает кажущуюся привлекательность широкого использования внешних переменных.
Одно из золотых правил защитного программирования заключается в соблюдении принципа "необходимо знать только то, что нужно". Организуйте работу каждой функции автономно, насколько это возможно, и используйте глобальные переменные только тогда, когда это действительно необходимо.
Иногда полезны и другие классы памяти. Но прежде чем их использовать, спросите себя, необходимо ли это.
I. Ключевые слова: auto, extern, static, register
II. Общие замечания:
Класс памяти определяет область действия переменной и продолжительность ее существования в памяти. Класс памяти устанавливается при описании переменной с соответствующим ключевым словом. Переменные, определенные вне функции, являются внешними и имеют глобальную область действия. Переменные, определенные внутри функции, являются автоматическими и локальными, если только не используются другие ключевые слова. Внешние переменные, определенные раньше функции, доступны ей, даже если не описаны внутри ее.
III. Свойства
КЛАСС ПАМЯТИ |
КЛЮЧЕВОЕ СЛОВО |
ПРОДОЛЖИТЕЛЬНОСТЬ СУЩЕСТВОВАНИЯ |
ОБЛАСТЬ ДЕЙСТВИЯ |
Автоматический |
auto |
Временно |
Локальная |
Регистровый |
register |
Временно |
Локальная |
Статический |
static |
Постоянно |
Локальная |
Внешний |
extern |
Постоянно |
Глобальная (все файлы) |
Внешний статический |
static |
Постоянно |
Глобальная (один файл) |
1. Разделим случайное число на 32768. В результате получим число х в диапазоне - 1 <= х < 1. (Мы должны превратить его в тип float, чтобы иметь десятичные дроби.)
2. Добавим 1. Наше новое число удовлетворяет отношению 0 < = х < 2.
3. Разделим на 2. Теперь имеем 0 <= х < 1.
4. Умножим на 6. Имеем 0 <= х < 6. (Близко к тому, что нужно, но 0 не является возможным значением.)
5. Прибавим 1: 1 <= х < 7. (Заметим, что эти числа все еще являются десятичными дробями.)
6. Преобразуем в целые числа. Теперь мы имеем целые в диапазоне от 1 до 6.
7. Для обобщения достаточно заменить значение 6 в п. 4 на число сторон.
Вот функция, которая выполняет эти действия:
/* электронное бросание костей */
#define SCALE 32768.0
rollem(sides) float sides;
{
float roll;
roll = ((float)rand( )/SCALE + 1.0) * sides/2.0 + 1.0;
return((int)roll);
}
Мы включили в программу два явных описания типа, чтобы показать, где выполняются преобразования типов. Обратимся к программе, которая использует эти средства:
/* многократное бросание кости */
main( )
{
int dice, count, roll, seed;
float sides;
printf(" Введите, пожалуйста, значение зерна. \n");
Читать дальше