Оператор цикла с постусловием
Оператор цикла с постусловием (анализ конца цикла производится после выполнения операторов тела цикла) используется, когда количество повторений операторов тела цикла заранее не известно и определяется в процессе выполнения цикла.
Синтаксис оператора:
do
оператор
while (выражение);
где
выражение – выражение любого типа;
оператор - простой или составной оператор тела цикла.
Тело цикла выполняется хотя бы один раз. После каждого выполнения тела цикла анализируется значение выражения: если оно истинно, то тело цикла выполняется снова, и снова вычисляется значение выражения; если ложно - цикл завершается.
Например:
do
{y=x-5;
x - -}
while (x>0);
МАССИВЫ В ЯЗЫКЕ СИ
Массив – это совокупность однотипных элементов, занимающих непрерывную область памяти.Элементы массива образуют последовательность, упорядоченную по номерам их элементов. С массивом связаны следующие его свойства: имя, тип, размерность.
Синтаксис объявления массива:
тип_элементов имя_массива [константное_выражение];
где
константное выражение определяет размер массива, т.е количество элементов массива. Например:
1) int a[10];
объявлен одномерный массив с именем a, содержащий 10 элементов целого типа.
2) float b[3][3]
объявлен двумерный массив b, состоящий из 3 строк и 3 столбцов, т.е.
из 9 элементов вещественного типа.
В отличие от языка Паскаль в языке Си нельзя определять произвольные диапазоны для индексов. Размер массива, указанный в объявлении, всегда на единицу больше максимального значения индекса.
Для обращения к элементам массива используется имя массива, после которого в квадратных скобках стоит индекс в виде выражения определяющего значение индекса - порядкового номера элементов массива. Индексов в квадратных скобках может быть столько, сколько измерений в массиве. Каждый индекс указывается в своих скобках. Значения индекса должны лежать в диапазоне от 0 до величины на единицу меньшей, чем размер массива указанный при его объявлении.
Например: a[0], а[1], а[2], а[3], а[4], а[5], а[6], а[7], а[8], а[9].
b[0][0], b[0][1], …, b[3][3]
В памяти элементы массива располагаются так, что при переходе от элемента к элементу наиболее быстро меняется самый правый индекс массива. Т.е. матрица располагается в памяти по строкам. Между элементами массива в памяти разрывыф отсутствуют. Операций над массивами в Си нет. Пересылка элементов одного массива в другой может быть реализована только поэлементно, с помощью цикла. Над элементами массива допускаются те же операции, что и над скалярными переменными того же типа. Форматный ввод-вывод значений элементов массива можно производить только поэлементно.
Пример 1. Ввод с клавиатуры и вывод на экран одномерного массива.
while(1)//открытие беск.цикла для проверки размерности
{
printf("Ведите размерность вектора:");
scanf("%d",&r);
if((r>0)&&(r<=R)) break;
printf("Размерность вне диапазона,повторите ввод\n");
} //закрытие беск.цикла для проверки размерности
printf("\n\t Введите вектор\n");// ввод вектора
for(i=0;i<r;i++)
{
printf("a[%d]=>",i);
scanf("%f",&a[i]);
} //конец ввода вектора
printf("\n\t Исходный вектор \n");//вывод вектора
for(i=0;i<r;i++)
printf("%5.2f",a[i]);
printf("\n");//конец вывода вектора
Пример 2. Ввод с клавиатуры и вывод на экран двумерного массива.
while(1)
{
printf("Введите размерность матрицы по строкам:");
scanf("%d",&ri);
if ((ri>0)&&(ri<=R)) break;
printf("Размерность вне диапазона, повторите ввод\n");
}
while(1)
{
printf("Введите размерность матрицы по столбцам:");
scanf("%d",&rj);
if ((rj>0)&&(rj<=R)) break;
printf("Размерность вне диапазона, повторите ввод\n");
}
printf("\n\t Введите матрицу\n");
for(i=0;i<ri;i++)
for(j=0;j<rj;j++)
{
printf("a[%d][%d]=> ",i,j);
scanf("%f",&a[i][j]);
}
printf("\n\t Исходная матрица \n");
for(i=0;i<ri;i++)
{
for(j=0;j<rj;j++)
printf("%5.2f ",a[i][j]);
printf("\n");
}
При объявлении массива можно указывать инициализацию массива, т.е присвоить значение каждому элементу массива.
Например:
float a[5] = {1, 0.5, 3, 2.1, 6};
int b[2][2] = {1,2,3,4}
int m[6] = {5, 3, 2}; - будет создан массив из шести элементов. Первые три элемента получат инициализированные значения. Значения остальных будут либо неопределенными, либо разны нулю, если массив внешний или статический.
Размер массива может не указываться, если при объявлении производится инициализация значений элементов.
Например: int p[] = {2, 4, 6, 10, 1};
Строки (СИМВОЛЬНЫЕ МАССИВЫ)
В языке Си нет специально определенного строкового типа данных (как в Паскале). Символьные строки организуются, как массивы символов, т.о. на длину строки в Си нет ограничения. В этом состоит их важное преимущество перед строками в Паскале, где размер строки не может превышать 255.
Каждый символ строки хранится в отдельном байте ОП. В конце каждой строки компилятор помещает нулевой символ \0 (null – в явном виде он не отображается), поэтому каждая строка занимает на 1 байт ОП больше, чем символы в строке. По этой же причине строка, содержащая один символ, не совпадает с символьной константой.
Строка– это последовательность символов, заключенных в кавычки. Строка может содержать любые символы алфавита, кроме кавычек, символа \ и символа конца строки \n (переход на новую строку). Для размещения в строке данных символов необходимо перед ними разместить символ \ .
Например: “Он сказал: \”Привет!\””
Каждая строковая константа, даже если она идентична другой строковой константе, сохраняется в отдельном месте памяти.
Если две строковые константы записаны одна за другой, то во время компиляции компилятор объединяет их:
“Hello, “, “Friends” => “Hello, Friends”
Такой механизм предоставляет удобное средство для записи длинных строковых констант.
Строка описывается, как символьный массив.
Синтаксис описания:
char имя строки [максимальный размер];
например: char str[20];
Одновременно с описанием строка может инициализироваться. Возможны два способа инициализации строки:
1) с помощью строковой константы (последовательности символов, заключенной в кавычки):
При таком способе инициализации в конце строки компилятор сам ставит символ \0.
char s[10] = “строка”; - начальное значение задавать необязательно
под строку s будет выделено 10 байт памяти, из них первые 7 получат значения при инициализации (седьмой – нулевой символ).
char s[] = ”строка”; -начальное значение обязательно
будет сформирована строка s из 7 символов.
2) в виде списка символов (элементов массива):
char s[10] = {‘c’,‘т’,’р’,’о’,’к’,’а’,‘\0’}; -описание равнозначно первому.
Символьный массив можно определить без нулевого символа в конце:
char s[10] = {‘c’,‘т’,’р’,’о’,’к’,’а’};
но это приведет к проблемам с обработкой такой строки, так как будет отсутствовать ориентир на ее окончание.
Отдельные символы строки идентифицируются индексированными именами, например: s[0]=’c’, s[5]=’a’
Инициализация двумерного символьного массива строками:
char b[4][30]=Тексты в кавычках эквивалентны
{скобочной записи:
“Результаты сессии”,{{…},{…},…};
“_________________”,
“ ФИО | Оценки “,
“ ________________”
};
Ввод-вывод символьных строк
Прототипы функций находятся в библиотеке стандартного ввода-вывода stdio.h.
gets(); Аргументом функций указывается имя строки. | чтение строки, введенной с клавиатуры Функция gets() читает строку из стандартного потока ввода stdin (высокоуровневый ввод-вывод) и помещает её по адресу, задаваемому параметром функции. Ввод строки заканчивается при обнаружении символа новой строки \n, который заменяется на нулевой символ \0. |
puts(); Аргументом функций указывается имя строки. | вывод строки на экран Функцияputs() записывает строку, адрес которой определяется значением параметра в круглых скобках, в стандартный поток вывода stdout. При выводе, завершающий \0 заменяется символом новой строки, то есть после вывода строки на экран курсор переходит в начало следующей строки. |
getchar(); getc(); | ввод одного символа с клавиатуры Например: ch = getchar (); присваивание переменной символьного типа ch очередного символа, полученного из стандартного ввода. |
putchar(); putc(); | вывод одного символа на экран Например: putchar (ch); выводит символ ch на экран. |
getch(); | ввод одного символа с клавиатуры без отображения его на экране |
Пример: Ввести с клавиатуры строку символов и вывести ее на печать.
1 способ. | 2 способ. |
# include <stdio.h> void main() { char str[100]; printf("Введите строку:\n"); gets(str); printf("Введенная строка\n "); puts(str); } | # include <stdio.h> void main() { char str[100]; printf("Введите строку:\n"); scanf("%s", &str); printf("Введенная строка\n "); printf("%s\n", str); } |
Ввод и вывод строки можно оформить в цикле:
3 способ. | 4 способ. |
# include <stdio.h> void main() { char str[100]; int i; printf("Введите строку:\n"); for(i=0; i<10; i++) str[i]=getchar(); printf("Введенная строка\n "); for(i=0; i<10; i++) putсhar(str[i]); } | # include <stdio.h> void main() { char str[100]; int i; printf("Введите строку:\n"); for(i=0; i<10; i++) scanf(“%c”, &str[i]); printf("Введенная строка\n "); for(i=0; i<10; i++) printf(“%c”, str[i]); } |
ОБРАБОТКА СТРОК
Обработка строк обычно связана с перебором всех символов от начала до конца. Признаком конца такого перебора является обнаружение нулевого символа.
При манипулировании со строками система не контролирует выход фактической длины строки за пределы максимально допустимого размера, задаваемого при описании. В случае ошибки дополнительные символы будут записаны поверх информации, которая располагается вслед за полем, отведенном для строки.
Для избегания ошибки рекомендуется следить за выходом строки за предусмотренные пределы, вводя достаточные размеры строк при их описании.
Для использования функций обработки строк необходимо подключить в программе библиотеку string.h (и stdlib.h).
Функция | Назначение | Тип возвращаемого результата |
strlen(str); | Определение длины строки str (завершающий символ \0 не учитывается). | int |
strrev(str); | Инвертирование (реверс, переворот) строки str. | сhar |
strlwr(str); | Преобразование букв верхнего регистра в строке в соответствующие буквы нижнего регистра (строчные). Только латинские буквы. | char |
strupr(str); | Преобразование букв нижнего регистра в строке в соответствующие буквы верхнего регистра (прописные). Только латинские буквы. | char |
strcat(str1, str2); | Присоединение строки str2 к строке str1 (объединение, конкатенация). Результат - сцепленная строка str1. | сhar |
strncat(str, str2, k); | Добавление к строке str1 k начальных символов из строки str2. | char |
strcmp(str1, str2); | Сравнение строк str1 и str2. Возвращаемое значение меньше нуля, если str1<str2; больше нуля, если str1>str2; равно нулю, если строки равны, т.е. совпадают по текущей, а не по объявленной длине и содержат одни и те же символы. Если длины строк равны, то происходит поэлементное сравнение символов до первого несовпадающего символа, и, та строка считается большей, в которой первый несовпадающий символ имеет наибольший код. | int |
strncmp(str1, str2, k); | Сравнение первых k символов строк str1 и str2. | int |
strcpy(str1,str2); | Копирование строки str2 (включая \0 символ) в строку str1. Результатом является строка str1. | char |
strncpy(str1, str2, k); | Копированиев начало строки str1k первых символовиз строки str2. | char |