
- •2.2.Функции, возвращающие значение
- •Void main ()
- •Void Sum(float *s,float *X, int n)
- •Void main ()
- •Void Sumstmatr ( float (*mz)[m], float *mx, int n1, int m1); //прототип функции Sumstmatr
- •Void main ()
- •Void Sumstmatr (float (*mz)[m], float *mx, int n1, int m1)
- •Void main ()
- •Void main()
- •2.3. Функции обработки строк
- •Void strcpy ( char *s, char *t)
- •Void strcpy ( char *s, char *t)
- •Int strcmp ( char * s, char * t)
- •Unsigned strlen (const char *str );
- •Void strcpy (char *s,char *t);
- •Void main ()
- •Int Vs(char *s, char *sl, int d);
- •Int Vs(char *s,char *sl, int d) // функция формирования очередной строки
- •2.4. Рекурсивные функции
- •Void main()
- •3.Классы памяти и области действия описаний
- •Автоматические переменные
- •Внешние переменные
- •Void main ()
- •Void main ()
- •Int a[4]; // указано, что а – локальный массив целого типа
- •Void main ()
- •Статические переменные
- •Void f();
- •Void main ()
- •Void f()
- •Регистровые переменные
- •4.Элементы структурного программирования
- •4.1.Нисходящая разработка
- •4.2.Основные структуры, пошаговая детализация
- •Void main ()
- •Void main ()
- •Void Smog (long mz[][n2]);
- •Void main ()
- •Void Smog (long mz[][n2])
- •4.3.Сквозной структурный контроль
- •Элементы, которые должны проверяться на контрольных сессиях
Автоматические переменные
До сих пор мы не обращали внимания на классы памяти, так как переменные, описанные внутри функции, по умолчанию являются автоматическими. Можно, однако, это подчеркнуть явно с помощью ключевого слова auto:
main ( ) { auto int x; …
Автоматические переменные имеют локальную область действия. Только функция, в которой переменная определена, «знает ее». Другие функции могут использовать переменные с тем же самым именем, но это будут уже другие области памяти. Автоматическая переменная начинает существовать при вызове функции, содержащей ее. Когда функция завершает свою работу и возвращает управление туда, откуда ее вызвали, автоматическая переменная исчезает. Ячейка памяти может использоваться для чего–нибудь другого. Чтобы лучше понять сказанное, рассмотрим следующую программу:
# include <stdio.h>
# include <conio.h>
float f( );// прототип функции без параметров f()
main ( ) { auto int x, y; //локальные автоматические переменные функции
// main x = 5;
y = f( );
printf (“ x = %d y = %d из функции main \n”, x,y); }
float f( ) { int x; //локальная автоматическая переменная функции f x =10; printf (“x = %d из функции f \n”, x);
return x; //возвращаем х из функции f
}
При выполнении этой программы получим следующий результат:
x
= 5 y = 10 из функции
main
x
=10 из функции f
Иллюстрация процесса изменения доступности и занятости ячеек памяти при выполнении рассмотренной программы показано на рис.8.
На этом рисунке видно, что с момента начала выполнения функции main для переменнойх выделяется ячейка 1. Как только начинает выполняться функция f, для переменнойх этой функции выделяется ячейка 2. Ячейка 1 недоступна для функцииf, но эта ячейка не освобождается. При выполненииf доступна ячейка 2. Как только выполнение функцииf заканчивается, ячейка 2 освобождается и может заниматься, если понадобится другими переменными, а ячейка 1 снова становится доступна функцииmain.
Обратите также ваше внимание, на то, что в этом примере использована функция без параметров, что допускается транслятором Си.
Следует еще сказать об области действия автоматической переменной: область действия ограничена блоком ( { }), в котором переменная описана. Обычно областью действия переменных является вся функция. Однако возможно описать переменную в блоке, который является частью текста функции. Например:
main ( )
{ int y;
float s;
{ int i;
for ( i =0; i <5; i++)
s +=i; } ….
}
В этом примере область действия переменной i является блок:
{ int i;
for ( i =0; i <5; i++)
s +=i; }
Внешние переменные
Переменная, описанная вне функции, является внешней. Внешнюю переменную можно описать в функции при помощи ключевого словаextern. Рассмотрим следующую программу:
#include <stdio.h>
#include <conio.h>
int Sum();
int A[4] = {1,4,6,7};// A- массив, описанный вне функции
Void main ()
{ int s;
extern int A[4];// указано, что А– внешний массив целого типа
clrscr();
printf("sumA=%d \n", Sum() );
s = A[0] + A[1];
printf (“s = %d\n”, s);
getch();
}
int Sum()
{int i, ss;
extern int A[4]; // указано, что А – внешний массив целого типа
for (i = 0, ss = 0; i < 4; i++)
ss +=A[i];
return ss;
}
В этой программе массив А является внешним для функцииmain иSum. Дело в том, что весь представленный текст после включения прототипов стандартных функций (исполнения операторов #include) воспринимается как текст исходной программы, находящийся в одном файле. Эта программа состоит из функций (одна из них – главная, с которой начинается выполнение программы). Но, помимо функций, в этом тексте могут быть прототипы функций и описания и инициализация переменных (или просто описания), которые являются внешними переменными для всех функций этого программного файла или другого программного файла, скомпилированного и собранного одновременно с первым. Тот факт, функция использует внешнюю переменную, указывается объявлением с использованием служебного словаextern (extern int A[4];). Таким образом, в нашей программе в функцииSum иmain А – это один и тот же массив, а в результате выполнения нашей программы получим следующий результат:
SumA = 18 s = 5
Самое интересное, что если убрать в обеих функциях объявление extern int A[4];, то получим точно такой же результат! Дело в том, что если в какой – либо функции используется какая – либо переменная, не объявленная в ней, то она считается внешней переменной с атрибутами, объявленными вне этой функции. Но, если переменная используется, но нигде вне функции не описана, то это – ошибка! Правда, такая ошибка будет выловлена при трансляции. Гораздо хуже будет, если в какой – либо функции мы забудем указать атрибутextern, хотя сама переменная будет описана в ней. Например, напишем такую программу:
#include <stdio.h>
#include <conio.h>
int Sum();
int A[4] = {1,4,6,7};// A- массив, описанный вне функции