void main (void) {

starbar ('_'); // вызов функции

printf ("ПГУ");

printf ("им. ");

printf ("25 октября, 200");

starbar('#'); // вызов функции

}

void starbar (char x) { // определение функции

int count;

for (count=1; count<=65; count++)

putchar (x);

putchar ('\n');

}

Определение функции начинается с заголовка void starbar (char x) {

Переменная x - является формальным параметром. Это новая переменная и под нее должна быть выделена отдельная ячейка памяти. При вызове функции мы присваиваем формальному аргументу значение фактического аргумента.

starbar (‘-‘); x = '-';

Фактический аргумент может быть константой, переменной или сложным выражением.

Можно передавать в функцию несколько фактических аргументов, разделенных запятыми.

printnum (int i, int j) {

printf ("Первый аргумент %d, вторй аргумент %d\n", i, j);

}

Возвращение значения функцией

Создадим функцию определяющую максимальное из двух чисел. На входе в эту функцию будут передаваться два числа, а на выходе возвращаться одно, то которое больше. Для возврата используется ключевое слово return.

void main (void){

int a=5, b=10, c=15, d=-10;

int e, f;

e=max(a, b);

f=max(c, d);

}

int max (int i, int j) {

int y;

y=i>j? i:j;

return(y);

}

Оператор return прекращает работу функции и передает управление следующему оператору в вызывающей функции, даже если он не является последним оператором в функции. Количество операторов return не ограничено. Возвращаемое значение присваивается переменной по выходу из функции.

НЕ нашли? Не то? Что вы ищете?

Inline-функции

Перед определением функции может быть использован спецификатор inline для того, чтобы компилятор помещал код функции непосредственно в место вызова функции.

#include <stdio. h>

#include <conio. h>

#include <dos. h>

inline float Circle(float r) {

return 2*3.14*r;

};

void main(void)

{

float y;

y = Circle(2);

printf(“%.2f\n”,y);

}

Это увеличивает код программы, но ведет к увеличению быстродействия работы программы. Inline-функции не должны содержать сложные программные конструкции.

Значение формальных параметров функции по умолчанию

Формальный параметр может иметь значение по умолчанию. Все параметры, стоящие справа от него тоже должны иметь значения по умолчанию. Эти значения передаются в функцию, если при вызове данные параметры не указаны.

#include <stdio. h>

void noName1 (float x, int y, char z='b') {

printf("x = %0.1f y = %d, z = %d \n", x, y, (int)z);

}

void noName2 (float x, int y=16, char z='a') {

printf("x = %0.1f y = %d, z = %d \n", x, y, (int)z);

}

void noName3 (float x=1.3, int y=4, char z='c') {

printf("x = %0.1f y = %d, z = %d \n", x, y, (int)z);

}

void main(void) {

noName1(1.0,2);

noName2(100.0);

noName3();

}

Перегрузка функций

Имена функций могут быть перегружены в пределах одной области видимости. Компилятор отличает одну функцию от другой по сигнатуре. Сигнатура задается числом, порядком следования и типами ее параметров.

#include <stdio. h>

#include <string. h>

int noName (int first) {

return first*first;

}

int noName (unsigned first) {

return first*first;

}

char noName (char first) {

return first*first;

}

int noName (int first, char *second) {

return first*strlen(second);

}

float noName (float r) {

return r*r;

}

double noName (double r) {

return r*r;

}

void main(void) {

printf("%d\n", noName(4));

printf("%d\n", noName((unsigned)4));

printf("%c\n", noName('c'));

printf("%d\n", noName(4,"cлово"));

printf("%0.2f\n", noName((float)1.2));

printf("%0.2lf\n", noName((double)1.2));

}

11.  КЛАССЫ ПАМЯТИ И ОБЛАСТЬ ДЕЙСТВИЯ

До сих пор мы имели дело с локальными переменными, которые доступны только в одной функции. В данном случае переменные a, b в main() и myfunc() являются разными переменными.

void myfunc(int, int);

void main (void){

int a=5, b=10;

printf ("%d %d\n", a, b);

myfun (a, b);

printf ("%d %d\n", a, b);

}

void myfun (int a, int b){

a++; b++;

printf ("%d %d\n", a, b);

}

Каждая существует только в своей функции и доступна только в ней. Физически это разные ячейки памяти. Такие переменные называются "локальными". Но иногда требуются переменные доступные из любой функции и даже модуля программы. Такие переменные называются "глобальными".

Каждая переменная в Си принадлежит некоторому классу памяти. Всего существует 5 классов памяти. Для их описания используются ключевые слова:

extern - внешний,

auto - автоматический,

static - статический

register - регистровые.

Глобальные переменные

1.  Класс Extern - внешние переменные.

Хранятся в области данных программы. Определяются до main() и доступны в любой функции программы. Время жизни - программа. При определении инициализируются по умолчанию 0 на стадии компиляции. Область видимости вся программа.

int count;

void main (void){

count ++;

.........

}

fun (){

printf ("%d\n", count);

}

Переменная count является внешней и доступна в обеих функциях.

Если в программе есть одноименная локальная переменная, она закрывает глобальную переменную. Для расширения видимости операция расширения доступа ::

int count;

void main (void){

int count; //автоматическая переменная

::count++;

..........

printf(“%d”,::count);

}

void fun (void){

count ++;

printf ("%d\n",count);

}

Если переменная определяется в одном модуле, но к ней есть обращение в другом, то нужно обязательно это указать, объявив ее как внешнюю, иначе будет создана новая переменная с этим именем.

I модуль. II модуль.

int cost; void func (void){

void main (void){ extern int cost;

............ ................

} }

2.  Статистические внешние переменные - static

Область видимости ограничена одним модулем. Доступны всем функциям в одном модуле. Время жизни работа всей программы. Инициализируются по умолчанию 0 на стадии компиляции. Создаются в области данных программы.

static int num;

void main (void){

int count;

for (count=1; count<5; count ++){

printf ("%d\n", count);

fun ();

}

}

void fun (void){

int i=1;

num ++;

printf ("%d %d\n", i, num);

}

Локальные переменные

3.  Внутренняя статическая переменная.

Ключевое слово static. Объявляется и определяется внутри одной функции, блока. Инициализируют 0 на стадии компиляции. Создаётся в области данных. Время жизни - работа всей программы, но область видимости только эта функция. При многократном вызове сохраняет своё значение. Инициализирует только 1 раз.

void main (void){

int count;

for (count=1; count<5; count ++){

printf ("%d\n", count);

fun ();

}

}

void fun (void){

static int num;

int i=1;

printf ("%d %d\n", i, num++);

}

4.  Регистровая переменная.

Ключевое слово register int i. Помещаются в регистры микропроцессора для увеличения скорости вычисления. Если нет свободного регистра, рассматриваются как автоматические. Область видимости блок, в котором были определены. По умолчанию не инициализируются.

5.  Автоматические переменные

Ключевое слово auto. Определяются внутри любого блока. Время жизни работа блока. Создаются в области стека. Область видимости блок, в котором были определены. По умолчанию не инициализируются.

Пример 1.

if (i==1){

int j=0;

int k=1;

i++;

}

printf(“%d %d”,j, k); //сообщение об ошибке

Пример 2.

int i;

......

{

int i; Внешнее i не видимо

......

}

...... Здесь опять ее видно

Существуют понятия: область видимости и область существования. Область видимости не может выходить за область существования, но область существования может превышать область видимости.

Таблица 1. Классы памяти и инициализация

Класс

Хранения

Внешний

Extern

Внешний

Статический static

Аргумен. Функции

Автоматические auto

Регистровые

Register

Внурен. Статические

Static

Область действия

Программа

Модуль

Функция

Блок

Блок

Блок

Время

Жизни

Программа

Программа

Функция

Блок

Блок

Программа

Область

Хранения

Сегмент

Данных

Сегмент данных

Сегмент стека

Сегмент стека

Регистры МП

Сегмент данных

Инициал-емость объектов

Все

Все

Не раз-решена в Си

Все в С++

Все

Все

Момент инициализации

На стадии

Компил.

На стадии компил.

При входе в блок

При входе в блок

При входе в блок

На стадии компил.

Инициализация по умолчан.

Инициализируются 0

Инициализируются 0

Значение указывается

Значение не опред.

Значение не опред.

Инициализируется 0

12.  ПРЕПРОЦЕССОР ЯЗЫКА СИ

Компиляция выполняет еще один шаг перед собственно компиляцией исходного файла, называемый предварительно обработкой. Препроцессор просматривает программу и заменяет символьные аббревиатуры в программе на соответствующие директивы. Он расширяет возможности языка 3 функциями.

1.  Подстановкой имен;

2.  Включением файлов;

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12