Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lexzii_08 / lexs_1_vstup.doc
Скачиваний:
20
Добавлен:
17.05.2015
Размер:
142.34 Кб
Скачать

Приклади використання форматного введення - виведення

#include stdio.h

main ()

{

char s [ ]; /* об'ява рядка символів */

float a = 86.531;

printf ( ” % s \n ”, ” Кафедра ПЗ ”); /* виведення рядка символів */

printf ( ” ввести рядок символів \n”)

scanf ( ” % ”, s);

printf ( ” _ _ _ 20 s ; %20s \n”, s ); /* заданий мінімальний розмір поля (20 символів)*/

printf ( ” (_ _ _ -20s ) ; % 20s \n ” , s); /* знак ”-” вказує, що рядок s буде виводитись починаючи з ліво мітки поля (вирівняння зліва)*/

}

Кафедра пз

Ввести рядок символів

ВДТУ

( _ _ _ 20 s) ВДТУ

( _ _ _ -20s) ВДТУ

printf ( ” ввести рядок символів \n”);

scanf ( ” %3s \n ”, s); /* з рядка буде введено 3 символа */

printf ( ” c = %”, c );

результат:

ввести рядок символів

Вінниця

С = Він

В приведених прикладах виводиться підказка на екран і потім переводиться курсор \n за допомогою.

Для аналогічної мети в Сі є функція puts, яка виконує те ж саме, але без символа \n . Друга функція gets дозволяє вводити рядок символів. Приклад використання:

#include stdio.h

main ()

{

char q [40]; /*об‘ява рядка символів */

puts (” введіть рядок символів ”)

puts (q); /* введення рядка символів, який може містити проміжки */

puts (q); /* виведення рядка символів */

}

введіть рядок символів

Привіт з Вінниці

Привіт з Вінниці

Зверніть увагу на те, що при введенні рідка в функції gets на відмінність від функції scanf можна використовувати проміжки.

Цей приклад демонструє виведення значень покажчика або адреси:

#include stdio.h

main ()

{ int a, *b; /* об’ява цілого числа а і цілого числа, записаного за адресою */

b = &a; /* покажчик b отримує значення адреси змінної а */

a = 7; /* зміна а отримує значення 7 */

printf (” адреса змінної a = %p\n ”, &a);

printf (” значення змінної a = %d\n ”, a);

printf (” значення покажчика b = %p\n”, b );

printf (” значення змінної по адресі b = %d\n”, *b);

}

Результати її роботи:

адреса змінної а = FFE2

значення змінної а = 7

значення покажчика b = FFE2

значення змінної по адресі b = 7

Пояснимо, що таке FFE0. Це число, представлене в 16-річному коді:

FFE0 = F163 + F162 + F161 + F160 = 65 504, що відповідає двійковому числу 1111 1111 1110 0000, що означає адресу зміщення початку слова в сегменті оперативної пам’яті комп’ютера, де зберігається значення змінної а. Якщо сегмент пам’яті , на якій вирішувалась ця задача має об’єм 64 Кбайт (65 536), то двохбайтне значення змінної а знаходиться десь в його кінці.

Покажчики і операції з адесами

Раніше згадувалось про покажчики, які є змінними, що містять адреси інших змінних. Тому, що покажчик – це адреса деякого об’єкту, то через нього можна звертатись до цього об’єкту.

Унарна операція & дає адресу змінної, тому оператор y = &x; присвоює адресу х змінній у.

З

Y = & X

начення х

Операцію & можна використовувати тільки до змінних і елементів масиву; конструкції вигляду &(x = 7) або &28 недопустимі.

Унарна операція * сприймає свій операнд, як адресу деякого об’єкту і використовує цю адресу для вибірки вмісту, тому оператор Z = * Y; присвоює значення змінної, записаної по адресі Y.

Y

*Y

Z = * Y

Якщо y = & x; z = * y, тоz = x, дивитись на рисунок:

Адреса Х

Значення х

Z = *Y

Значення Х

Про об’єкти, які складаються із знака * і адреси (наприклад, *а), необхідно повідомляти. Робиться це так:

int *a, *b, *c;

char * d;

Визначення виду char *d; говорить про те, що значення, записане за адресою d має тип char.

Покажчики можуть можуть зустрічатися і у виразах. Якщо у – покажчик на ціле значення , тобто мало місце визначення int *y, то *yможе з’явитись там, де і будь-яка інша змінна, яка не є покажчиком. Таким чином допустимі такі вирази:

*у = 7;

*х* = 5;

(*z) ++;

Перше з них заносить число 7 в комірку за адресою у, друге збільшує значення за адресоюхв 5 разів, третє – добавляє одиницю до вмісту комірки пам’яті з адресоюz.В останньому випадку круглі дужки необхідні тому, що операції * та ++ з однаковим приоритетом виконуються справа наліво. В результаті, якщо, наприклад, *z = 5,то (*z)++ приведе до того, що *z = 6, a *z++ тільки змінить адресуz(операція ++ виконується над адресоюz, а не над значенням*zпо цій адресі).

Покажчики можна використовувати як операнди в арифметичних операціях. Якщо у– покажчик, то унарна операціяу++збільшує його значення ; тепер воно є адресою поточного елементу. Покажчики і цілі числа можна додавати. Конструкція у+n(у – покажчик,n– ціле число) задає адресуn – го об’єкту, на який вказує у. Це справедливо для будь-яких об’єктів (int, char, float…). Транслятор буде масштабувати приріст адреси у відповідності з типом, визначеним з відповідної об’яви (int *y; char*y; float *y; і т.п.). Вираз у+=nозначає виконання тих же дій, що і у = у +n;

Будь-яку адресу можливо перевірити на рівність (= =) або нерівність (!=)зі спеціальним значенням NULL, яке записується замість нуля. СловоNULLдозволяє визначити покажчик, який нічого не адресує.

Приклад програми, яка використовує покажчики:

#include stdio.h

main ()

{

unsigned char *a,*b;

const char S[] = ” ВНТУ ”;

printf (”адрес S[]:% p\n”, S); /* на екран дисплея виведеться адреса першого елемента в рядкуS */;

puts (”введіть через кому значення покажчика і символ ”);

/* показано, як переносити текст в функції виведення, якщо він дуже довгий для одного рядка */

scanf(”% р, % с”,&d, &b); /*введення значень покажчика і символа */

*a = b;

printf (”значенняbдорівнює:% c \n ”, b);

printf(” значенняbзаписаного по адресі:% p \n ”, &b);

printf (” За адресою а записане число:% d \n ”, *a);

printf (” значення покажчика а дорівнює:% p \n ”, a);

printf (” % s \n ” , s);

printf (” *++a = %d; *( a + 2 ) =% d; ++*a = % d; *a + 2 =% d ”, *++a, *(a + 2 ), ++*a, *a + 2);

}

Результати виконання можна представити приблизно так:

Адреса S[ ] : FFDC

Введіть через кому значення покажчика і символ f f e 3 , 2

Значення bдорівнює : 2

Значення bзаписане по адресі :FFDB

За адресою а записане число : 50

Значення покажчика а дорівнює : FFE3

ВДТУ

*++a = 17; *(a + 2) = 1; ++*a = 51; *a + 2 = 52;

Введене значення покажчика d ffe3 в 16-му коді і значення “2” символаb. Номер символа “2” в код. Таблиці дорівнює 50. Прокоментуємо останній рядок:

*++a– це значення типуunsigned char, записане по адресі ffe4;

*(a + 2) – це значення по адресі, збільшеній відносно а на дві масштабні одиниці ( в прикладіffe5);

++*a– це значення по адресі а , збільшене на 1 ( в прикладі номер символа “2” плюс 1 , тобто 50 + 1 = 51);

*a + 2– це значення по адресі а, збільшене на 2 ( в прикладі

50 + 2 = 52);

Зверніть увагу, що унарна операція * має більш високий пріоритет, ніж бінарна операція + .

Домашнє завдання:ввести замість адресиffe3 ffdc + 1 = ffdd,а замість “2” знак “!”. Що буде?

Перетворення типів

Повинні використовуватись змінні і константи одного типу. При змішуванні компілятор Сі не вважає програму правильною, як це було на Паскалі. Замість цього компілятор використовує набір правил для перетворення типів.

Основні правила перетворення типів:

  1. Якщо виконується операція над змінними двох різних типів, обидві величини приводяться до “вищого” з двох типів. Цей процес називається “підвищенням” типу;

  2. Послідовність назв типів, впорядкованих від ”вищого” до “нижчого” виглядає наступним чином:

Double, float, long, int, short, char,

Застосування ключового слова unsignedпідвищує ранг відповідного типу данних зі знаком.

  1. В операторі присвоєння кінцевий результат обчислення виразу в правій частині приводиться до типу змінної, котрій було присвоєне це значення. Даний процес може призвести до “підвищення ” типу або до “пониження”, при якому величини приводяться до типу даних, що має більш низький пріоритет.

“Підвищення ” типу проходить гладко, а “пониження ” може призвести до ускладнень.

mice = 1.6 + 1.7 3.3 = 3

mice = ((int)1.6 + (int)1.7 ); 1 + 1 = 2

Питання для самоконтроля

  1. Чому мова Сі отримала таке поширене використання при програмуванні?

  2. Перелічіть етапи створення програми на мові Сі.

  3. Що таке препроцесор? Для чого він використовується?

  4. Які команди препроцесора ви знаєте?

  5. З чого складається будь-яка програма на мові Сі?

  6. З якої функції починається програма на мові Сі?

  7. Що входить до алфавіту мови Сі?

  8. Яка відмінність оператора присвоєння від арифметичних операцій Паскаля?

  9. Поясніть дію операцій інкремента і декремента.

  10. Правила використання коментарів в мові Сі.

  11. Які знаки логічних і порозрядних операцій в мові Сі ви знаєте?

  12. Які типи даних оголошують змінні цілого типу? Приклади.

  13. Які типи даних оголошують змінні дійсного типу? Приклади.

  14. Як збільшити діапазон значень для цілого і дійсного типів?

  15. Для чого призначений переліковий тип enum?

  16. Які ви знаєте символи перетворення в функції виведення printf?

  17. Які ви знаєте керуючі символьні константи ?

  18. Пояснити, як працює функція форматного введення.

  19. Які символи перетворення функції printf допускаються в функції scanf?

  20. Чому при форматному введенні масиву в функції scanfневикористовуєтьсязнак &?

  21. Яка функція дозволяє ввести тільки один символ?

  22. Що таке покажчик? Приклади використання.

  23. Як працює тернарна операція в мові Сі?

  24. Запишіть вираз мовою Сі: “Збільшити на одиницю вміст комірки пам’яті з адресою Z”.

  25. Запишіть вираз мовою Сі: “Збільшити значення по адресі х в 5 разів”

  26. Які ви знаєте правила перетворення типів?

  27. Поясніть приоритет виконання операцій мовою Сі.

Соседние файлы в папке lexzii_08