Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы_по_проге_Берлин / Книги / учебное пособие ОАиП.pdf
Скачиваний:
49
Добавлен:
11.02.2015
Размер:
947 Кб
Скачать

fun()

{ static int i; // статическая переменная

. . . // тело функции

}

Регистровые переменные

Спецификация register при объявлении переменных сообщает компилятору, что декларируемая переменная будет использоваться интенсивно. Такую переменную желательно размещать на одном из регистров машины. Это приведет к тому, что программа станет короче и работа ускорится. Пример декларации:

register int i,j; register char k;

При этом компилятор имеет право проигнорировать указание разместить данные переменные в регистре машины. Спецификация register может применяться только к арифметическим переменным и к формальным параметрам функции. Объявление для формальных параметров имеет вид

fun(register unsigned int n, register char c)

{register int k;

. . .

}

Ограниченное число регистров накладывает ограничение на число register–переменных: достаточно небольшое их число и при этом только определенных типов может быть размещено на регистрах. Избыточные register объявления игнорируются, а для переменной независимо от того выделен ей регистр или нет, не определено понятие адреса. Ограничение на количество и тип register–переменных зависят от типа процессора.

Блочная структура

Блочная структура программы принятая в других языках (Паскаль и др.) не допустима в С(С++) в том смысле, что функции не могут быть расположены одна внутри другой. Однако переменные внутри функций можно определять в блочно-структурной манере.

Декларации переменных (а также их инициализация) может быть размещена не только в начале функции, но и после любой левой фигурной скобки ({). Переменная, описанная таким способом, ”маскирует” одноименные переменные, расположенные вне блока, и действует до соответствующей правой фигурной скобки. Например:

{ float n;

. . .

for (i=0; i<max; i++)

{int n=mas[0]; for(j=i+1; j<max; j++) n+=mas[j];

}

{ char n;

. . .

}

}

Автоматические переменные, декларируемые и инициализируемые в блоке, инициализируются каждый раз при входе в блок. Переменные static инициализируются только один раз при первом входе в блок.

Автоматические переменные и формальные параметры ”затеняют” внешние переменные с теми же именами. Например:

int x, y;

//

x,y - внешние переменные

fun(float x)

//

x,y - автоматические переменные заменяют на

{ char y;

//

на время работы fun внешние переменные x и y

. . .

 

 

}

 

 

Примеры программ

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

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

#include<stdio.h>

#include<stdlib.h>

char *getstr(char *); // прототипы функций используемых в main get_str(char *, int );

int str_len(char *);

int str_cmp(char *,char *); char * str_cat(char *,char *,int); double atof(char *);

int atoi(char []); void itoa(int ,char *); main()

{char *s1,*s2; int n,n1,n2; double d; do

{fflush(stdin);

printf("введите размерность ПЕРВОЙ строки = "); } while(!scanf("%d",&n1) || n1<=0);

if (!(s1=(char *)calloc(n1,sizeof(char))))

{printf("\nНедостаточно свободной памяти \n"); return 0;

}

do

{clrscr();

fflush(stdin);

// преобразование int в строку s2

printf("введите размерность ВТОРОЙ строки = "); } while(!scanf("%d",&n2) || n2<=0);

if (!(s2=(char *)calloc(n2,sizeof(char))))

{printf("\nНедостаточно свободной памяти \n"); free(s1);

return 0;

}

printf("Вводите первую строку "); fflush(stdin);

printf("\n строка %s",getstr(s1));

// ввод и вывод первой строки

printf("\nДлина первой строки == %d байт",str_len(s1));

d=atof(s1);

// преобразование строки s1 в double

printf("\nЗначение числа (double) в строке %s == %lf \n",s1,d); printf("\nДлина второй строки == %d байт",get_str(s2,n2)); printf("\nЗначение числа (int) в строке %s == %d ",n,atoi(s2)); printf("\nВводите число для перевода в строку "); scanf("%d",&n);

itoa(n,s2);

printf("\n строка %s",s2);

if (str_cmp(s1,s2)>0) printf("\n строка 1 > строки 2"); else if (str_cmp(s1,s2)<0) printf("\n строка 1 < строки 2");

else printf("\n строка 1 = строке 2");

s1=str_cat(s1,s2,3);

// добавление строки s2 в строку s1

printf("\nстрока (s1+s2) == %s",s1);

 

}

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

char *getstr(char *s)

// функция ввода строки

{int i=0;

while((*(s+i++)=(char)getchar())!='\n'); // посимвольный ввод в строку

*(s+ --i)='\0';

// до нажатия клавиши Enter

return s;

// возврат указателя на строку

}

 

get_str(char *s, int k)

// ввод строки и подсчет ее длины

{int c,i=0;

//символы заносятся в буфер и после нажатия клавиши Enter

//k-1 символ из буфера переносятся в строку s

while(--k>0 && (c=getchar())!=EOF && c!='\n')

*(s+i++)=c;

// ввод строки до заданного кол-ва символов или

 

// пока не нажата клавиша Enter или Ctrl + Z

*(s+i)='\0';

// признак конца строки

return i;

// возврат длинны строки

}

int str_len(char *s) // функция определения длины строки

{for(int n=0; *(s+n); n++); return t;

}

int str_cmp(char *s1,char *s2)

// функция сравнения двух строк

{ while(*s1 && *s2)

// пока не достигнут конец одной из строк

if (*s1-*s2) return *s1-*s2;

// найдены различающиеся символы

else

//

{ s1++;

// переход к новому символу строк s1 и s2

s2++;

 

}

 

return 0;

// строки равны.

}

// Еще один вариант функции сравнения двух строк.

int str_cmp(char *s1,char *s2) // функция сравнения двух строк { for (;*s==*t; s++,t++)

if(!*s && !*t) return 0; return *s-*t;

}

// функция вставки (добавления) в строку s1 строки s2 с позиции k char * str_cat(char *s1,char *s2,int k)

{char *s; int i;

if (k>str_len(s1)) k=str_len(s1);

if (!(ss=(char *)malloc(sizeof(char)*(str_len(s1)+str_len(s2))))

{ printf("\nНедостаточно свободной памяти ");

return s1;

// возврат строки без изменения

}

 

for (i=0; i<k; i++)

// перезапись s1 в ss k символов

*(s+i)=*(s1+i);

 

for (i=0; *(s2+i); i++)

// дозапись s2 в ss srt_len символов

*(s+k+i)=*(s2+i);

 

for (i=0; *(s1+k+i); i++)

// дозапись остатка s1 в ss

*(s+k+str_len(s2)+i)=*(s1+k+i);

*(s+k+str_len(s2)+i)='\0';

 

free(s1);

 

return s

// строки полностью совпали

}

// функция перевода цифровой символьной строки в signed double double atof(char *ss)

{ double n, ii=0.0;