Шаг 33.
Microsoft Visual C++ 2010. Язык С/С++.
Создание и использование функций. Атрибут static

    На этом шаге мы рассмотрим особенности использования этого спецификатора.

    Наряду с внешними переменными существуют, как мы видели, локальные переменные. Локальные переменные объявлены в какой-либо функции или блоке и известны только там. При этом каждый раз при вхождении в функцию (блок) такие переменные получают значения, а при выходе эти значения теряются. Как же заставить переменные сохранять свои значения после выхода из функции (блока)? Такая проблема существует во множестве алгоритмов. Решить ее можно, объявив переменную с атрибутом 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 - освободить память.

    На следующем шаге мы рассмотрим рекурсивные функции.




Предыдущий шаг Содержание Следующий шаг