На этом шаге мы рассмотрим особенности использования этого спецификатора.
Наряду с внешними переменными существуют, как мы видели, локальные переменные. Локальные переменные объявлены в какой-либо функции или блоке и известны только там. При этом каждый раз при вхождении в функцию (блок) такие переменные получают значения, а при выходе эти значения теряются. Как же заставить переменные сохранять свои значения после выхода из функции (блока)? Такая проблема существует во множестве алгоритмов. Решить ее можно, объявив переменную с атрибутом static.
Ниже приведен текст проверочной программы. Для простоты взята уже известная нам функция ввода строки с клавиатуры getline(), и в ее тело вставлено объявление статической переменной j, которой там же присваивается значение количества введенных символов i.
// AttrStatic.cpp: главный файл проекта. #include "stdafx.h" #include <stdio.h> #include <conio.h> #define eof -1 //CTRL+Z #define MAXLINE 100 using namespace System; //Ввод строки с клавиатуры //В следующую функцию вставлены "лишние" //операторы, чтобы продемонстрировать действие атрибута static int getline(char s[], int lim) { int c,i; static int j; for(i=0; i<lim-1 && (c=getchar()) != eof && c != '\n'; i++) s[i]=c; s[i]='\0'; i++; //для учета количества j=i; return i; } int main() { char s[MAXLINE]; for (int i=0; i < 3; i++) { getline(s, MAXLINE); static int b; b=i; } _getch(); return 0; }
В режиме Отладчика можно увидеть, что локальная переменная j сохраняет свое значение и после выхода из функции, и после нового входа в функцию.
В функцию getline() вставлены "лишние" операторы (static int j и j=i), чтооы продемонстрировать действие атрибута static.
Они не меняют функциональности getline(). Поставьте точку останова Отладчика на оператор j=i и в цикле работы getline() убедитесь, что переменная j сохраняет свое значение в других циклах запуска getline() (рисунки 1 и 2).
Рис.1. Переменная j при первом заходе в функцию имеет значение 0, а i - значение 6
Рис.2. При втором заходе переменная j сохранила предыдущее значение i
Для ввода можно использовать объявление char* s (об этой записи мы поговорим в следующих шагах). В этом случае перед обращением к функции ввода надо динамически выделить память операцией s= new char [MAXLINE], а в конце программы выполнить оператор delete [] s - освободить память.
На следующем шаге мы рассмотрим рекурсивные функции.