Чи все ще використовується мова програмування C?


96

Я програміст на C #, і більшість моїх розробок стосується веб-сайтів разом із кількома програмами Windows. Що стосується С, то я давно не користувався ним, оскільки не було потреби. Це сталося для мене несподіванкою, коли одна з моїх друзів сказала, що їй потрібно вивчити С для тестування завдань, а я допомагав їй вивчати C #.

Я подумав, що хтось навчиться C для тестування лише в тому випадку, якщо розробляється робота в C. З моїх знань, усі розробки, пов'язані з COM та дизайном обладнання, також здійснюються в C ++. Тому вивчення C не має сенсу, якщо вам потрібно використовувати C ++. Я також не вірю в історичну значимість, так навіщо витрачати час і гроші на навчання С?

Чи все ще використовується C у будь-якій новій розробці програмного забезпечення чи що-небудь ще?


46
Ви коли-небудь бачили компілятор C ++ для ПОС?
SK-логіка

195
Хіба я єдиний, кому сумно, що хтось прирівнював би навчання до того, щоб витрачати гроші та час?
Jetti

37
" Наскільки мені відомо, усі розробки, пов'язані з COM та дизайном обладнання, також виконуються на C ++ " - Здається мені, що ви насправді не займаєтесь будь-яким дизайном апаратного інтерфейсу.
Ред С.

32
Люди забувають, що вигадливі мови вищого рівня, які ми всі любимо, часто впроваджуються у C.
David Cowden

13
@ThomasEding Мертва мова? У вас, звичайно, дуже обмежені знання мов програмування, якщо ви вважаєте C мертвою мовою.
JesperE

Відповіді:


214

Перевага C має те, що це порівняно невелика мова , що спрощує реалізацію компілятора C (тоді як компілятор C ++ - це монстр для запису) та полегшує вивчення мови . Також дивіться індекс TIOBE , згідно з яким C трохи випереджає C ++.

У порядку зменшення (IMO) порядку виправдання C досі багато використовується

  • Вбудовані речі
    Простіше перенести компілятор C на невелику платформу, ніж портувати компілятор C ++. Також прихильники C стверджують, що C ++ "робить занадто багато за їхніми спинами". Однак ІМО - це FUD.

  • Програмування систем
    Знову ж таки, це зазвичай пояснюється твердженнями, що легше "знати, що робить компілятор". Однак багато вбудованих програм виграють від, наприклад, шаблонів та інших ключових функцій C ++.

  • Програмне забезпечення з відкритим кодом.
    Це, головним чином, проблема ставлення: OSS завжди віддав перевагу C над C ++ (тоді як у великих частинах галузі навпаки). Ірраціональна ненависть Торвальда може бути насправді найважливішою причиною цього в Linux .


16
Це більше історія, ніж ставлення. Багато з того, що ви можете вважати "основними" пакетами з відкритим кодом, були спочатку розроблені, коли C ++ був не настільки широко доступний, як зараз, а ресурсів було ще мало.
Blrfl

65
Індекс TIOBE - жарт. Хіти пошукових систем безглузді.
DeadMG

29
@Sedate: Ці шаблони, як правило, спричиняють роздуття коду - це міф, що походить із часів стародавніх компіляторів C ++. Сучасні компілятори складають однакові екземпляри шаблону. OTOH, шаблони дозволяють мета-програмування шаблонів, яке виконує код під час компіляції, а не час виконання, внаслідок чого генерується менше коду. Крім того, вони створюють набагато безпечніші програми (менше кастингу), що часто є дуже важливим у вбудованому домені. Експерти C ++ були забиті на смерть EC ++ через (серед іншого) абсолютну глупость викидання шаблонів.
sbi

18
@James: Ви маєте на увазі такі речі, як ефективні абстракції, загальне програмування та безпека типу? Так, хто б цього хотів?
Xeo

11
@JesperE Як це трапляється, я змінив роботу, так як писав це, і зараз програмую вбудовані пристрої. Ми використовуємо C ++, і це чудово, що металопрограмування STL та шаблонів може зробити для вас, коли у вас слабкі апаратні та жорсткі обмеження в реальному часі, а також необхідність надійності. (Ми робимо електростанції.) Так, ви повинні знати, чи слід використовувати std::vectorабо std::mapдля певного коду - але вам не доведеться його реалізовувати самостійно, але ви можете розраховувати на добре перевірену, високоефективну, і надійні бібліотечні реалізації, що пропонують високі абстракції.
sbi

119

C багато використовується у вбудованому апаратному програмуванні, де ресурсів мало.

Ядро Linux написано на мові C, оскільки, за словами Лінуса Торвальдса, C ++ - жахлива мова .


14
Я думаю, велика частина ядра Windows також є C. І багато застарілих систем.
Coder

14
Для завершення Лінус спробував C ++ у ядрі. Це було скоріше питанням, ніж плюсом. У будь-якому разі, розвиток ядра - це дійсно конкретна тема, це не означає, що C ++ взагалі поганий.
deadalnix

75
На думку інших , аргументація Лінуса жахлива.
sbi

36
Аргументи Лінуса можуть бути, а можуть бути і
невірними

15
Лінус - це гет.
ubiyubix

94

Усі сучасні мови, які я бачив, можуть взаємодіяти з C:

  • C ++
  • Java
  • C #
  • Пітон
  • Хаскелл
  • Мета C

Необхідність взаємодії з C випливає з:

  • C маючи простий ABI
  • C тривалий час

Це означає, що оскільки ці мови можуть спілкуватися з C, вони можуть:

  • використовувати свої бібліотеки
  • спілкуватися між собою через C (наприклад, Clang написано на C ++, але пропонує Python Bindings, підключений до його інтерфейсу C).

І я б погодився, що всі вони покладаються на C упродовж виконання (якщо вони не пройшли повну збірку? Сумнівно).

C - мова мов програмування Lingua Franca і одна з найпростіших (ABI-мудра), не пов'язана з конкретною архітектурою (як, наприклад, збірка), знадобиться серйозний зсув, щоб позбутися її.


45

На мій погляд, це дуже короткоглядне питання, схожий на "Мої друзі, і я слухаю Реггі. Чи справді хтось ще слухає Репа?".

Кожна мова там має своє використання. Різні мови безумовно мають свої ніші. Але питати про С! Я впевнений, що менше людей щодня використовують C #, ніж C (з абсолютно упередженого погляду роботи в магазині, де ніхто не використовує C #).

Швидкий Google, дивлячись на відносну популярність мов.
Я впевнений, що нічого з цього не є авторитетним, але ми можемо використовувати його, щоб побачити тенденції:

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
http://langpop.com/

Навіть дивлячись на співвідношення питань щодо тегів:
https://stackoverflow.com/tags

  • C #: 209845
  • 16 інших тегів
  • С: 38790

Тож C - це 18 найпопулярніших тем на SO (і там є багато інших мов).

Примітка: вищевказаний індекс TIOBE постійно оновлюється протягом більше десяти років (і має деякі дані, що відносяться до 3 десятиліть), як слід вимірювати інженерів, що працюють на кожній мові (хоча я не маю уявлення, наскільки це точно). З 10 кращих мов, окрім Java / Visual Basic, він відображає те, що знають люди в моєму магазині (хоча наші співвідношення будуть дещо різними, оскільки у нас значно менший розмір вибірки).


1
Ця відповідь мене бентежить ... ви продовжуєте працювати з C # і потім показуєте ТАК-теги питань, але жодне з цього не має нічого спільного з використанням C. Популярність (особливо на langpop, де вони використовують запити пошукових систем для визначення популярності) насправді не показує сучасне використання мови, а лише сучасні пошуки на мові. Ви повинні врахувати, що C використовується в університетах часто для класів нижчого рівня, щоб можна збільшити кількість запитів, а також повідомлення SO.
Jetti

3
@ Jetti: Ось чому я прямо кажу: I am sure none of this is authoritative but we can use it to see trendsАле я не згоден з вашим другим твердженням; C більше не є основною мовою, яку викладають у вищих навчальних закладах (якби це було, тоді нова партія випускників не була б такою марною). Зараз люди, як правило, навчаються Java / C # різко. Також звіт Tiobe стосується завдань, а не запитів.
Мартін Йорк

Озирнувшись назад, здається, що з мого боку якраз поганий вибір слова. Я не мав на увазі класи з низькою кількістю (початкові класи), я мав на увазі системні класи (архітектура комп'ютера), де використовується C.
Jetti

4
Кількість тегів SO не визначає популярність мови в цілому, вона просто показує популярність мови серед користувачів SO .
Ред С.

4
@Ed S. Очевидно. Але питання не в популярності. Її про існування С як мови. Кількість тегів SO показує нам, що це, безумовно, не мертва мова. Той факт, що C знаходиться в топ-2 на інших сайтах, не робить його першою / другою найбільш вживаною мовою. Але його існування в топ-10 є вагомим показником того, що він не мертвий. Звичайно, ніщо це не є доказом лише сильних показників того, що C все ще активно використовується.
Мартін Йорк

23

Можливо, вам доведеться використовувати C, коли ви мало ресурсів і не потребуєте об'єктно-орієнтованих можливостей.

Багато програмних засобів, які використовуються сьогодні, все ще написані на мові C, не кажучи вже про драйвери апаратного забезпечення.

За індексом Tiobe , C все ще є найбільш вживаною мовою.


Як запропонував tcrosley, ви можете поглянути на це пов'язане питання .


Ви також повинні перевірити деякі пов’язані статті щодо відмінностей між C і C ++, як-от ця вікі або, наприклад, ця .


4
гм !! це чудовий момент. Я ніколи не замислювався над тим, що "можливості OOP фактично додають накладні витрати на мову". Дякуємо, що пояснили цю дійсну точку. Тепер я можу зрозуміти, де C випереджає інших
Pankaj Upadhyay

7
@Pankaj C ++, як правило, не обов'язково додає багато часу роботи, багато складності мови полягає в принципі "не платити за те, що ти не використовуєш" - якщо ви не використовуєте винятки, то винятки не сповільнити або додати розмір коду. Хоча компілятор більший і складніший
Мартін Бекетт

2
Re C у вбудованому полі, дивіться також це питання та відповіді: programmers.stackexchange.com/questions/84514/…
tcrosley

6
Насправді вам ніколи не потрібні можливості OOP, він просто добре працює в деяких сценаріях.
Ред С.

2
@Jose Faeti: Мій бос погодиться, бо мій начальник досвідчений, раціональний хлопець. Він не переживає релігію програмування.
Ред С.

20

Здається, ви намагаєтеся переконати себе, що C марний і тому його можна ігнорувати. Давайте розбимо ваше запитання:

"Я подумав, що хтось навчиться С на тестування лише в тому випадку, якщо є розробка, зроблена в C."

Ні, є багато причин, щоб навчитися C. Навіть якби ви не знали, що я все одно уникатиму таких висловлювань, особливо в поєднанні з круговою логікою. Очевидно, що потрібно знати мову, на якій написаний код, щоб мати змогу належним чином перевірити / виправити його, але це передбачає, що мовний текст все ще використовується як даний, і це стосується будь-якої мови, а не лише C.

"Наскільки мені відомо, усі розробки, пов'язані з COM та дизайном обладнання, також виконуються в C ++."

Це неправильно.

"Тому вивчення C не має сенсу, якщо вам потрібно використовувати C ++. Я також не вірю в історичну значимість, так навіщо витрачати час і гроші на вивчення C?"

Це найбільш сумнівна логіка з усіх. Перш за все, історичне значення - це те, у що ви повинні вірити, адже якби ви знали, що C - це підмножина C ++, і, завдяки цьому, знання C може допомогти вам бути кращим програмістом на C ++. Звичайно, C також впливав на більшість мов, які з’явилися після нього, тому переваги не припиняються на цьому. Крім того, оскільки С настільки важливий, його не можна вважати таким, що має лише історичне значення. Він все ще широко використовується, і тому не може бути відведений на подібну позицію. Ви можете стверджувати, що це не мова, якою повинен користуватися кожен програміст і має досконалі знання, і це було б правильно, але, будь ласка, не будуйте своїх аргументів на тому, що ви не вірите чомусь, не вивчивши спочатку його справжні достоїнства.


7
C - це підмножина C ++ , це те, що ви мали на увазі ?? . C не є підмножиною C ++; Фактично вони зовсім інші. Так, C ++ - це розширення C, або іноді його називають C з класами та OOP , але сказати, що C - це підмножина, не виправдовує
Pankaj Upadhyay

7
C ++ здебільшого є набором старої версії C, і C відтоді пішов у дещо іншому напрямку. Деякі аспекти мов пішли в основному паралельними напрямками, але інші - ні (і C ++ має ще багато інших).
стипендіати

Я погоджуюсь голосувати за уточнення цього факту, що не всі дійсні програми C є дійсними програмами C ++, тобто C ++ не є сукупністю C. Однак це супернабір того, як C був у момент прийняття рішення про його Суперсет, як згадували стипендіати Доналу. Просто не має сенсу говорити, що це більше, коли це вже не правда.
Джошуа Хеджес

16

Окрім вбудованих систем, більшість нових мов мають певний спосіб взаємодіяти з C. Коли ви пишете бібліотеку, яку ви хочете провести легко, використовуючи всі ці мови, C - це очевидний вибір. C ++, хоча він також може взаємодіяти з деякими мовами (наприклад, Python (лише CPython)), C ++ не може взаємодіяти з більшою кількістю мов через деякі особливості (особливо керування іменами, але шаблони не допомагають у питанні). C ABI є одним з найпростіших для інтерфейсу (я знаю, що ви можете написати C ++ і використовувати інтерфейс "C" для інтерфейсу. Мені все одно).

Це також має перевагу в тому, що C і C ++ дійсно є найкращими мовами для програмування систем, а час компіляції на C набагато швидший. Часи компіляції на C ++ помітно гірші за будь-яку мову, якою я користувався.

В той час, коли є інші мови, які хочуть стати популярною системою мови там (я знаю про D зокрема), значна частина програмного забезпечення написана на C / C ++. Такі мови, як D, вимагають, щоб хтось створив обгортку навколо бібліотеки С, а не просто використовував її безпосередньо (як, наприклад, з C ++).


D може зателефонувати на код C безпосередньо, як і на C ++ Все, що вам потрібно, якщо прототип функції (знову ж таки, як і C ++). Ви просто пишете extern(C)в D, тоді як на C ++ ви пишетеextern "C"
Петро Олександр

@Peter Alexander Я знаю про зовнішнє (C) в D. Це те, про що я мав на увазі, коли говорив файл обгортки. Ви не можете безпосередньо включати заголовок C (що можна зробити в C ++, якщо припустимо, що заголовок C використовує зовнішнє "C" і має блоки #ifdef __cplusplus, які це роблять більшість). Тоді є й інші несумісності серед просто використання extern (C) (особливо, як обробляються рядки. Наскільки мені відомо, вони не мають нульового термінатора в D. Тому вам потрібно спеціально змінити масив при передачі його на C).
jsternberg

11

перегляньте langpop.com , особливо графіки з Freshmeat та Google Code. Це свідчить про те, що С все-таки є попереду.

C все ще популярний в системах, де вам потрібно наблизитися до металу (тобто вбудованої системи) та додатків, які працюють на робочу силу.


4
НЕ ВІДКРИТИ цю URL-адресу! Веб-сайт вже не існує, а URL-адреса переспрямовує на деякі дратівливі спам-сторінки.
Микола Суванджієв

11

Я використовую його майже щодня, розробляючи для iPad / iPhone. Багато бібліотек написані на C і не мають еквівалента Objective-C. Так, так, він все ще використовується і одним із найновіших пристроїв на ринку.

За допомогою C ви можете запрограмувати безліч вбудованих систем, це мало і зручно, і, ймовірно, буде ще довгі роки (так само ви не витрачаєте часу, ані грошей на це вивчаєте)


2
"Objective-C ще молодий", це насправді з середини 1980-х років, приблизно стільки ж, скільки C ++. Більшість людей, які його використовують, не натрапили на нього лише до 2007 року.

Щоправда, те, що я хотів сказати, це в основному, що існує багато бібліотек С, які не мають еквівалента в Objective-C для iOS. Дійсно, сама мова зовсім не молода (перевірено у Вікі). Дякуємо, що вказали на це.
Валентин Раду

7

Як правило, для вбудованої системи C все ще широко використовується.

Це питання дає ще якийсь приклад.

Індекс Tiobe , який намагається класифікувати мову за популярністю / використанням , послідовно ставить C на перші місця.


2 місце (після Java).
Мартін Йорк

7
Цікаво, що за останні 10 років C ++ та Java обидва мають тенденцію до зниження популярності, тоді як C залишається більш-менш статичною.
Пол Р.

7

Переносність.

Складіть список кожної системи, на вашу думку, запустить код C, а потім подібний список для будь-якої іншої мови, яка вам подобається.

Якщо ви придумали ту саму відповідь, що і я, то висновок - так.


5

Я думаю, що C - це найпотужніша мова через наступні причини!

1) AT перший C, це системна мова (це означає, що її можна використовувати для програмування низького рівня з мінімальним або відсутнім часом виконання).

2) Швидкість отриманого додатку. Вихідний код C можна оптимізувати набагато більше, ніж мови вищого рівня, оскільки набір мов порівняно невеликий і дуже ефективний. Це приблизно так близько, як ви можете дістатись до програмування на мові асемблера, без програмування на мові складання. і ви навіть можете використовувати збірку та C разом!

3) C має своє застосування у програмуванні програмного забезпечення (апаратного забезпечення). Це пов'язано з його здатністю використовувати / працювати зі складанням і безпосередньо спілкуватися з контролерами, процесорами та іншими пристроями.

4) C - це будівельний блок для багатьох інших відомих на сьогодні мов. Подивіться історію C, і ви побачите, що вона існує вже деякий час (оскільки мови програмування так чи інакше). Погляньте на Python, наприклад, повністю об'єктно-орієнтовану мову програмування високого рівня. Він написаний на С (можливо, і на С ++). Це говорить вам, якщо ви хочете дізнатися, що відбувається під капотом іншими мовами; розуміння C і як він працює, дуже важливо.

Мова програм використовується для програмування високого рівня, наприклад, написання текстового процесора чи гри. Прикладами мов програм є Java, C #. Причина полягає в тому, що вони містять збирання сміття, автоматичне введення тексту, перевірку часу роботи тощо - де основна увага приділяється продуктивності.

Система мови використовується для програмування низького рівня. наприклад мікроконтролер, драйвер та ядро ​​ОС. Приклади включають в себе збірку, C. Для виконання коду безпосередньо на апаратному забезпеченні вони вимагають мало часу або без його виконання, і фокус полягає в тому, щоб програміст мав прямий контроль над обладнанням.

В цілому він зменшується як мова додатків, але все ще сильний як системна мова.


1

О так, це використовується. Я працюю в галузі обробки мережевих пакетів. Я був у двох різних компаніях, де ми обробляємо мережеві пакети. Отже, ми працюємо на рівні Ethernet або IP, а не на рівні вище TCP.

Цікаво, що в обох компаніях C обирали над C ++. В одній з компаній один з двох продуктів був побудований на основі ядра Linux, тоді як інший продукт був побудований у просторі користувачів Linux. Продукт ядра, очевидно, що використовується C як ядро ​​Linux, запрограмований на C, але вони вирішили використовувати C і для продукту простору користувачів. Обидва продукти були розроблені починаючи приблизно з 2000 року (продукт ядра трохи до 2000 року, а продукт простору користувача - трохи після 2000 року).

У компанії, куди я пішов після цього, продукт будувався на C, а не на C ++. Це фактично продовження проекту з середини 1990-х, хоча через останні вимоги до підвищення продуктивності було вирішено, що по суті все буде переписано. У нас була можливість вибрати C ++ завдяки цьому переписуванню, але цього не зробили.

У галузі обробки мережевих пакетів продуктивність налічує багато. Отже, я хочу реалізувати власну хеш-таблицю, що має більш високу продуктивність, ніж існуючі хеш-таблиці. Я, а не автор хеш-таблиці, я вибираю, яку хеш-функцію потрібно використовувати. Можливо, я хочу виступити і піти на MurMurHash3 . Можливо, я хочу забезпечити безпеку і поїхати за SipHash . Розподільники пам'яті, очевидно, на замовлення. Насправді всі важливі структури даних, які ми використовуємо, були реалізовані на замовлення для досягнення максимальної продуктивності.

Хоча немає нічого, що перешкоджало б використанню C ++, зазвичай це погана ідея. Один викинутий виняток за пакет знизить швидкість обробки пакету до неприйнятних рівнів! Отже, ми не можемо використовувати винятки C ++. Шлях занадто повільний. Ми вже використовуємо своєрідний об'єктно-орієнтований код С, реалізуючи структури даних як структури, а потім реалізуючи функції, що працюють на цих структурах. C ++ дозволить мати віртуальні функції, але потім знову виклики віртуальних функцій знищать продуктивність, якщо вони використовуються скрізь. Отже, краще бути явним і мати покажчик функції, якщо потрібні виклики віртуальних функцій.

C ++ зробить багато речей за вашою спиною: розподіл пам’яті тощо. З іншого боку, у C зазвичай цього не відбувається. Ви можете записати функцію, яка виділяє пам'ять, але зазвичай з інтерфейсу функції видно, що розподіл відбувається.

Як приклад типу мікрооптимізацій, які ви можете робити при програмуванні на C, подивіться на макрос контейнер_of у ядрі Linux. Звичайно, ви можете використовувати контейнер_of у коді C ++, але хто це робить? Я маю на увазі, це цілком прийнятно в більшості програм С, але типові програмісти C ++ негайно запропонують щось інше, наприклад, пов'язаний список, який виділяє вузли посилань як окремі блоки. Ми цього не хочемо, оскільки кожен виділений блок пам'яті поганий для продуктивності.

Мабуть, єдине, що допоможе нам у C ++, це те, що C ++ дозволяє метапрограмування шаблонів, тобто ви можете іноді уникати викликів віртуальних функцій, зберігаючи параметр функції, і дозволяти компілятору вбудовувати функції. Але метапрограмування шаблонів є складним, і нам вдалося виконати всі вимоги на C, тому користь цієї функції в C ++ не настільки важлива.

В одній із компаній у нас фактично була спеціальна мова для компіляції, де частина функцій була реалізована. Вгадайте, яка була цільова мова компілятора? Асамблея? Ні, нам довелося підтримувати як 32-бітну, так і 64-бітну архітектуру. C ++? Звичайно, ви жартуєте. Очевидно, це був C з обчисленим гото GCC . Так, спеціальна мова була компільована у C (або власне gcc-варіант C, який підтримував обчислені goto), і компілятор C виробляв збірку.


0

Я все ще використовую C щодня, і одна з головних причин - це взаємодія з іншими мовами та SDK, призначений для використання плагінами, побудованими всіма видами компіляторів на різних мовах.

Я не можу написати API C ++, який використовує класи з конструкторами та деструкторами та vtables, перевантаження функцій, викидає винятки тощо, які можна використовувати з Lua, C #, Python, C тощо. і налаштування від наших власних.

Я не можу написати C # SDK, який можна викликати з Python, наприклад, або SDK Python, який можна викликати з C #.

C - це єдина мова, яка дозволяє мені створити API, який можна викликати з будь-якої з цих мов. Це говорить про те, що я часто використовую C ++ для реалізації цих інтерфейсів C (хоча іноді я просто реалізую їх у C).

Крім того, мені іноді здається, що C є найпростішою мовою роботи з такими речами, як структури низького рівня даних та розподільники пам'яті. Вся додаткова безпека, яку ви отримуєте в C ++, не допомагає, якщо ви пишете розподільник пам'яті, призначений для об'єднання біт і байтів, що вирівнюються. А проти системи багатого типу C ++ та обробки винятків, непросто прокручувати власні структури даних - просто подивіться, скільки зусиль потрібно, щоб написати структуру даних настільки тривіально, як std::vectorніби ви хочете зробити її безпечною для винятків і уникати посилань ctors і dtors на елементах, які ви не вставили в контейнер (я кажу як той, хто реалізував всю стандартну бібліотеку C ++). Коли просто розробити масив дуже важко втілити в життя, тоді уявіть роботу, необхідну для впровадження високоякісної BVH.

Я віддаю перевагу C ++ над C, коли хочу використовувати існуючі структури даних або реалізувати вищі рівні, використовуючи існуючі, але якщо я збираюся впроваджувати структуру даних низького рівня в основі двигуна, який не використовує для З існуючих структур даних, C, безумовно, робить це набагато простіше зробити зі своєю системою спрощеного типу uber, яка дозволяє вам просто memcpyтут і тут memmoveречі, mallocсуміжний блок і reallocтам, не турбуючись про те, що кидають конструктори, деструктори та винятки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.