C установка IDE C структура програми C змінні C типи даних С функція printf C константи C арифметичні операції C операції порівняння і логічні операції C порозрядні операції C операції присвоювання C перетворення типів C умовні конструкції C цикли С масиви і рядки С функція scanf C препроцесор. Директива #include C #define директива C макроси C умовна компіляція C функції. Визначення та опис функцій C функції. Передача параметрів в функцію C функції. Повернення результату з функції C функції. Рекурсивні функції C область видимості змінних C зовнішні об'єкти C вказівники C вказівник. Операції з вказівниками C покажчики. Арифметика покажчиків C покажчики. Константи і покажчики C покажчики. Покажчики та масиви C покажчики. Масиви покажчиків, рядки і багаторівнева адресація C покажчики. Покажчики в параметрах функції C покажчики. Динамічна пам'ять C покажчики. Покажчик як результат функції C покажчики. Управління динамічної пам'яттю C покажчики. Покажчики на функцію C покажчики. Покажчики на функції як параметри і результати функцій C покажчики. Функції зі змінною кількістю параметрів C struct. Визначення структур C struct. Структури як елементи структур C struct. Покажчики на структури C struct. Масиви структур C struct. Структури і функції C struct. union об'єднання C struct. Бітові поля С file. Введення-виведення і робота з файлами C file. Читання і запис бінарних файлів C file. Читання і запис структур в файл C file. Читання і запис текстових файлів C file. Форматування вводу-виводу C file. Позиціонування в потоці C file. Консольне введення-виведення

C макроси


Всі ідентифікатори, які визначаються за допомогою директив #define , які передбачають заміну на певну послідовність символів, ще називають макросами .

Макроси дозволяють визначати заміну не тільки для окремих символів, а й для цілих виразів:

#include <stdio.h>
 
#define HELLO printf("Hello World! \n")
#define FOR for(int i=0; i<4; i++)
 
int main(void)
{
    FOR HELLO;
    return 0;
}

Макрос HELLO визначає вивід на консоль рядка " Hello World! \n ". А макрос FOR визначає цикл, який відпрацьовує 4 рази. І в підсумку після обробки препроцесора, функція main буде виглядати наступним чином:

int main(void)
{
    for(int i=0; i<4; i++) printf("Hello World! \n");
    return 0;
}

// RESULT:
/*
Hello World!
Hello World!
Hello World!
Hello World!
*/

Подібні визначення директиви #define мають один недолік, послідовність символів, яка використовується директивою фіксована. Наприклад, тут всюди, де зустрінеться в вихідному коді ідентифікатор HELLO , виводиться рядок " Hello World! ". Але що, якщо ми динамічно хочемо передавати рядок, тобто рядок може бути будь-який. У цьому випадку ми можемо поставити макровизначення з параметрами в такій формі:

#define імя_макроса(список_параметрів) послідовність_символів

Спісок_параметрів тут це список ідентифікаторів, розділених комами. Між ім'ям макросу і відкриваючою дужкою не повинно бути пробілів.

Для звернення до макросу застосовується конструкція:

імя_макроса(список_аргументів)

Список_аргументів - це набір значень, які передаються для кожного параметра макросу.

Наприклад, візьмемо просту операцію, для виведення чисел на консоль і спробуємо скоротити її за допомогою макросів:

#define print(a) printf("%d \n", a)

Тут print - це ім'я макросу або ідентифікатор, після якого в дужках вказано параметр a . Цей параметр буде представляти будь-яке ціле число. І будь-який виклик макросу print буде замінюватися на рядок printf("%d \n", a) . Подивимося, як це буде виглядати на прикладі:

#include <stdio.h>
#define print(a) printf("%d \n", a)
 
int main(void)
{
    int x = 10;
    print(x);
    int y =20;
    print(y);
    print(22);
    return 0;
}

// RESULT:
// 10
// 20
// 22

Або більш складний приклад: визначимо макрос swap(t,x,y) , який обмінює місцями значення двох аргументів типу t :

#include <stdio.h>
 
#define t int
#define swap(t, x, y) { t temp = x; x = y; y=temp;}
 
int main(void)
{
    t x = 4;
    t y = 10;
    swap(t, x, y)
    printf("x=%d \t y=%d", x, y);
    return 0;
}

Макрос swap застосовує блок для обміну значеннями. Причому даний макрос фактично універсальний: нам неважливо, який тип у змінних x і y .

Або ще один приклад - знаходження мінімального значення:

#include <stdio.h>
#define min(a,b) (a < b ? a : b)
 
int main(void)
{
    int x = 23;
    int y = 14;
    int z = min(x,y);
    printf("min = %d", z);  // min = 14
    return 0;
}

Тобто в даному випадку після роботи препроцесора замість рядка int z = min(x,y); ми отримаємо рядок:

int z = (x < y ? x : y);

препроцесорні операції

При обробці вихідного коду препроцесор може виконувати дві операції: # і ## .

Операція # дозволяє вставляти текст параметра, який слідує після операції, в лапки:

#include <stdio.h>
#define print_int(n) printf(#n"=%d \n",n);
 
int main(void)
{
    int x = 23;
    print_int(x);       // x=23
    int y = 14;
    print_int(y);       // y=14
    int number = 203;
    print_int(number);  // number=203
    return 0;
}

Директива ## дозволяє поєднувати дві лексеми:

#include <stdio.h>
#define print(a,b,c) printf("%d", a##b##c);
 
int main(void)
{
    print(2, 81, 34);   // 28134
    return 0;
}

Тут склеюються три числа, які передаються в макрос print . Або аналогічний приклад:

#include <stdio.h>
#define unite(a,b,c) a##b##c;
 
int main(void)
{
    int x = unite(2, 81, 34);   // 28134
    printf("%d \n", x);
    return 0;
}

Наш партнер:
beta test mp3 playlist downloader