10 главных конструкций языка C
10 главных конструкций языка C
10 главных конструкций языка Go 10 главных конструкций языка Swift 10 главных конструкций языка Java

Быст­рый обзор основ­ных кон­струк­ций язы­ка C для тех, кто хочет разо­брать­ся в осно­вах. Здесь вы встре­ти­те мно­го оче­вид­ных и понят­ных кон­струк­ций, кото­рые есть во мно­гих язы­ках, — это пото­му, что мно­гие язы­ки взя­ли эти кон­струк­ции как раз из язы­ка C.

На самом деле в ста­тье их 11, но 10 зву­чит лучше.

👉 Точ­ка с запя­той ста­вит­ся после каж­дой команды.

Комментарии

Клас­си­че­ские ком­мен­та­рии в C выгля­дят так:

/* Привет, это комментарий */

/* Его можно начинать на одной строчке

и продолжать на другой */

Есть ещё одно­строч­ные ком­мен­та­рии дву­мя сле­ша­ми //, но быва­ют ком­пи­ля­то­ры, кото­рые их не понимают.

Переменные и типы данных

Что­бы объ­явить пере­мен­ную в C, нуж­но сна­ча­ла ука­зать её тип, а потом напи­сать имя. Отдель­но­го слу­жеб­но­го сло­ва для созда­ния пере­мен­ной в C нет.

В C есть раз­де­ле­ние на корот­кие (short), обыч­ные и длин­ные (long) пере­мен­ные — на 2, 4 и 8 байт соот­вет­ствен­но. Это нуж­но для эко­но­мии памя­ти, что­бы выде­лять ров­но то коли­че­ство байт, кото­рое нуж­но для рабо­ты программы.

int i; /* целое число на 4 байта */
int x,y; /* две целочисленные переменные */
short int si; / *короткое целое число на 2 байта */
long int l; /* целое число на 8 байт */
char c; /* символьная переменная */
float f; /* дробная переменная на 4 байта */
double d; /* дробная переменная на 8 байт */
int a [10]; /* массив из 10 целых чисел */
struct {int i; char c;} str_name; /* структура из целого числа и символа */

Внешние файлы и директивы

Что­бы про­грам­ма полу­чи­ла неко­то­рые допол­ни­тель­ные воз­мож­но­сти, кото­рых нет в коде по умол­ча­нию, исполь­зу­ют дирек­ти­вы. Они обыч­но пишут­ся в нача­ле про­грам­мы и начи­на­ют­ся с сим­во­ла решётки:

/* компилятор ищет файл prog.h в каталоге /usr/include и позволяет нам использовать команды из этого файла */
#include <prog.h>
#ifdef i8088
     /* если программа будет запущена на процессоре 8088, то выполнятся инструкции, написанные внутри этого блока */
#endif

Формат программы

В каж­дой про­грам­ме на C долж­на быть функ­ция main(), внут­ри кото­рой раз­ме­ща­ет­ся основ­ной код. Боль­шин­ство ком­пи­ля­то­ров тре­бу­ют, что­бы мы ука­за­ли тип этой функ­ции — обыч­но мож­но исполь­зо­вать int (цело­чис­лен­ный) или void (пустой). Все осталь­ные функ­ции добав­ля­ют­ся по жела­нию, но main() долж­на быть всегда.

#include <prog.h>

/* основная функция */
void main() {
      /* содержимое функции */
}

Ввод и вывод

Для выво­да исполь­зу­ет­ся коман­да printf():

/* подключаем библиотеку расширенного ввода-вывода */
#include <stdio.h>

/* основная функция */
void main() {
    /* объявляем целочисленную переменную */
    int x;
    /* выводим только строку /*
    printf("Введите число: ");
    /* вводим число */
    cin >> x;
    /* выводим строку и переменную */
    /* u означает, что переменную нужно вывести как целое десятичное число без знака */
    printf("Вы ввели  %u", x);
}

Если нужен ввод дан­ных, то исполь­зу­ют коман­ду scanf():

/* подключаем библиотеку расширенного ввода-вывода */
#include <stdio.h>

/* основная функция */
void main() {
    /* объявляем переменные */
    int h,m;
    /* выводим только строку /*
    printf("Введите время в формате чч:мм ");
    /* вводим время */
    /* d означает, что мы ждём целое десятичное число */
    scanf("%d:%d", &h, &m);
}

Присваивание и сравнение

C исполь­зу­ет клас­си­че­ский подход:

один сим­вол «рав­но» — присваивание

два сим­во­ла «рав­но» — сравнение

Осталь­ные опе­ра­то­ры срав­не­ния и логи­че­ские опе­ра­то­ры такие же, как и в дру­гих язы­ках. Каж­дое срав­не­ние берёт­ся в скобки.

Условный оператор if

Тоже всё стан­дарт­но (пото­му что C во мно­гом этот стан­дарт и создал):

if (условие) {

    /* если условие верно, делаем что-то */

} else {

    /* если условие неверно, делаем что-то другое */

}

#include<stdio.h>

void main() {
    int pass;
    prinf("Введите пароль: ");
    scanf("%d", &pass);
    /* если ввели число 1234 */
    if (pass == 1234) {
        printf("Вход разрешён");
    /* если ввели что-то другое */
    } else {
        prinf("Вы ввели неверный пароль");
    }
}

Если блок с else не нужен, его мож­но не писать — корот­кий if тоже работает.

Оператор множественного выбора switch

Что­бы не пло­дить мно­же­ство опе­ра­то­ров if, когда нуж­но выбрать одно из несколь­ких зна­че­ний, исполь­зу­ют опе­ра­тор switch:

#include<stdio.h>
 
int main() {
    short int day;
 
    printf("Введите номер дня недели");
    scanf("%d", &day);
 	/* если номер больше семи — берём целочисленный остаток от деления номера на 7 */
    if (day > 7) {
        day = day % 7;
    }
 
     /* выбираем день из вариантов ниже */
    switch (day) {
    /* если день равен 0 */
    case 1:
        printf("Понедельник");
        /* выходим из дальнейших проверок */
        break;
    case 2:
        printf("Вторник");
        break;
    case 3:
        printf("Среда");
        break;
    case 4:
        printf("Четверг");
        break;
    case 5:
        printf("Пятница");
        break;
    case 6:
        printf("Суббота");
        break;
    /* если ни один вариант не подошёл */,
    default:
        printf("Воскресенье");
    }
}

Если не ста­вить коман­ду break, то опе­ра­тор будет про­дол­жать выпол­нять осталь­ные про­вер­ки, даже если най­дёт сов­па­де­ние по условию. 

Цикл с предусловием for

Клас­си­че­ский цикл, кото­рый в таком же виде исполь­зу­ет­ся во мно­гих языках:

int i;
/* перебираем все числа от 1 до 100, увеличивая переменную на 1 на каждом шаге цикла */
for (i = 1; i < 101; i++) {
	/* выводим значения их квадратов */ 
    printf("%d ", i*i);
}

Осо­бен­ность это­го цик­ла в C в том, что он может рабо­тать и с дроб­ны­ми чис­ла­ми, напри­мер, уве­ли­чи­вать счёт­чик каж­дый раз на 0,1:

/* дробное число */
float num;
/* идём от 5 до 0 и каждый раз уменьшаем число на 0,1 */
for (num = 5.0f; num > 0f; num -= 0.1) {
	/* выводим результат */
    printf("%.2f ", num);
}

Циклы while и do-while

Если вы зара­нее не зна­е­те, сколь­ко раз будет выпол­нять­ся цикл, исполь­зуй­те while или do-while. Пер­вый про­ве­ря­ет усло­вия до нача­ла цик­ла (и если там исти­на — выпол­ня­ет его), а вто­рой дела­ет про­вер­ку в самом конце.

/* объявляем переменную и сразу присваиваем ей значение */
int i = 0;
 
/* пока i меньше 10 – цикл работает */
while (i < 10) {
    printf("%d\n", i);
    /* обрабатываем переменную цикла */
    i++;
}

/* сделаем то же самое, но с постусловием */
i = 0;
/* сначала заходим в цикл */
do {
    printf("%d\n", i);
    i++;
/* а в конце проверяем, идём на новый повтор или нет */
} while(i < 10);

В отли­чие от цик­ла for здесь про­грам­мист сам дол­жен сле­дить за тем, что­бы цикл когда-нибудь пре­кра­тил­ся. Если забыть изме­нить в теле цик­ла пере­мен­ную, от кото­рой зави­сит усло­вие, то про­грам­ма может зацик­лить­ся и зависнуть.

Функции

В язы­ке C про­грам­мист может объ­явить сколь­ко угод­но функ­ций. Каж­дая функ­ция объ­яв­ля­ет­ся так:

тип_результата название (аргументы) {

    тело_функции

}

Если у функ­ции нет аргу­мен­тов, то ста­вят про­сто две скоб­ки, а если есть, то нуж­но обя­за­тель­но ука­зать их тип:

#include <stdio.h>
 
/* объявляем функцию sqr */
float sqr(float x) {
	/* возвращаем квадрат переданного числа */
    return x * x;
}
 
/* основная функция */
void main() {
	/* выводим  строку и сразу вызываем функцию, которая вернёт нам квадрат числа*/
    printf("Квадрат числа 4,2 равен %.3f", sqr(4.2f));
}

Классы, объекты и методы

В язы­ке C тако­го нет. Если нуж­но ООП — исполь­зуй­те С++, про него будет в сле­ду­ю­щий раз.

Текст:

Миха­ил Полянин

Редак­ту­ра:

Мак­сим Ильяхов

Худож­ник:

Даня Бер­ков­ский

Кор­рек­тор:

Ири­на Михеева

Вёрст­ка:

Мария Дро­но­ва

Соц­се­ти:

Олег Веш­кур­цев