- •Int a; /* целая
- •Int n; // Переменная n целого типа double a; // Переменная a вещественного типа двойной точности
- •Вещественные константы
- •Символьные константы
- •Строковые константы
- •Логические операции
- •Тернарные операции
- •Оператор ветвления switch
- •Параметрический цикл for
- •Тип *имя_объекта;
- •Стандартные функции динамического выделения памяти
- •Динамическое выделение памяти для одномерных массивов
- •Основные функции стандартной библиотеки string.H
- •Массивы структур
- •Идентификатор(аргумент1, ..., агрументn)
- •Функция, позволяющая вывести день недели на русском языке
- •Файловая структура fat32
- •Работа с файлами в языке Си
Параметрический цикл for
Общая форма записи
for (инициализация параметра; проверка условия окончания; коррекция параметра) {
блок операций;
}
for — параметрический цикл (цикл с фиксированным числом повторений). Для организации такого цикла необходимо осуществить три операции:
инициализация параметра - присваивание параметру цикла начального значения;
проверка условия окончания - сравнение величины параметра с некоторым граничным значением;
коррекция параметра - изменение значения параметра при каждом прохождении тела цикла.
Эти три операции записываются в скобках и разделяются точкой с запятой (;). Как правило, параметром цикла является целочисленная переменная. Инициализация параметра осуществляется только один раз — когда цикл for начинает выполняться. Проверка условия окончания осуществляется перед каждым возможным выполнением тела цикла. Когда выражение становится ложным (равным нулю), цикл завершается. Коррекция параметра осуществляется в конце каждого выполнения тела цикла. Параметр может как увеличиваться, так и уменьшаться.
Пример
#include <stdio.h> int main() {
int num;
for(num = 1; num < 5; num++)
printf("num = %d\n",num);
getchar();
return 0; }
Результат
работы программы
Можно опустить одно или несколько выражений, но нельзя опускать точку с запятой, разделяющие три составляющие цикла. Пример
#include <stdio.h> int main() {
int num = 1;
for(; num < 5; num++)
printf("num = %d\n",num);
getchar();
return 0; }
Параметры, находящиеся в выражениях в заголовке цикла можно изменить при выполнении операции в теле цикла. В цикле for может использоваться операция запятая (,) для разделения нескольких выражений. Это позволяет включить в спецификацию цикла несколько инициализирующих или корректирующих выражений. Выражения, к которым применяется операция запятая, будут вычисляться слева направо. Пример
#include <stdio.h> int main() {
int i,j;
for(i = 1, j=2; i < 5; i++, j=j+2)
printf("i = %d j = %d\n",i,j);
getchar();
return 0; }
Результат
работы программы
В
Си допускаются вложенные циклы, то есть
когда один цикл находится внутри другого:
for ( i=0; i<n; i++) { // цикл 1
for( j=0; j<n; j++) { // цикл 2
// блок операций цикла 2;
}
// блок операций цикла 1; }
Пример: Вывести числа от 0 до 99
#include <stdio.h> #include <stdlib.h> int main() {
unsigned int i,j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
printf("%2d ",i*10+j);
}
printf("\n"); // перевод строки
}
getchar();
return 0; }
Результат
выполнения
Рекомендации по выбору цикла
При выборе цикла необходимо оценить необходимость проверки yсловия при входе в цикл или по завершении прохождения цикла. Если цикл ориентирован на работу с параметром, который меняется в заданных пределах с заданным шагом, то более предпочтительным является параметрический цикл.
Операторы break и continue
В теле любого цикла можно использовать операторы break и continue. Оператор break позволяет выйти из цикла, не завершая его. Оператор continue позволяет пропустить часть операторов тела цикла и начать новую итерацию.
Пример: Вывести числа от 0 до 99 ниже главной диагонали
#include <stdio.h> #include <stdlib.h> int main() {
unsigned int i,j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
if(j>i)
break;
printf("%2d ",i*10+j);
}
printf("\n");
}
getchar();
return 0; }
Результат
выполнения программы
Пример:
Вывести числа от 0 до 99 исключая числа,
оканчивающиеся на 5 или 8
#include <stdio.h> #include <stdlib.h> int main() {
unsigned int i,j;
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
if((j==8) || (j==5)))
continue;
printf("%2d ",i*10+j);
}
printf("\n");
}
getchar();
return 0; }
Результат
выполнения
При вложенных циклах действия операторов break и continue распространяется только на самую внутреннюю структуру, в которой они содержатся.
Оператор безусловного перехода goto
Общая форма записи
goto метка; . . . метка : операция;
Выполнение оператора goto вызывает передачу управления в программе операции, помеченной меткой. По сути метка является идентификатором адреса операции, которой должно быть передано управление. Для отделения метки от оператора используется двоеточие (:). Метка может располагаться в программе как до оператора goto, так и после . Имена меток образуются по тем же правилам, что и имена переменных.
Пример
#include <stdio.h> int main() {
int k=5; M1: if(k<0)
goto M2;
printf("%d ",k);
k--;
goto M1; M2: getchar();
return 0; }
Результат
выполнения
Функции в языке Си
Главная > Язык Си > Функции в языке Си
Функция — это самостоятельная единица программы, которая спроектирована для реализации конкретной подзадачи. Функция является подпрограммой, которая может содержаться в основной программе, а может быть создана отдельно (в библиотеке). Каждая функция выполняет в программе определенные действия.
Сигнатура функции определяет правила использования функции. Обычно сигнатура представляет собой описание функции, включающее имя функции, перечень формальных параметров с их типами и тип возвращаемого значения.
Семантика функции определяет способ реализации функции. Обычно представляет собой тело функции.
Определение функции
Каждая функция в языке Си должна быть определена, то есть должны быть указаны:
тип возвращаемого значения;
имя функции;
информация о формальных аргументах;
тело функции.
Определение функции имеет следующий синтаксис:
ТипВозвращаемогоЗначения ИмяФункции(СписокФормальныхАргументов){
ТелоФункции;
...
return(ВозвращаемоеЗначение); }
Пример
float function(float x, float z) {
float y;
y=x+z;
return(y); }
В указанном примере возвращаемое значение имеет тип float. В качестве возвращаемого значения в вызывающую функцию передается значение переменной y. Формальными аргументами являются значения переменных x и z.
Если функция не возвращает значения, то тип возвращаемого значения для нее указывается как void. При этом операция return может быть опущена. Если функция не принимает аргументов, в круглых скобках также указывается void.
Различают системные (в составе систем программирования) и собственные функции.
Системные функции хранятся в стандартных библиотеках, и пользователю не нужно вдаваться в подробности их реализации. Достаточно знать лишь их сигнатуру. Примером системных функций, используемых ранее, являются функции printf() и scanf().
Собственные функции - это функции, написанные пользователем для решения конкретной подзадачи.
Разбиение программ на функции дает следующие преимущества:
Функцию можно вызвать из различных мест программы, что позволяет избежать повторения программного кода.
Одну и ту же функцию можно использовать в разных программах.
Функции повышают уровень модульности программы и облегают ее проектирование.
Использование функций облегчает чтение и понимание программы и ускоряет поиск и исправление ошибок.
С точки зрения вызывающей программы функцию можно представить как некий "черный ящик", у которого есть несколько входов и один выход. С точки зрения вызывающей программы неважно, каким образом производится обработка информации внутри функции. Для корректного использования функции достаточно знать лишь ее сигнатуру.
Вызов функции
Общий вид вызова функции
переменная = ИмяФункции(СписокФактическихАргументов);
Фактический аргумент — это величина, которая присваивается формальному аргументу при вызове функции. Таким образом, формальный аргумент — это переменная в вызываемой функции, а фактический аргумент — это конкретное значение, присвоенное этой переменной вызывающей функцией. Фактический аргумент может быть константой, переменной или выражением. Если фактический аргумент представлен в виде выражения, то его значение сначала вычисляется, а затем передается в вызываемую функцию. Если в функцию требуется передать несколько значений, то они записываются через запятую. При этом формальные параметры заменяются значениями фактических параметров в порядке их следования в сигнатуре функции.
Возврат в вызывающую функцию
По окончании выполнения вызываемой функции осуществляется возврат значения в точку ее вызова. Это значение присваивается переменной, тип которой должен соответствовать типу возвращаемого значения функции. Функция может передать в вызывающую программу только одно значение. Для передачи возвращаемого значения в вызывающую функцию используется оператор return в форме
return(ВозвращаемоеЗначение);
Действие оператора следующее: значение выражения, заключенного в скобки, вычисляется и передается в вызывающую функцию. Возвращаемое значение может использоваться в вызывающей программе как часть некоторого выражения. Оператор return также завершает выполнение функции и передает управление следующему оператору в вызывающей функции. Оператор return не обязательно должен находиться в конце тела функции.
Функции могут и не возвращать значения, а просто выполнять некоторые вычисления. В этом случае указывается пустой тип возвращаемого значения void, а оператор return может либо отсутствовать, либо не возвращать никакое значение:
return;
Пример Посчитать сумму двух чисел.
#include <stdio.h> int sum(int x, int y) {
int k;
k = x + y;
return(k); } int main() {
int a, r;
printf("a= ");
scanf("%d",&a);
r = sum(a, 5); // вызов функции: x=a, y=5
printf("%d + 5 = %d",a, r);
getchar();getchar();
return(0); }
В языке Си нельзя определять одну функцию внутри другой.
В языке Си нет требования, чтобы семантика функции обязательно предшествовало её вызову. Функции могут определяться как до вызывающей функции, так и после нее. Однако если семантика вызываемой функции описывается ниже ее вызова, необходимо до вызова функции определить прототип этой функции, содержащий:
тип возвращаемого значения;
имя функции;
типы формальных аргументов в порядке их следования.
Прототип необходим для того, чтобы компилятор мог осуществить проверку соответствия типов передаваемых фактических аргументов типам формальных аргументов. Имена формальных аргументов в прототипе функции могут отсутствовать.
Пример
#include <stdio.h> int sum(int, int); // сигнатура int main() {
int a, r;
printf("a= ");
scanf("%d",&a);
r = sum(a, 5); // вызов функции: x=a, y=5
printf("%d + 5 = %d",a, r);
getchar();getchar();
return 0; }
int sum(int x, int y) {
int k; // семантика
k = x + y;
return(k);
}
Рекурсивные функции
Функция, которая вызывает сама себя, называется рекурсивной функцией. Рекурсия - вызов функции из самой функции. Пример рекурсивной функции - функция вычисления факториала.
#include <stdio.h> int fact(int num) {
if(num==1) return(1);
else return(num*fact(num-1)); // рекурсивный вызов } int main() {
int a, r;
printf("a= ");
scanf("%d",&a);
r = fact(a);
printf("%d! = %d",a,r);
getchar();getchar();
return(0);
}
Математические функции
Математические функции хранятся в стандартной библиотеке math.h. Аргументы большинства математических функций имеют тип double. Возвращаемое значение также имеет тип double. Углы в тригонометрических функциях задаются в радианах. Основные математические функции стандартной библиотеки.
Функция |
Описание |
int abs(int x) |
Модуль целого числа x |
double acos(double x) |
Арккосинус x |
double asin(double x) |
Арксинус x |
double atan(double x) |
Арктангенс x |
double cos(double x) |
Косинус x |
double cosh(double x) |
Косинус гиперболический x |
double exp(double x) |
Экспонента x |
double fabs(double x) |
Модуль вещественного числа |
double fmod(double x, double y) |
Остаток от деления x/y |
double log(double x) |
Натуральный логарифм x |
double log10(double x) |
Десятичный логарифм x |
double pow(double x, double y) |
x в степени y |
double sin(double x) |
Cинус x |
double sinh(double x) |
Cинус гиперболический x |
double sqrt(double x) |
Квадратный корень x |
double tan(double x) |
Тангенс x |
double tanh(double x) |
Тангенс гиперболический x |
Область видимости объектов и модификация
Главная > Язык Си > Область видимости объектов и модификация
Область видимости объекта (переменной или функции) определяет набор функций или модулей, внутри которых допустимо использование имени этого объекта. Область видимости объекта начинается в точке объявления объекта.
Время жизни объекта может быть глобальным и локальным. Глобальными называют объекты, объявление которых дано вне функции. Они доступны (видимы) во всем файле, в котором они объявлены. В течение всего времени выполнения программы с глобальным объектом ассоциирована некоторая ячейка памяти.
Локальными называют объекты, объявление которых дано внутри блока или функции. Эти объекты доступны только внутри того блока, в котором они объявлены. Объектам с локальным временем жизни выделяется новая ячейка памяти каждый раз при осуществлении описания внутри блока. Когда выполнение блока завершается, память, выделенная под локальный объект, освобождается, и объект теряет своё значение.
Пример
#include <stdio.h> void autofunc(void) {
int k=1; // локальный объект
printf(" \n k = %d ", k);
k=k+1; } int main() {
for(int i = 0; i<=5; i++) // область видимости i - цикл
autofunc();
getchar();
return 0; }
Область видимости локальной переменной k - функция autofunc(). Каждый раз при входе в функцию с идентификатором k ассоциируется некоторая ячейка памяти, в которую помещается значение равное 1.
Результат
выполнения программы
Та
же программа, но с использованием
глобального объекта
#include <stdio.h> int k=1; // глобальный объект void autofunc(void) {
printf(" \n k = %d ", k);
k=k+1; } int main() {
for(int i = 0; i<=5; i++) // область видимости i - цикл
autofunc();
getchar();
return 0; }
Результат
выполнения программы
С
помощью глобальных переменных можно
организовать обмен информацией между
функциями. При этом вызываемая функция
не будет принимать значения глобальных
переменных в качестве формальных
аргументов. Однако в этом случае
существует опасность случайного
изменения глобальных объектов другими
функциями.
Пример
#include <stdio.h> int x, y, z; // глобальные переменные void sum(void){
z = x + y;
} int main() {
printf("x= ");
scanf("%d",&x);
printf("y= ");
scanf("%d",&y);
sum();
printf("z= %d", z);
getchar(); getchar();
return 0; }
Модификация объектов
Модификация или видоизменение объектов в языке Си применяется для того, чтобы изменить диапазон значений или область действия объекта. Ключевые слова, которые применяются для модификации, называются модификаторами. Модификатор unsigned предназначен для того, чтобы объявлять беззнаковую целочисленную переменную, тем самым изменив диапазон представления этой переменной. Модификатор extern предназначен для использования в данном программном модуле объекта, который объявлен в другом программном модуле.
Файл 1 |
Файл 2 |
#include <stdio.h> int x, y, z; extern void func(void); int main() { printf("x= "); scanf("%d", &x); printf("y= "); scanf("%d", &y); func(); printf("z= %d",z); getchar(); getchar(); return 0; } |
extern int x, y, z; void func(void) { z = x + y; } |
Пример
окна проекта, состоящего из двух файлов
Модификатор static позволяет связать с идентификатором фиксированный адрес (ячейку памяти). Если объект расположен по некоторому фиксированному адресу, то он называется статическим. Объект, который располагается в произвольном месте оперативной памяти, называется динамическим. Если необходимо динамический объект сделать статическим, то используется модификатор static. Переменные, объявленные с использованием модификатора static сохраняют свои значения при входе и выходе из функции, однако не являются глобальными.
Пример
#include <stdio.h> void autofunc(void) {
static int k=1; // статический объект
printf(" \n k = %d ", k);
k=k+1; } int main(){
for(int i = 0; i<=5; i++)
autofunc();
getchar();
return 0; }
Переменная k в функции autofunc() зафиксирована в оперативной памяти. Инициализация k проводится только один раз — при первом вызове функции. При повторном обращении к функции autofunc() инициализация переменной k не будет производиться. Значение переменной k и ее адрес сохраняются в оперативной памяти, однако эта переменная не будет доступна из других функций. Результат выполнения программы Модификатор register предназначен для того, чтобы поместить переменную в один из регистров общего назначения центрального процессора при наличии свободного регистра. Благодаря этому повышается скорость работы с данными. Это необходимо для создания управляющих программ, где требуется высокая скорость обработки данных.
Указатели в языке Си
Главная > Язык Си > Указатели в языке Си
Указатель — переменная, содержащая адрес объекта. Указатель не несет информации о содержимом объекта, а содержит сведения о том, где размещен объект. Указатели широко используются в программировании на языке Си. Указатели часто используются при работе с массивами.
Память компьютера можно представить в виде последовательности пронумерованных однобайтовых ячеек, с которыми можно работать по отдельности или блоками.
Каждая переменная в памяти имеет свой адрес - номер ячейки, где она расположена, а также свое значение. Указатель — это тоже переменная, которая размещается в памяти. Она тоже имеет адрес, а ее значение является адресом некоторой другой переменной. Переменная, объявленная как указатель, занимает 4 байта в оперативной памяти (в случае 32-битной версии компилятора).
Указатель, как и любая переменная, должен быть объявлен. Общая форма объявления указателя
