Питання та відповіді на іспит з інформатики (програмування на мові С)

1.doc (1 стор.)
Оригінал



http://cpp.r2.ru/h12.htm # 126 http://dfe3300.karelia.ru/koi/posob/c/c.htm # g3.1

  1. Які символи використовуються для утворення ключових слів і ідентифікаторів?

Відповідь:

У цю групу входять великі та малі літери англійського алфавіту, а також символ підкреслення. Слід зазначити, що однакові прописні і малі літери вважаються різними символами, оскільки мають різні коди.

Таблиця 1







Великі літери латинського алфавіту

ABCDEFGHIJKLMNOPQRSTU VWXYZ

Малі літери латинського алфавіту

abcdefghijklmnopqrstu vwxyz

Символ підкреслення

_



  1. ^ Що таке керуюча послідовність?

Відповідь:

Спеціальні символьні комбінації, використовувані у функціях введення і виведення інформації. Керуюча послідовність будується на основі використання зворотного дробової риси (\) (обов'язковий перший символ) і комбінацією латинських букв і цифр (табл.2).

Таблиця 2







^ Керуюча послідовність

Найменування

Шеснадцатерічная заміна

\ A

Дзвінок

007

\ B

Повернення на крок

008

\ T

Горизонтальна табуляція

009

\ N

Перехід на новий рядок

00A

\ V

Вертикальна табуляція

00B

\ R

Повернення каретки

00C

\ F

Переклад формату

00D

\ "

Лапки

022

\ '

Апостроф

027

\ 0

Нуль-символ

000

\ \

Зворотній дробова риса

05C

\ Ddd

Символ набору кодів ПЕОМ в вісімковому поданні



\ Xddd

Символ набору кодів ПЕОМ в шістнадцятковому представленні



Послідовності виду \ ddd і \ xddd (тут d позначає цифру) дозволяє представити символ з набору кодів ПЕОМ як послідовність вісімкових або шістнадцятирічних цифр відповідно. Наприклад символ повернення каретки може бути представлений різними способами:

\ R - загальна керуюча послідовність,

\ 015 - восьмерична керуюча послідовність,

\ X00D - шестнадцатеричная керуюча послідовність.

Слід зазначити, що в строкових константах завжди обов'язково здавати всі три цифри в керуючій послідовності. Наприклад окрему керуючу послідовність \ n (перехід на новий рядок) можна представити як \ 010 або \ xA, але в строкових константах необхідно задавати всі три цифри, в іншому випадку символ або символи наступні за керуючої послідовністю будуть розглядатися як її відсутня частина. Наприклад:

"ABCDE \ x009FGH" дана строковая команда буде надрукована з використанням певних функцій мови СІ, як два слова ABCDE FGH, розділені 8-ю пробілами, в цьому випадку якщо вказати неповну керуючу рядок "ABCDE \ x09FGH", то на друку з'явиться ABCDE = | = GH, так як компілятор сприйме послідовність \ x09F як символ "= + =".

Відзначимо той факт, що, якщо зворотна дробова риса передує символу не є керуючою послідовністю (тобто не включеному до табл.4) і яка не є цифрою, то ця риса ігнорується, а сам символ представляється як літеральний. Наприклад:

символ \ h представляється символом h в строковой або символьної константі.

Окрім визначення керуючої послідовності, символ зворотної дробової риси (\) використовується також як символ продовження. Якщо за (\) слід (\ n), то обидва символи ігноруються, а наступна рядок є продовженням попередньої. Ця властивість може бути використано для запису довгих рядків.

  1. ^ Що таке константа?

Константами називаються перерахування величин в програмі. У мові СІ поділяють чотири типи констант: цілі константи, константи з плаваючою комою, символьні константи і строковими літерали.

Ціла константа: це десяткове, вісімкове або шістнадцяткове число, яке представляє цілу величину в одній з наступних форм: десяткового, вісімковій або шістнадцятковій.

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

Вісімкова константа складається з обов'язкового нуля і однієї або декількох вісімкових цифр (серед цифр мають бути відсутні вісімка і дев'ятка, так як ці цифри не входять в вісімкову систему числення).

Шістнадцяткова константа починається з обов'язкової послідовності 0х або 0Х і містить одну або кілька шістнадцятирічних цифр (цифри представляють собою набір цифр шеснадцатерічной системи числення: 0,1,2,3,4,5,6,7,8,9, A, B, C, D, E, F)
Приклади цілих констант:

Десяткова Вісімкова Шістнадцяткова

константа константа константа

16020 0x10

127 0117 0x2B

240 0360 0XF0

Якщо потрібно сформувати негативну цілу константу, то використовують знак "-" перед записом константи (який називатиметься унарним мінусом). Наприклад:-0x2A, -088, -16.

Кожній цілої константі присвоюється тип, що визначає перетворення, які повинні бути виконані, якщо константа використовується в виразах. Тип константи визначається наступним чином:

- Десяткові константи розглядаються як величини зі знаком, і їм присвоюється тип int (ціла) або long (довга ціла) у відповідності зі значенням константи. Якщо константа менше 32768, то їй присвоюється тип int в іншому випадку long.

- Восьмеричним і шістнадцятиричним констант присвоюється тип int, unsigned int (Беззнаковая ціла), long або unsigned long залежно від значення константи згідно табл 3.

Таблиця 3

^ Діапазон шістнадцяткових констант

Діапазон вісімкових констант

Тип

0x0 - 0x7FFF

0 - 077777

int

^ 0X8000 - 0XFFFF

0100000 - 0177777

unsigned int

0X10000 - 0X7FFFFFFF

0200000 - 017777777777

long

^ 0X80000000 - 0XFFFFFFFF

020000000000 - 037777777777

unsigned long

5l, 6l, 128L, 0105L, OX2A11L.

Константа з плаваючою точкою - десяткове число, представлене у вигляді дійсної величини з десятковою крапкою або експонентою. Формат має вигляд:

[Цифри]. [Цифри] [Е | e [+ | -] цифри].

Число з плаваючою точкою складається з цілої і дробові частини і (або) експоненти. Константи з плаваючою точкою представляють позитивні величини подвоєною точності (мають тип double). Для визначення негативної величини необхідно сформувати константне вираз, що складається з знака мінуса і позитивної константи.

Приклади: 115.75, 1.5Е-2, -0.025, .075,-0.85Е2

Символьна константа - представляється символом укладеному в апострофи. Керуюча послідовність розглядається як одиночний символ, допустимо її використовувати в символьних константах. Значним символьної константи є числовий код символу. Приклади:

'' - Пробіл,

'Q'-буква Q,

'\ N' - символ нового рядка,

'\ \' - Зворотна дробова риса,

'\ V' - вертикальна табуляція.

Символьні константи мають тип int і при перетворенні типів доповнюються знаком.

Строкова константа (літерал) - послідовність символів (включаючи рядкові та прописні літери російського і латинського а також цифри) укладені в лапки ("). Наприклад:" Школа N 35 "," місто Тамбов "," YZPT КОД ".

Відзначимо, що всі керуючі символи, лапки ("), зворотна дробова риса (\) і символ нового рядка в строковому літералі і в символьній константі представляються відповідними керуючими послідовностями. Кожна керуюча послідовність представляється як один символ. Наприклад, при друку литерала" Школа \ n N 35 "його частину" Школа "буде надрукована на одному рядку, а друга частина" N 35 "на наступному рядку.

Символи строкового літерала зберігаються в області оперативної пам'яті. Кінець кожного строкового літерала компілятором додається нульовий символ, що представляється керуючої послідовністю \ 0.

Строковий літерал має тип char []. Це означає, що рядок розглядається як масив символів. Відзначимо важливу особливість, число елементів масиву дорівнює числу символів у рядку плюс 1, так як нульовий символ (символ кінця рядка) також є елементом масиву. Всі рядкові літерали розглядаються компілятором як різні об'єкти. Рядкові літерали можуть розташовуватися на декількох рядках. Такі літерали формуються на основі використання зворотного дробової риси і клавіші введення. Зворотній чорта з символом нового рядка ігнорується компілятором, що призводить до того, що наступна рядок є продовженням попередньої. Наприклад:

"Рядок невизначеною \ n

довжини "

повністю ідентична ЛІТЕРАЛЬ

"Рядок невизначеною довжини".

Для зчеплення строкових літералів можна використовувати символ (або символи) пробілу. Якщо в програмі зустрічаються два або більше строкових литерала, розділені тільки пробілами, то вони будуть розглядатися як одна символьний рядок. Цей принцип можна використовувати для формування строкових літералів займають більше одного рядка.
  1. ^

    Що таке ідентифікатор?


Відповідь:

Ідентифікатором називається послідовність цифр і букв, а також спеціальних символів, за умови, що перший стоїть буква або спеціальний символ. Для утворення ідентифікаторів можуть бути використані рядкові або прописні літери латинського алфавіту. В якості спеціального символу може використовуватися символ підкреслення (_). Два ідентифікатора для утворення яких використовуються збігаються рядкові і прописні літери, вважаються різними. Наприклад: abc, ABC, A128B, a128b.

Важливою особливістю є те, що компілятор допускає будь-яку кількість символів у ідентифікаторі, хоча значущими є перші 31 символ. Ідентифікатор створюється на етапі оголошення змінної, функції, структури і т.п. після цього його можна використовувати в подальших операторах розроблюваної програми. Слід зазначити важливі особливості при виборі ідентифікатора.

По перше, ідентифікатор не повинен співпадати з ключовими словами, із зарезервованими словами та іменами функцій бібліотеки компілятора мови СІ.

По друге, слід звернути особливу увагу на використання символу (_) підкреслення в якості першого символу ідентифікатора, оскільки ідентифікатори побудовані таким чином, що, з одного боку, можуть збігатися з іменами системних функцій і (або) змінних, а з іншого боку, при використанні таких ідентифікаторів програми можуть виявитися нестерпними, тобто їх не можна використовувати на комп'ютерах інших типів.

У третьому, на ідентифікатори використовуються для визначення зовнішніх змінних, повинні бути накладені обмеження, що формуються використовуваним редактором зв'язків (відзначимо, що використання різних версій редактора зв'язків, або різних редакторів накладає різні вимоги на імена зовнішніх змінних).
  1. ^

    Типи даних.


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

У мові розрізняють поняття "тип даних" і "модифікатор типу". Тип даних - це, наприклад, цілий, а модифікатор - зі знаком або без знаку. Ціле зі знаком буде мати як позитивні, так і негативні значення, а ціле без знака - тільки позитивні значення. У мові Сі можна виділити п'ять базових типів, які задаються наступними ключовими словами:

Дамо їм коротку характеристику:

  1. Змінна типу char має розмір 1 байт, її значеннями є різні символи з кодової таблиці, наприклад: 'ф', ':', 'j' (при записі в програмі вони полягають в одинарні лапки).

  2. Розмір змінної типу int в стандарті мови Сі не визначений. У більшості систем програмування розмір змінної типу int відповідає розміру цілого машинного слова. Наприклад, в компіляторах для 16-розрядних процесорів змінна типу int має розмір 2 байти. У цьому випадку знакові значення цієї змінної можуть лежати в діапазоні від -32768 до 32767.

  3. Ключове слово float дозволяє визначити змінні дійсного типу. Їх значення мають дробову частину, відокремлювану крапкою, наприклад: -5.6, 31.28 і т.п. Речові числа можуть бути записані також у формі з плаваючою крапкою, наприклад:-1.09e +4. Число перед символом "е" називається мантиссой, а після "е" - порядком. Змінна типу float займає в пам'яті 32 біта. Вона може приймати значення в діапазоні від 3.4е-38 до 3.4e +38.

  4. Ключове слово double дозволяє визначити речову змінну подвійної точності. Вона займає в пам'яті в два рази більше місця, ніж змінна типу float (тобто її розмір 64 біта). Змінна типу double може приймати значення в діапазоні від 1.7e-308 до 1.7e +308.

  5. Ключове слово void (який не має значення) використовується для нейтралізації значення об'єкта, наприклад, для оголошення функції, не повертає ніяких значень.

Об'єкт деякого базового типу може бути модифікований. З цією метою використовуються спеціальні ключові слова, звані модифікаторами. У стандарті ANSI мови Сі є наступні модифікатори типу:

Модифікатори записуються перед специфікаторами типу, наприклад: unsigned char. Якщо після модифікатора опущений специфікатор, то компілятор припускає, що цим специфікатором є int. Таким чином, наступні рядки:

long а;

long int а;

є ідентичними і визначають об'єкт а як довгий цілий. Табл. 1 ілюструє можливі поєднання модифікаторів (unsigned, signed, short, long) зі специфікаторами (char, int, float і double), а також показує розмір і діапазон значень об'єкту (для 16-розрядних компіляторів).

Таблиця 1

Тип

Розмір в байтах (бітах)

Інтервал зміни

char

1 (8)

від -128 до +127

unsigned char

1 (8)

від 0 до 255

signed char

1 (8)

від -128 до +127

int

2 (16)

від -32768 до 32767

unsigned int

2 (16)

від 0 до 65535

signed int

2 (16)

від -32768 до 32767

short int

2 (16)

від -32768 до 32767

unsigned short int

2 (16)

від 0 до 65535

signed short int

2 (16)

від -32768 до 32767

long int

4 (32)

від -2147483648 до 2147483647

unsigned long int

4 (32)

від 0 до 4294967295

signed long int

4 (32)

від -2147483648 до 2147483647

float

4 (32)

від 3.4Е-38 до 3.4Е +38

double

8 (64)

від 1.7Е-308 до 1.7Е +308

long double

10 (80)

від 3.4Е-4932 до 3.4Е +4932




  1. Масиви.

Масив складається з багатьох елементів одного і того ж типу. До всього масиву цілком можна звертатися по імені. Крім того, можна вибирати будь-який елемент масиву. Для цього необхідно задати індекс, який вказує його відносну позицію. Число елементів масиву призначається при його визначенні і надалі не змінюється. Якщо масив оголошений, то до будь-якого його елементу можна звернутися наступним чином: вказати ім'я масиву та індекс елемента в квадратних дужках. Масиви визначаються так само, як і змінні:

int a [100];

char b [20];

float d [50];

У першому рядку оголошений масив а з 100 елементів цілого типу: а [0], а [1], ..., а [99] (індексація завжди починається з нуля). У другому рядку елементи масиву b мають тип char, а в третій - float.

Двовимірний масив представляється як одновимірний, елементи якого теж масиви. Наприклад, визначення char а [10] [20]; задає такий масив. За аналогією можна встановити і більше число вимірювань. Елементи двовимірного масиву зберігаються по рядках, тобто якщо проходити по них в порядку їх розташування в пам'яті, то швидше за все змінюється самий правий індекс. Наприклад, звернення до дев'ятого елементу п'ятого рядка запишеться так: а [5] [9].

Нехай заданий масив:

int a [2] [3];

Тоді елементи масиву а розміщуватимуться у пам'яті таким чином: a [0] [0], a [0] [1], a [0] [2], a [1] [0], a [1] [1] , a [1] [2].

Ім'я масиву - це константа, яка містить адресу його першого елемента (в даному прикладі а містить адресу а [0] [0]). Припустимо, що a = 1000. Тоді адреса елемента а [0] [1] дорівнюватиме 1002 (елемент типу int займає в пам'яті 2 байти), адреса наступного елемента а [0] [2] - 1004 і т.д. Що ж станеться, якщо вибрати елемент, для якого не виділена пам'ять? На жаль, компілятор не стежить за цим. У результаті виникне помилка і програма буде працювати невірно.

У мові Сі існує сильний взаємозв'язок між покажчиками і масивами. Будь-яка дія, яке досягається індексуванням масиву, можна виконати і за допомогою покажчиків, причому останній варіант буде швидше.

Визначення

int a [5];

задає масив з п'яти елементів а [0], a [1], a [2], a [3], a [4]. Якщо об'єкт * у визначений як

int * у;

то оператор у = & a [0]; присвоює змінної у адресу елемента а [0]. Якщо змінна у вказує на черговий елемент масиву а, то y +1 вказує на наступний елемент, причому тут виконується відповідне масштабування для збільшення адреси з урахуванням довжини об'єкта (для типу int - 2 байта, long - 4 байта, (double - 8 байт і т.д.).

Так як саме ім'я масиву є адреса його нульового елемента, то оператор у = & a [0]; можна записати і в іншому вигляді: у = а. Тоді елемент а [1] можна представити як * (а +1). З іншого боку, якщо у - покажчик на масив a, то наступні два записи: a [i] і * (у + i) еквівалентні.

Між ім'ям масиву і відповідним покажчиком є ​​одна важлива відмінність. Покажчик - це змінна і у = а; або y + +; - Допустимі операції. Ім'я ж масиву - константа, тому конструкції виду a = y; a + +; використовувати не можна, так як значення константи постійно і не може бути змінено.

Змінні з адресами можуть утворювати деяку ієрархічну структуру (можуть бути багаторівневими) типу покажчик на покажчик (тобто він містить адресу іншого покажчика), покажчик на покажчик на покажчик і т.д. Якщо покажчики адресують елементи одного масиву, то їх можна порівнювати (відносини виду <,>, ==,! = Й інші працюють правильно). У той же час не можна порівнювати лі6о використовувати в арифметичних операціях покажчики на різні масиви (відповідні вирази не призводять до помилок при компіляції, але в більшості випадків не мають сенсу). Будь адресу можна перевірити на рівність чи нерівність зі значенням NULL. Покажчики на елементи одного масиву можна також вичитати. Тогда результатом будет число элементов массива, расположенных между уменьшаемым и вычитаемым объектами.

Язык Си позволяет инициализировать массив при его определении. Для этого используется следующая форма:

тип имя_массива[...] ... [...] = {список значений};

Приклади:

int a[5] = {0, 1, 2, 3, 4};

char ch[3] = {'d', 'e', '9'};

int b[2][3] = {1, 2, 3, 4, 5, 6};

В последнем случае: b[0][0] = 1, b[0][1] = 2, b[0][2] = 3, b[1][0] = 4, b[1][1] = 5, b[1][2] = 6.

В языке допускаются массивы указателей, которые определяются, например, следующим образом: char *m[5];. Здесь m[5] - массив, содержащий адреса элементов типа char.
  1. ^

    Приоритеты операций и порядок вычислений


В языке СИ операции с высшими приоритетами вычисляются первыми. Наивысшим приоритетом является приоритет равный 1. Приоритеты и порядок операций приведены в табл. 4.

Таблица 4







Пріоритет

Знак операции

^ Типы операции

Порядок выполнения

1

() [] . ->

Выражение

Слева направо

2

- ~! * & ++ -- sizeof приведение типов

Унарні

Справа налево

3

* /%

Мультиплікативні

Слева направо

4

+ -

Адитивні

5

<< >>

Сдвиг

6

< > <= >=

Ставлення

7

== !=

Отношение (равенство)

8

&

Поразрядное И

9

^

Поразрядное исключающее ИЛИ

10

|

Поразрядное ИЛИ

11

&&

Логическое И

12

| |

Логическое ИЛИ

13

? :

Условная

14

= *= /= %= += -= &= |= >>= <<= ^=

Простое и составное присваивание

Справа налево

15

,

Послідовне обчислення

Слева направо
  1. ^

    Преобразование типов


Если в выражении появляются операнды различных типов, то они преобразуются к некоторому общему типу, при этом к каждому арифметическому операнду применяется такая последовательность правил:

  1. Если один из операндов в выражении имеет тип long double, то остальные тоже преобразуются к типу long double.

  2. В противном случае, если один из операндов в выражении имеет тип double, то остальные тоже преобразуются к типу double.

  3. В противном случае, если один из операндов в выражении имеет тип float, то остальные тоже преобразуются к типу float.

  4. В противном случае, если один из операндов в выражении имеет тип unsigned long, то остальные тоже преобразуются к типу unsigned long.

  5. В противном случае, если один из операндов в выражении имеет тип long, то остальные тоже преобразуются к типу long.

  6. В противном случае, если один из операндов в выражении имеет тип unsigned, то остальные тоже преобразуются. к типу unsigned.

  7. В противном случае все операнды преобразуются к типу int. При этом тип char преобразуется в int со знаком; тип unsigned char в int, у которого старший байт всегда нулевой; тип signed char в int, у которого в знаковый разряд передается знак из сhar; тип short в int (знаковый или беззнаковый).

Предположим, что вычислено значение некоторого выражения в правой части оператора присваивания. В левой части оператора присваивания записана некоторая переменная, причем ее тип отличается от типа результата в правой части. Здесь правила преобразования очень простые: значение справа от оператора присваивания преобразуется к типу переменной слева от оператора присваивания. Если размер результата в правой части больше размера операнда в левой части, то старшая часть этого результата будет потеряна.

В языке Си можно явно указать тип любого выражения. Для этого используется операция преобразования ("приведения") типа. Она применяется следующим образом:

(тип) выражение

(здесь можно указать любой допустимый в языке Си тип).

Рассмотрим пример:

int a = 30000;

float b;

........

b = (float) a * 12;

(переменная a целого типа явно преобразована к типу float; если этого не сделать, то результат будет потерян, т.к. a * 12 > 32767).

При выполнении операций происходят неявные преобразования типов в следующих случаях:

- при выполнении операций осуществляются обычные арифметические преобразования (которые были рассмотрены выше);

- при выполнении операций присваивания, если значение одного типа присваивается переменной другого типа;

- при передаче аргументов функции.

Кроме того, в Си есть возможность явного приведения значения одного типа к другому.

В операциях присваивания тип значения, которое присваивается, преобразуется к типу переменной, получающей это значение. Допускается преобразования целых и плавающих типов, даже если такое преобразование ведет к потере информации.

Преобразование целых типов со знаком. Целое со знаком преобразуется к более короткому целому со знаком, посредством усечения старших битов. Целая со знаком преобразуется к более длинному целому со знаком, путем размножения знака. При преобразовании целого со знаком к целому без знака, целое со знаком преобразуется к размеру целого без знака и результат рассматривается как значение без знака.

Преобразование целого со знаком к плавающему типу происходит без потери] информации, за исключением случая преобразования значения типа long int или unsigned long int к типу float, когда точность часто может быть потеряна.

Преобразование целых типов без знака. Целое без знака преобразуется к более короткому целому без знака или со знаком путем усечения старших битов. Целое без знака преобразуется к более длинному целому без знака или со знаком путем дополнения нулей слева.

Когда целое без знака преобразуется к целому со знаком того же размера, битовое представление не изменяется. Поэтому значение, которое оно представляет, изменяется, если знаковый бит установлен (равен 1), т.е. когда исходное целое без знака больше чем максимальное положительное целое со знаком, такой же длины.

Целые значения без знака преобразуются к плавающему типу, путем преобразования целого без знака к значению типа signed long, а затем значение signed long преобразуется в плавающий тип. Преобразования из unsigned long к типу float, double или long double производятся с потерей информации, если преобразуемое значение больше, чем максимальное положительное значение, которое может быть представлено для типа long.

Преобразования плавающих типов. Величины типа float преобразуются к типу double без изменения значения. Величины double и long double преобразуются к float c некоторой потерей точности. Если значение слишком велико для float, то происходит потеря значимости, о чем сообщается во время выполнения.

При преобразовании величины с плавающей точкой к целым типам она сначала преобразуется к типу long (дробная часть плавающей величины при этом отбрасывается), а затем величина типа long преобразуется к требуемому целому типу. Если значение слишком велико для long, то результат преобразования не определен.

Преобразования из float, double или long double к типу unsigned long производится с потерей точности, если преобразуемое значение больше, чем максимально возможное положительное значение, представленное типом long.

Преобразование типов указателя. Указатель на величину одного типа может быть преобразован к указателю на величину другого типа. Однако результат может быть не определен из-за отличий в требованиях к выравниванию и размерах для различных типов.

Указатель на тип void может быть преобразован к указателю на любой тип, и указатель на любой тип может быть преобразован к указателю на тип void без ограничений. Значение указателя может быть преобразовано к целой величине. Метод преобразования зависит от размера указателя и размера целого типа следующим образом:

- если размер указателя меньше размера целого типа или равен ему, то указатель преобразуется точно так же, как целое без знака;

- если указатель больше, чем размер целого типа, то указатель сначала преобразуется к указателю с тем же размером, что и целый тип, и затем преобразуется к целому типу.

Целый тип может быть преобразован к адресному типу по следующим правилам:

- если целый тип того же размера, что и указатель, то целая величина просто рассматривается как указатель (целое без знака);

- если размер целого типа отличен от размера указателя, то целый тип сначала преобразуется к размеру указателя (используются способы преобразования, описанные выше), а затем полученное значение трактуется как указатель.

Преобразования при вызове функции. Преобразования, выполняемые над аргументами при вызове функции, зависят от того, был ли задан прототип функции (объявление "вперед") со списком объявлений типов аргументов.

Если задан прототип функции и он включает объявление типов аргументов, то над аргументами в вызове функции выполняются только обычные арифметические преобразования.

Эти преобразования выполняются независимо для каждого аргумента. Величины типа float преобразуются к double, величины типа char и short преобразуются к int, величины типов unsigned char и unsigned short преобразуются к unsigned int. Могут быть также выполнены неявные преобразования переменных типа указатель. Задавая прототипы функций, можно переопределить эти неявные преобразования и позволить компилятору выполнить контроль типов.

Преобразования при приведении типов. Явное преобразование типов может быть осуществлено посредством операции приведения типов, которая имеет формат:

( имя-типа ) операнд .

В приведенной записи имя-типа задает тип, к которому должен быть преобразован операнд.

Приклад:
int i=2;

long l=2;

double d;

float f;

d=(double)i * (double)l;

f=(float)d;

В данном примере величины i,l,d будут явно преобразовываться к указанным в круглых скобках типам.

  1. Операторы языка Си

Все операторы языка СИ могут быть условно разделены на следующие категории:

- условные операторы, к которым относятся оператор условия if и оператор выбора switch;

- операторы цикла (for,while,do while);

- операторы перехода (break, continue, return, goto);

- другие операторы (оператор "выражение", пустой оператор).

Операторы в программе могут объединяться в составные операторы с помощью фигурных скобок. Любой оператор в программе может быть помечен меткой, состоящей из имени и следующего за ним двоеточия.

Все операторы языка СИ, кроме составных операторов, заканчиваются точкой с запятой ";".
  1. ^

    Оператор выражение


Любое выражение, которое заканчивается точкой с запятой, является оператором.

Выполнение оператора выражение заключается в вычислении выражения. Полученное значение выражения никак не используется, поэтому, как правило, такие выражения вызывают побочные эффекты. Заметим, что вызвать функцию, невозвращающую значения можно только при помощи оператора выражения. Правила вычисления выражений были сформулированы выше.

Приклади:

++ i;

Этот оператор представляет выражение, которое увеличивает значение переменной i на единицу.

a=cos(b * 5);

Этот оператор представляет выражение, включающее в себя операции присваивания и вызова функции.

a(x,y);

Этот оператор представляет выражение состоящее из вызова функции.
  1. ^

    Пустой оператор


Пустой оператор состоит только из точки с запятой. При выполнении этого оператора ничего не происходит. Он обычно используется в следующих случаях:

- в операторах do, for, while, if в строках, когда место оператора не требуется, но по синтаксису требуется хотя бы один оператор;

- при необходимости пометить фигурную скобку.

Синтаксис языка СИ требует, чтобы после метки обязательно следовал оператор. Фигурная же скобка оператором не является. Поэтому, если надо передать управление на фигурную скобку, необходимо использовать пустой оператор.

Приклад:
int main ( )

{

:

{ if (...) goto a; /* переход на скобку */

{ ...

}

a:; }

return 0;

}
  1. ^

    Составной оператор


Составной оператор представляет собой несколько операторов и объявлений, заключенных в фигурные скобки:
{ [oбъявление]

:

оператор; [оператор];

:

}

Заметим, что в конце составного оператора точка с запятой не ставится.

Выполнение составного оператора заключается в последовательном выполнении составляющих его операторов.

Приклад:
int main ()

{

int q,b;

double t,d;

:

if (...)

{

int e,g;

double f,q;

:

}

:

return (0);

}

Переменные e,g,f,q будут уничтожены после выполнения составного оператора. Отметим, что переменная q является локальной в составном операторе, т.е. она никоим образом не связана с переменной q объявленной в начале функции main с типом int. Отметим также, что выражение стоящее после return может быть заключено в круглые скобки, хотя наличие последних необязательно.
  1. ^

    Оператор if


Формат оператора:

if (выражение) оператор-1; [else оператор-2;]

Выполнение оператора if начинается с вычисления выражения.

Далее выполнение осуществляется по следующей схеме:

- если выражение истинно (т.е. отлично от 0), то выполняется оператор-1.

- если выражение ложно (т.е. равно 0),то выполняется оператор-2.

- если выражение ложно и отсутствует оператор-2 (в квадратные скобки заключена необязательная конструкция), то выполняется следующий за if оператор.

После выполнения оператора if значение передается на следующий оператор программы, если последовательность выполнения операторов программы не будет принудительно нарушена использованием операторов перехода.

Приклад:
if (i < j) i++:

else { j = i-3; i + +; }

Этот пример иллюстрирует также и тот факт, что на месте оператор-1, так же как и на месте оператор-2 могут находиться сложные конструкции.

Допускается использование вложенных операторов if. Оператор if может быть включен в конструкцию if или в конструкцию else другого оператора if. Чтобы сделать программу более читабельной, рекомендуется группировать операторы и конструкции во вложенных операторах if, используя фигурные скобки. Если же фигурные скобки опущены, то компилятор связывает каждое ключевое слово else с наиболее близким if, для которого нет else.

Приклади:
int main ( )

{

int t=2, b=7, r=3;

if (t>b)

{

if (b < r) r=b;

}

else r=t;

return (0);

}

В результате выполнения этой программы r станет равным 2.

Если же в программе опустить фигурные скобки, стоящие после оператора if, то программа будет иметь следующий вид:
int main ( )

{

int t=2,b=7,r=3;

if ( a>b )

if ( b < c ) t=b;

else r=t;

return (0);

}

В этом случае r получит значение равное 3, так как ключевое слово else относится ко второму оператору if, который не выполняется, поскольку не выполняется условие, проверяемое в первом операторе if.

Следующий фрагмент иллюстрирует вложенные операторы if:
char ZNAC;

int x,y,z;

:

if (ZNAC == '-') x = y - z;

else if (ZNAC == '+') x = y + z;

else if (ZNAC == '*') x = y * z;

else if (ZNAC == '/') x = y / z;

else ...

Из рассмотрения этого примера можно сделать вывод, что конструкции использующие вложенные операторы if, являются довольно громоздкими и не всегда достаточно надежными. Другим способом организации выбора из множества различных вариантов является использование специального оператора выбора switch.
  1. ^

    Оператор switch


Оператор switch предназначен для организации выбора из множества различных вариантов. Формат оператора следующий:
switch ( выражение )

{ [объявление]

:

[ case константное-выражение1]: [ список-операторов1]

[ case константное-выражение2]: [ список-операторов2]

:

:

[ default: [ список операторов ]]

}

Выражение, следующее за ключевым словом switch в круглых скобках, может быть любым выражением, допустимыми в языке СИ, значение которого должно быть целым. Отметим, что можно использовать явное приведение к целому типу, однако необходимо помнить о тех ограничениях и рекомендациях, о которых говорилось выше.

Значение этого выражения является ключевым для выбора из нескольких вариантов. Тело оператора smitch состоит из нескольких операторов, помеченных ключевым словом case с последующим константным-выражением. Следует отметить, что использование целого константного выражения является существенным недостатком, присущим рассмотренному оператору.

Так как константное выражение вычисляется во время трансляции, оно не может содержать переменные или вызовы функций. Обычно в качестве константного выражения используются целые или символьные константы.

Все константные выражения в операторе switch должны быть уникальны. Кроме операторов, помеченных ключевым словом case, может быть, но обязательно один, фрагмент помеченный ключевым словом default.

Список операторов может быть пустым, либо содержать один или более операторов. Причем в операторе switch не требуется заключать последовательность операторов в фигурные скобки.

Отметим также, что в операторе switch можно использовать свои локальные переменные, объявления которых находятся перед первым ключевым словом case, однако в объявлениях не должна использоваться инициализация.

Схема выполнения оператора switch следующая:

- вычисляется выражение в круглых скобках;

- вычисленные значения последовательно сравниваются с константными выражениями, следующими за ключевыми словами case;

- если одно из константных выражений совпадает со значением выражения, то управление передается на оператор, помеченный соответствующим ключевым словом case;

- если ни одно из константных выражений не равно выражению, то управление передается на оператор, помеченный ключевым словом default, а в случае его отсутствия управление передается на следующий после switch оператор.

Отметим интересную особенность использования оператора switch: конструкция со словом default может быть не последней в теле оператора switch. Ключевые слова case и default в теле оператора switch существенны только при начальной проверке, когда определяется начальная точка выполнения тела оператора switch. Все операторы, между начальным оператором и концом тела, выполняются вне зависимости от ключевых слов, если только какой-то из операторов не передаст управления из тела оператора switch. Таким образом, программист должен сам позаботится о выходе из case, если это необходимо. Чаще всего для этого используется оператор break.

Для того, чтобы выполнить одни и те же действия для различных значений выражения, можно пометить один и тот же оператор несколькими ключевыми словами case.

Приклад:
int i=2;

switch (i)

{

case 1: i += 2;

case 2: i *= 3;

case 0: i /= 2;

case 4: i -= 5;

default: ;

}

Выполнение оператора switch начинается с оператора, помеченного case 2. Таким образом, переменная i получает значение, равное 6, далее выполняется оператор, помеченный ключевым словом case 0, а затем case 4, переменная i примет значение 3, а затем значение -2. Оператор, помеченный ключевым словом default, не изменяет значения переменной.

Рассмотрим ранее приведенный пример, в котором иллюстрировалось использование вложенных операторов if, переписанной теперь с использованием оператора switch.
char ZNAC;

int x,y,z;

switch (ZNAC)

{

case '+': x = y + z; break;

case '-': x = y - z; break;

case '*': x = y * z; break;

case '/': x = u / z; break;

default : ;

}

Использование оператора break позволяет в необходимый момент прервать последовательность выполняемых операторов в теле оператора switch, путем передачи управления оператору, следующему за switch.

Отметим, что в теле оператора switch можно использовать вложенные операторы switch, при этом в ключевых словах case можно использовать одинаковые константные выражения.

Приклад:
:

switch (a)

{

case 1: b=c; break;

case 2:

switch (d)

{ case 0: f=s; break;

case 1: f=9; break;

case 2: f-=9; break;

}

case 3: b-=c; break;

:

}
  1. ^

    Оператор break


Оператор break обеспечивает прекращение выполнения самого внутреннего из объединяющих его операторов switch, do, for, while. После выполнения оператора break управление передается оператору, следующему за прерванным.
  1. ^

    Оператор for


Оператор for - это наиболее общий способ организации цикла. Он имеет следующий формат:

for ( выражение 1 ; выражение 2 ; выражение 3 ) тело

Выражение 1 обычно используется для установления начального значения переменных, управляющих циклом. Выражение 2 - это выражение, определяющее условие, при котором тело цикла будет выполняться. Выражение 3 определяет изменение переменных, управляющих циклом после каждого выполнения тела цикла.

Схема выполнения оператора for:

1. Вычисляется выражение 1.

2. Вычисляется выражение 2.

3. Если значения выражения 2 отлично от нуля (истина), выполняется тело цикла, вычисляется выражение 3 и осуществляется переход к пункту 2, если выражение 2 равно нулю (ложь), то управление передается на оператор, следующий за оператором for.

Существенно то, что проверка условия всегда выполняется в начале цикла. Это значит, что тело цикла может ни разу не выполниться, если условие выполнения сразу будет ложным.

Приклад:
int main ()

{ int i,b;

for (i=1; i<10; i++)

b=i*i;

return 0;

}

В этом примере вычисляются квадраты чисел от 1 до 9.

Некоторые варианты использования оператора for повышают его гибкость за счет возможности использования нескольких переменных, управляющих циклом.

Приклад:
int main ()

{ int top, bot;

char string[100], temp;

for ( top=0, bot=100 ; top < bot ; top++, bot--)

{ temp=string[top];

string[bot]=temp;

}

return 0;

}

В этом примере, реализующем запись строки символов в обратном порядке, для управления циклом используются две переменные top и bot. Отметим, что на месте выражение 1 и выражение 3 здесь используются несколько выражений, записанных через запятую, и выполняемых последовательно.

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

Приклад:
for (;;)

{ ...

... break;

...

}

Так как согласно синтаксису языка Си оператор может быть пустым, тело оператора for также может быть пустым. Такая форма оператора может быть использована для организации поиска.

Приклад:

for (i=0; t[i]<10 ; i++) ;

В данном примере переменная цикла i принимает значение номера первого элемента массива t, значение которого больше 10.
  1. ^

    Оператор while


Оператор цикла while называется циклом с предусловием и имеет следующий формат:

while (выражение) тело ;

В качестве выражения допускается использовать любое выражение языка Си, а в качестве тела любой оператор, в том числе пустой или составной. Схема выполнения оператора while следующая:

1. Вычисляется выражение.

2. Если выражение ложно, то выполнение оператора while заканчивается и выполняется следующий по порядку оператор. Если выражение истинно, то выполняется тело оператора while.

3. Процесс повторяется с пункта 1.

Оператор цикла вида

for (выражение-1; выражение-2; выражение-3) тело ;

может быть заменен оператором while следующим образом:
выражение-1;

while (выражение-2)

{ тело

выражение-3;

}

Так же как и при выполнении оператора for, в операторе while вначале происходит проверка условия. Поэтому оператор while удобно использовать в ситуациях, когда тело оператора не всегда нужно выполнять.

Внутри операторов for и while можно использовать локальные переменные, которые должны быть объявлены с определением соответствующих типов.
  1. ^

    Оператор do while


Оператор цикла do while называется оператором цикла с постусловием и используется в тех случаях, когда необходимо выполнить тело цикла хотя бы один раз. Формат оператора имеет следующий вид:

do тело while (выражение);

Схема выполнения оператора do while :

1. Выполняется тело цикла (которое может быть составным оператором).

2. Вычисляется выражение.

3. Если выражение ложно, то выполнение оператора do while заканчивается и выполняется следующий по порядку оператор. Если выражение истинно, то выполнение оператора продолжается с пункта 1.

Чтобы прервать выполнение цикла до того, как условие станет ложным, можно использовать оператор break.

Операторы while и do while могут быть вложенными.

Приклад:
int i,j,k;

...

i=0; j=0; k = 0;

do { i++;

j--;

while (a[k] < i) k++;

}

while (i<30 && j<-30);
  1. ^

    Оператор continue


Оператор continue, как и оператор break, используется только внутри операторов цикла, но в отличие от него выполнение программы продолжается не с оператора, следующего за прерванным оператором, а с начала прерванного оператора. Формат оператора следующий:

continue;

Приклад:
int main ()

{ int a,b;

for (a=1,b=0; a<100; b+=a,a++)

{ if (b%2) continue;

... /* обработка четных сумм */

}

return 0;

}

Когда сумма чисел от 1 до а становится нечетной, оператор continue передает управление на очередную итерацию цикла for, не выполняя операторы обработки четных сумм.

Оператор continue, как и оператор break, прерывает самый внутренний из объемлющих его циклов.
  1. ^

    Оператор return


Оператор return завершает выполнение функции, в которой он задан, и возвращает управление в вызывающую функцию, в точку, непосредственно следующую за вызовом. Функция main передает управление операционной системе. Формат оператора:

return [выражение] ;

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

Если в какой-либо функции отсутствует оператор return, то передача управления в вызывающую функцию происходит после выполнения последнего оператора вызываемой функции. При этом возвращаемое значение не определено. Если функция не должна иметь возвращаемого значения, то ее нужно объявлять с типом void.

Таким образом, использование оператора return необходимо либо для немедленного выхода из функции, либо для передачи возвращаемого значения.

Приклад:
int sum (int a, int b)

{ renurn (a+b); }

Функция sum имеет два формальных параметра a и b типа int, и возвращает значение типа int, о чем говорит описатель, стоящий перед именем функции. Возвращаемое оператором return значение равно сумме фактических параметров.

Приклад:
void prov (int a, double b)

{ double c;

if (a<3) return;

else if (b>10) return;

else { c=a+b;

if ((2*cb)==11) return;

}

}

В этом примере оператор return используется для выхода из функции в случае выполнения одного из проверяемых условий.
  1. ^

    Оператор goto


Использование оператора безусловного перехода goto в практике программирования на языке СИ настоятельно не рекомендуется, так как он затрудняет понимание программ и возможность их модификаций.

Формат этого оператора следующий:
goto имя-метки;

...

имя-метки: оператор;

Оператор goto передает управление на оператор, помеченный меткой имя-метки. Помеченный оператор должен находиться в той же функции, что и оператор goto, а используемая метка должна быть уникальной, т.е. одно имя-метки не может быть использовано для разных операторов программы. Имя-метки - это идентификатор.

Любой оператор в составном операторе может иметь свою метку. Используя оператор goto, можно передавать управление внутрь составного оператора. Но нужно быть осторожным при входе в составной оператор, содержащий объявления переменных с инициализацией, так как объявления располагаются перед выполняемыми операторами и значения объявленных переменных при таком переходе будут не определены.
  1. ^

    Препроцессорные директивы


Директивы препроцессора представляют собой инструкции, записанные в тексте программы на СИ, и выполняемые до трансляции программы. Директивы препроцессора позволяют изменить текст программы, например, заменить некоторые лексемы в тексте, вставить текст из другого файла, запретить трансляцию части текста и т.п. Все директивы препроцессора начинаются со знака #. После директив препроцессора точка с запятой не ставятся.
  1. ^

    Директива # include


Директива #include включает в текст программы содержимое указанного файла. Эта директива имеет две формы:
#include "имя файла"

#include <имя файла>

Имя файла должно соответствовать соглашениям операционной системы и может состоять либо только из имени файла, либо из имени файла с предшествующим ему маршрутом. Если имя файла указано в кавычках, то поиск файла осуществляется в соответствии с заданным маршрутом, а при его отсутствии в текущем каталоге. Если имя файла задано в угловых скобках, то поиск файла производится в стандартных директориях операционной системы, задаваемых командой PATH.

Директива #include может быть вложенной, т.е. во включаемом файле тоже может содержаться директива #include, которая замещается после включения файла, содержащего эту директиву.

Директива #include широко используется для включения в программу так называемых заголовочных файлов, содержащих прототипы библиотечных функций, и поэтому большинство программ на СИ начинаются с этой директивы.
  1. ^

    Директива #define


Директива #define служит для замены часто использующихся констант, ключевых слов, операторов или выражений некоторыми идентификаторами. Идентификаторы, заменяющие текстовые или числовые константы, называют именованными константами. Идентификаторы, заменяющие фрагменты программ, называют макроопределениями, причем макроопределения могут иметь аргументы.

Директива #define имеет две синтаксические формы:
#define идентификатор текст

#define идентификатор (список параметров) текст

Эта директива заменяет все последующие вхождения идентификатора на текст. Такой процесс называется макроподстановкой. Текст может представлять собой любой фрагмент программы на СИ, а также может и отсутствовать. В последнем случае все экземпляры идентификатора удаляются из программы.

Приклад:
#define WIDTH 80

#define LENGTH (WIDTH+10)

Эти директивы изменят в тексте программы каждое слово WIDTH на число 80, а каждое слово LENGTH на выражение (80+10) вместе с окружающими его скобками.

Скобки, содержащиеся в макроопределении, позволяют избежать недоразумений, связанных с порядком вычисления операций. Например, при отсутствии скобок выражение t=LENGTH*7 будет преобразовано в выражение t=80+10*7, а не в выражение t=(80+10)*7, как это получается при наличии скобок, и в результате получится 780, а не 630.

Во второй синтаксической форме в директиве #define имеется список формальных параметров, который может содержать один или несколько идентификаторов, разделенных запятыми. Формальные параметры в тексте макроопределения отмечают позиции на которые должны быть подставлены фактические аргументы макровызова. Каждый формальный параметр может появиться в тексте макроопределения несколько раз.

При макровызове вслед за идентификатором записывается список фактических аргументов, количество которых должно совпадать с количеством формальных параметров.
Приклад:

#define MAX(x,y) ((x)>(y))?(x):(y)

Эта директива заменит фрагмент

t=MAX(i,s[i]);

на фрагмент

t=((i)>(s[i])?(i):(s[i]);

Как и в предыдущем примере, круглые скобки, в которые заключены формальные параметры макроопределения, позволяют избежать ошибок связанных с неправильным порядком выполнения операций, если фактические аргументы являются выражениями.
Например, при наличии скобок фрагмент

t=MAX(i&j,s[i]||j);

будет заменен на фрагмент

t=((i&j)>(s[i]||j)?(i&j):(s[i]||j);

а при отсутствии скобок - на фрагмент

t=(i&j>s[i]||j)?i&j:s[i]||j;

в котором условное выражение вычисляется в совершенно другом порядке.


  1. ^ Ввод. вывод в языке Си.

Операции ввода/вывода в языке Си организованы посредством библиотечных функций (причем их довольно много).

Самый простой механизм ввода - чтение по одному символу из стандартного входного потока (с клавиатуры) с помощью функции getchar( ). Она имеет следующий прототип (т.е. описание заголовка):

int getchar(void);

Здесь определен тип единственного аргумента (void) и тип возвращаемого функцией значения (int).

Оператор вида:

х = getchar( );

присваивает переменной х очередной вводимый символ. Переменная х должна иметь символьный или целый тип.

Другая функция - putchar(х) выдает значение переменной x в стандартный выходной поток (на экран дисплея). Функция putchar( ) имеет прототип:

int putchar(int);

Объявления getchar( ) и putchar( ) сделаны в заголовочном файле stdio.h, содержащем описания заголовков библиотечных функций стандартного ввода/вывода. Чтобы библиотечные функции стали доступны программе, к ней необходимо подключить данный файл. Подключение осуществляется с помощью директивы препроцессора

# Include <stdio.h>

помещаемой в начало программы (подробнее см. в разделе 5).

Заметим, что для функции getchar( ) после выбора символа необходимо нажать клавишу <Enter>. Иногда это создает определенные неудобства. Функции getch( ) и getche( ) устраняют их. Они имеют следующие прототипы:

int getch(void);

int getche(void);

Обе эти функции вводят символ сразу же после нажатия соответствующей клавиши (здесь не надо дополнительно нажимать клавишу <Enter>). Отличие между ними заключается в том, что getche( ) отображает вводимый символ на экране дисплея, а getch( ) - нет. Прототипы этих функций содержатся в файле conio.h (консольный ввод/вывод). Для их использования файл conio.h также следует подключить к программе с помощью директивы #include .



  1. Форматированный вывод данных


Функция printf( ) (прототип содержится в файле stdio.h) обеспечивает форматированный вывод. Ее можно записать в следующем формальном виде:

рrintf ("управляющая строка", аргумент _1, аргумент _2,...);

Управляющая строка содержит компоненты трех типов: обычные символы, которые просто копируются в стандартный выходной поток (выводятся на экран дисплея); спецификации преобразования, каждая из которых вызывает вывод на экран очередного аргумента из последующего списка; управляющие символьные константы.

Каждая спецификация преобразования начинается со знака % и заканчивается некоторым символом, задающим преобразование. Между знаком % и символом преобразования могут встречаться другие знаки в соответствии со следующим форматом:

% [признаки] [ширина_поля] [точность] [F|N|h|l|L] c_n

Все параметры в квадратных скобках не являются обязательными.

На месте параметра c_n (символ преобразования) могут быть записаны:

с - значением аргумента является символ;
d или i - значением аргумента является десятичное целое число;
е - значением аргумента является вещественное десятичное число в экспоненциальной форме вида 1.23e+2;
Е - значением аргумента является вещественное десятичное число в экспоненциальной форме вида 1.23E+2;
f - значением аргумента является вещественное десятичное число с плавающей точкой;
g (или G) - используется, как е или f, и исключает вывод незначащих нулей;
о - значением аргумента является восьмеричное целое число;
s - значением аргумента является строка символов (символы строки выводятся до тех пор, пока не встретится символ конца строки или же не будет, выведено число символов, заданное точностью);
u - значением аргумента является беззнаковое целое число;
х - значением аргумента является шестнадцатеричное целое число с цифрами 0,..., 9, а, b, с, d, е, f;
^ X - значением аргумента является шестнадцатеричное целое число с цифрами 0,..., 9, А, В, С, О, Е, F;
р - значением аргумента является указатель;
n - применяется в операциях форматирования. Аргумент, соответствующий этому символу спецификации, должен быть указателем на целое. В него возвращается номер позиции строки (отображаемой на экране), в которой записана спецификация %n.

Необязательные параметры в спецификации преобразования:

Если после знака % записан не символ преобразования, то он выводится на экран. Таким образом, строка %% приводит к выводу на экран знака %.

Функция printf( ) использует управляющую строку, чтобы определить, сколько всего аргументов и каковы их типы. Аргументами могут быть переменные, константы, выражения, вызовы функций; главное, чтобы их значения соответствовали заданной спецификации.

При наличии ошибок, например, в числе аргументов или типе преобразования результаты будут неверными.

Среди управляющих символьных констант наиболее часто используются следующие:

\а - для кратковременной подачи звукового сигнала;
\b - для перевода курсора влево на одну позицию;
\f - для подачи формата;
\n - для перехода на новую строку;
\r - для возврата каретки;
\t - горизонтальная табуляция;
\v - вертикальная табуляция;
\\ - вывод символа \;
\' - вывод символа ' ;
\" - вывод символа ";
\? - вывод символа ?.

Например, в результате вызова функции:

printf("\tComputer\n%d\n", i);

сначала выполняется горизонтальная табуляция (\t), т.е. курсор сместится от края экрана, затем на экран будет выведено слово Computer, после этого курсор переместится в начало следующей строки (\n), затем будет выведено целое число i по формату %d (десятичное целое), и окончательно курсор перейдет в начало новой строки (\n).

Напечатать строку символов можно и так:

printf("Это строка символов");




  1. ^

    Форматированный ввод данных


Функция scanf( ) (прототип содержится в файле stdio.h) обеспечивает форматированный ввод. Ее можно записать в следующем формальном виде:

scanf("управляющая строка", аргумент_1, аргумент_2,...);

Аргументы scanf( ) должны быть указателями на соответствующие значения. Для этого перед именем переменной записывается символ &. Назначение указателей будет рассмотрено далее.

Управляющая строка содержит спецификации преобразования и используется для установления количества и типов аргументов. В нее могут включаться:

Рассмотрим символы преобразования функции scanf( ) (указываются после символа %):

с - на входе ожидается появление одиночного символа;
d или i - на входе ожидается десятичное целое число и аргумент является указателем на переменную типа int;
D или l - на входе ожидается десятичное целое число и аргумент является указателем на переменную типа long;
е или Е - на входе ожидается вещественное число с плавающей точкой;
f - на входе ожидается вещественное число с плавающей точкой;
g или G - на входе ожидается вещественное число с плавающей точкой;
о - на входе ожидается восьмеричное целое число и аргумент является указателем на переменную типа int;
О - на входе ожидается восьмеричное целое число и аргумент является указателем на переменную типа long;
s - на входе ожидается появление строки символов;
х - на входе ожидается шестнадцатеричное целое число и аргумент является указателем на переменную типа int;
^ Х - на входе ожидается шестнадцатеричное целое число и аргумент является указателем на переменную типа long;
р - на входе ожидается появление указателя в виде шестнадцатеричного числа;
n - применяется в операциях форматирования. Аргумент, соответствующий этому символу спецификации, должен быть указателем на целое. В него возвращается номер позиции (после ввода), в которой записана спецификация %n;
u - на входе ожидается беззнаковое целое число и аргумент является указателем на переменную типа unsigned int;
U - на входе ожидается беззнаковое целое число и аргумент является указателем на переменную типа unsigned long;
[ ] - сканирует входную строку для получения символов.

Перед некоторыми символами преобразования могут записываться следующие модификаторы:

^ F - изменяет указатель, заданный по умолчанию, на указатель типа far;
N - изменяет указатель, заданный по умолчанию, на указатель типа near;
h - преобразует аргумент к типу short int (может записываться перед символами d, i, о, u, х);
l - преобразует аргумент к типу long int (может записываться перед символами d, i, o, u, x);
L - преобразует аргумент к типу long double (может записываться перед символами е, f, g).

Ввести целое число (int a;), символ (char b;) и вещественное число (float t;) можно так:

scanf("%d", &a);

scanf("%c", &b);

scanf("%c", &b);

или так:

scanf("%d%c%f",&a, &b, &t);
Навчальний матеріал
© uadoc.zavantag.com
При копіюванні вкажіть посилання.
звернутися до адміністрації