- •Введение
- •Блок-схема алгоритма
- •Общие требования к блок-схеме алгоритма
- •Линейные и разветвляющиеся процессы
- •Циклические процессы
- •Итерационные процессы
- •Основные понятия языка С(С++)
- •Комментарии
- •Типы данных
- •Данные целого типа
- •Данные вещественного типа
- •Модификатор const
- •Переменные перечисляемого типа
- •Константы
- •Структура программы на языке С(С++)
- •Операции и выражения
- •sizeof
- •Операция присваивания
- •Арифметические операции
- •Операции поразрядной арифметики
- •Логические операции
- •Операции отношения
- •Инкрементные и декрементные операции
- •Операция sizeof
- •Порядок выполнения операций
- •Приоритет операций
- •Преобразование типов
- •Операция приведения
- •Операция запятая
- •Ввод и вывод информации
- •Директивы препроцессора
- •Директива #include
- •Директива #define
- •Операторы языка С(С++)
- •Понятие пустого и составного операторов
- •Операторы организации цикла
- •Оператор цикла for
- •Оператор цикла while
- •Оператор цикла do … while
- •Вложенные циклы
- •Примеры программ
- •Массивы
- •Одномерные массивы
- •Примеры программ
- •Многомерные массивы (матрицы)
- •Примеры программ
- •Указатели
- •Понятие указателя
- •Описание указателей
- •Операции с указателями
- •Связь между указателями и массивами
- •Массивы указателей
- •Многоуровневые указатели
- •Примеры программ
- •Символьные строки
- •Ввод/вывод строк.
- •Функции работы со строками.
- •Примеры программ
- •Функции
- •Прототип функции.
- •Определение функции.
- •Параметры функции
- •Передача массива в функцию
- •inline функции
- •Класс памяти
- •Автоматические переменные
- •Статические переменные
- •Регистровые переменные
- •Блочная структура
- •Примеры программ
- •Указатели на функции
- •Примеры программ
- •Рекурсия
- •Примеры программ
- •Аргументы в командной строке
- •Функции с переменным числом параметров
- •Вершина стека
- •Примеры программ
- •Сортировка
- •Пузырьковая сортировка.
- •Шейкер сортировка
- •Сортировка вставкой
- •Сортировка выбором
- •Метод Шелла
- •Метод Хора
- •Структуры
- •Указатели на структуры.
- •Структуры и функции
- •Примеры программ
- •Поля бит
- •Объединения
- •Переменные с изменяемой структурой
- •Организация списков и их обработка
- •Операции со списками при связном хранении
- •Стек
- •Построение обратной польской записи
- •Односвязный линейный список, очередь
- •Двусвязный линейный список
- •Циклический список, кольцо
- •Двусвязный циклический список
- •Примеры программ
- •Деревья
- •Файлы
- •Примеры программ
- •Литература
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);
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;