Название: Вказівки, масиви і символьні рядки в мові C
Вид работы: лабораторная работа
Рубрика: Информатика и программирование
Размер файла: 29.57 Kb
Скачать файл: referat.me-136594.docx
Краткое описание работы: Практичне використання і вживання інструментів мови C для роботи із складними агрегатами даних. Загальний підхід до різних програмних об'єктів: масив і рядок. Використання вказівок при роботі з масивами і рядками. Розробка завдання і алгоритму програми.
Вказівки, масиви і символьні рядки в мові C
Лабораторна робота
Вказівки, масиви і символьні рядки в мові C
програма вказівка масив символ рядок
1. Мета роботи
Метою лабораторної роботи є отримання практичних навиків в роботі з вказівниками і з адресною арифметикою в мові С.
2. Теоретичні відомості
В С++ існує надзвичайно потужний інструмент для роботи зі складними агрегатами даних, який надає загальний підхід до різних на перший погляд програмних об’єктів таких як масив та рядок. Цей і нструмент базується на широкому використанні вказівника.
Вказівник - це символічне представлення адреси. Він використовується для непрямої адресації змінних і об'єктів.
В мові С++ є операція визначення адреси — &, за допомогою якої визначається адреса комірки пам’яті, що містить задану змінну. Наприклад, якщо vr — ім’я змінної, то &vr — адреса цієї змінної.
В С++ також існують і змінні типу вказівник. Значенням змінної типу вказівник є адреса змінної або об'єкта. Нехай змінна типу вказівник має ім'я ptr, тоді в якості значення їй можна присвоїти адресу за допомогою наступного оператора:
ptr=&vr;
В мові С++ при роботі з вказівниками велике значення має операція непрямої адресації — *. Операція * дозволяє звертатися до змінної не напряму, а через вказівник, який містить адресу цієї змінної. Ця операція є одномісною і має асоціативність зліва направо. Цю операцію не слід плутати з бінарною операцією множення. Нехай ptr — вказівник, тоді *ptr — це значення змінної, на яку вказує ptr.
Опис змінних типу вказівник здійснюється за допомогою операторів наступної форми:
<тип> *<ім'я вказівника на змінну заданого типу>;
Кожна змінна в програмі це об'єкт, що має ім'я і значення по імені можна звернутися до змінного й одержати її значення.
Оператор присвоювання ( = ) виконує зворотну дію: імені змінної ставиться у відповідність значення.
a=10;
Вираз &a дозволяє одержати адресу ділянки пам'яті, виділеного змінній а. Операція & застосовна тільки до об'єктів, що мають ім'я і розміщених у пам'яті.
Маючи можливість визначити адреси змінної за допомогою &, треба мати можливість працювати з цією адресою: зберігати його, передавати, перетворювати.
Для цього вводиться поняття вказівника.
Вказівник - це змінна, значенням якої служить адреса об'єкта конкретного типу. Нульова адреса позначається константою NULL, що визначена в заголовному файлі stdio.h. Щоб визначити вказівник треба повідомити на об'єкт якого типу посилається цей вказівник.
char *z;
int *k,*i;
float *f;
* - це операція разіменування. Операндом цієї операції завжди є вказівник. Результат операції - це той об'єкт, що адресує вказівник_операнд.
*z=’$ ‘;
![]() |
![]() |
*k=*i=0;
Приклад:
int e, c, b, *m;
. . . . . . . . .
m = &e ;
*m = c + b ;
Операції над вказівниками.
присвоювання (=);
одержання значення об'єкта, на який посилається вказівник (*);
одержання адреси самого вказівника (&).
Приклад:
int date = 10;
int *i, *k;;
i = &date;
k = i;
z = NULL;
Подібно будь-яким змінної змінна типу вказівник має ім'я, арес у пам'яті і значення.
За допомогою унарних операцій ++ і –і числові значення змінних типу вказівник міняються по різному, у залежності від типу даних, з яким зв'язані ці змінні.
Приклад:
char *z;
int *k,*i;
float *f;
. . . . . . .
z++; // значення змінюється на 1
і++; // значення змінюється на 2
f++; // значення змінюється на 4
Тобто при зміні вказівника на 1, вказівник переходить до початку наступного (попереднього) поля тієї довжини, що визначається типом об'єкта, який адресується вказівником.
2.1 Використання вказівників при роботі з масивами
Ім'я масиву без індексу є вказівником-константою, тобто адресою першого елемента масиву (a[0]).
a
*a = = a[0] ;
*(a+1) = = a[1];
. . . . . . . . .
*(a+і) = =a[і];
Відповідно до синтаксису в С існують тільки одномірні масиви, але їх елементами , у свою чергу, теж можуть бути масиви.
int a[5][5];
Для двовимірного масиву:
a[m][n] = = *(a[m]+n) = = *(*(a+m)+n);
Приклад1. Опис вказівників.
int *ptri; //вказівник на змінну цілого типу
char *ptrc; //вказівник на змінну символьного типу
float *ptrf; //вказівник на змінну з плаваючою точкою
Такий спосіб оголошення вказівників виник внаслідок того, що змінні різних типів займають різну кількість комірок пам'яті. При цьому для деяких операцій з вказівниками необхідно знати об'єм відведеної пам'яті. Операція * в деякому розумінні є оберненою до операції &.
Вказівники використовуються для роботи з масивами. розглянемо оголошення двовимірного масиву:
int mas[4][2];
int *ptr;
Тоді вираз ptr=mas вказує на першу колонку першого рядка матриці. Записи mas і &mаs[0][0] рівносильні. Вираз ptr+1 вказує на mas[0][1], далі йдуть елементи: mas[1][0], mas[1][1], mas[2][0] і т. д.; ptr+5 вказує на mas[2][1].
Двовимірні масиви розташовані в пам’яті так само, як і одновимірні масиви, займаючи послідовні комірки пам’яті
ptr | ptr+1 | ptr+2 | ptr+3 | ptr+4 | ptr+5 |
mas[0][0] | mas[0][1] | mas[1][0] | mas[1][1] | mas[2][0] | mas[2][1] |
Розміщення двовимірного масиву в пам’яті
Динамічним називається масив, розмірність якого стає відомою в процесі виконання програми.
В С++ для роботи з динамічними об’єктами використовують спеціальні операції new і delete. За допомогою операції new виділяється пам’ять під динамічний об’єкт (який створюється в процесі виконання програми), а за допомогою операції delete створений об’єкт видаляється з пам’яті.
Приклад . Виділення пам’яті під динамічний масив.
Нехай розмірність динамічного масиву вводиться з клавіатури. Спочатку необхідно виділити пам’ять під цей масив, а потім створений динамічний масив треба видалити.
…
int n;
scanf(n; // n — розмірність масиву
int *mas=new int[n]; // виділення пам’яті під масив
delete [] mas; // звільнення пам’яті
…
В цьому прикладі mas є вказівником на масив з n елементів. Оператор int *mas=new int[n] виконує дві дії: оголошується змінна типу вказівник, далі вказівнику надається адреса виділеної області пам’яті у відповідності з заданим типом об’єкта.
Для цього ж прикладу можна задати наступну еквівалентну послідовність операторів:
…
int n, *mas;
scanf(n;// n - розмірність масиву
mas=new int[n];// виділення пам’яті під масив
delete [] mas;// звільнення пам’яті
…
Якщо за допомогою операції new неможливо виділити потрібний об’єм пам’яті, то результатом операції new є 0.
Іноді при програмуванні виникає необхідність створення багатовимірних динамічних об’єктів. Програмісти-початківці за аналогією з поданим способом створення одновимірних динамічних масивів для двовимірного динамічного масиву розмірності n*k запишуть наступне
mas=new int[n][k]; // Невірно! Помилка!
Такий спосіб виділення пам’яті не дасть вірного результату. Наведемо приклад створення двовимірного масиву.
#include<iostream.h>
#include<conio.h>
int main()
{
int n;const m=5;
printf("input the number";
scanf(&n);
int** a; //a - вказівник на масив вказівників на рядки
a=new int* [n]; //виділення пам’яті для масиву вказівників на n рядків
for(int i=0;i<n;i++)
a[i]=new int [m]; //виділення пам’яті для кожного рядка масиву розмірністю nxm
…
for(int i=0;i<n;i++)
{for(int j=0;j<m;j++)
printf(a[i][j]);
}
for(int i=0;i<n;i++)
delete [] a[i]; //звільнення пам’яті від кожного рядка
delete [] a; //звільнення пам’яті від масиву вказівників
getch();
return 0;
}
2.2 Використання вказівників при роботі з рядками
Символьна константа складається з одного символа ASCII між апострофами (''). Приклади спеціальних символів:
Новий рядок | 'n' |
Горизонтальна табуляція | 't' |
Повернення каретки | 'r' |
Апостроф | ''' |
Лапки | '"' |
Нульовий символ | ' ' |
Зворотний слеш | '\' |
Символьні дані в С предствляють у вигляді стрингів. Стринги є одним з найбільш корисних та важливих типів даних мови С. Символьний рядок (стринг ) — це масив символів, що закінчується у лапки ("). Він має тип char. Нульовий символ ( ) автоматично додається останнім байтом символьного рядка та виконує роль ознаки його кінця. Кількість елементів у масиві дорівнює кількості символів у стрингу плюс один, оскільки нульовий символ також є елементом масива. Кожна стрингова константа, навіть у випадку, коли вона ідентична іншій стринговій константі, зберігається у окремому місці пам'яті. Якщо необхідно ввести у рядок символ лапок ("), то перед ним треба поставити символ зворотного слешу (). У стринг можуть бути введені будь-які спеціальні символьні константи, перед якими стоїть символ .
Прототипи всіх функцій, що працюють з рядками символів, містяться у файлі string.h. Всі функції працюють з рядками, що закінчуються нульовим символом. Ось деякі з них:
int strcat( char *, char *) — з'єднати два стринги;
int strcpy(char *s1, char *s2) — копіювати рядок s2 у рядок s1;
int strlen(char *s) — визначити довжину рядку (кількість символів без нульового символа).
Для роботи з масивом символів, що не має у кінці нульового байта, можна користуватися функціями перетворення буферів. Протипи цих функцій знаходяться у файлі mem.h. Ці функції дозволяють присвоювати кожному байту в межах вказаного буфера задане значення, а також використовуються для порівняння вмісту двох буферів. Наприклад:
memcpy() — копіювання символів з одного буфера у другий, поки не буде скопійований заданий символ або не буде скопійовано визначену кількість символів
memcmp() — порівнює вказану кількість символів з двох буферів
У файлі ctype.h описано прототипи функцій, що призначені для перевірки літер. Ці функції повертають ненульове значення (істина), коли її аргумент задовольняє заданій умові або належить вказаному класу літер, та нуль в іншому випадку. Наприклад:
int islower(int с) — символ с є малою літерою;
int isupper(int c) — символ с є великою літерою;
int isalnum(int c) — символ с є буквою або цифрою;
int isalpha(int c) — символ с є буквою;
int tolower(int c) — перетворення літери у нижній регістр;
int strtol(int c) — перетворення стрингу у довге ціле число;
Приклад
Обчислити вираз з дужками, десятковими цифрами та знаками +, -, *, /.
#include <ctype.h>
#include <math.h>
isdig(char c) {return ((isdigit(c)) || 'с'=='.');}
double val(char **);
double getdig(char ** s)
{
double res;
if(**s=='(') res=val(++*s);
else {res=atof(*s); while(isdig(*++*s));};
return res;
}
double multi(char** s)
{
double res=getdig(s);
while((**s=='*') || (**s=='/'))
if(**s=='*') res*=getdig(++*s);
else res/=getdig(++*s);
}
double val(char** s)
{
double res=multi(s);
while((**s!=')') && (**s!=' '))
if(**s=='+') res+=multi(++*s);
else res-=*(++*s);
if(**s==')') ++*s;
return res;
}
double getsvalue(char* s) {char** l; *l=s;
return val(l);}
main()
{
char* s="2-4/2+25/(2+3)/5+(-1)*(2*4/8-2)*(-1)+5";
cout << getsvalue(s);
}
3.Порядок виконання роботи
Проаналізувати умову задачі.
Розробити алгоритм та створити програму розв’язання задачі згідно з номером варіанту.
Результати роботи оформити протоколом
Похожие работы
-
Автоматизоване нарахування заробітної плати
Методика та особливості створення програми "Автоматизоване нарахування платні" для збереження, перегляду та аналізу введеної інформації, її алгоритм та вихідний код. Аналіз факторів, які впливають на формування заробітної платні робітника підприємства.
-
Програма HelloWin
Опрацювання роботи програми HelloWin, яка демонструє основні принципи створення вікна у OS Windows. Вивчення матеріалу, викладеного у файлі допомоги. Використання функцій для створення вікна, відображення у ньому тексту, відтворення звукових файлів.
-
Проектування ітераційних алгоритмів
Використання ітерацій для обчислення приблизних значень величин. Розробка ітераційних алгоритмів з перевіркою правильності введення даних. Побудова блок-схеми і програмування мовою Turbo Pascal обчислення значення функції, розкладеної в степеневий ряд.
-
Програма для тестування знань з дисципліни "Програмування на мові С"
Розробка програми, яка б дозволяла протестувати знання з дисципліни "Програмування на мові С", виставити оцінку. Опис та обґрунтування методу організації вхідних та вихідних даних, вибору складу технічних та програмних засобів. Проведення лістингу.
-
Програма "Screen Saver" (зберігач екрану)
Файл ssaver.com - резидентна програма, яка має призначення вимкнення екрану при тривалій перерві в роботі з комп’ютером і оберігає екран від передчасної втрати чіткості та кольоровості зображення. Алгоритм програми, функціонування та язик програмування.
-
Робота з пакетом Grapher 2.0 for Windows
Опис програми Grapher, призначеної для математичної і графічної обробки даних, що описуються одновимірною функцією. Процес побудови графіка. Запис файлу даних мовою програмування Pascal. Моделювання вигляду апроксимаційних кривих та дискретних точок.
-
Елементи та структура програми мови Паскаль
Загальні відомості про мову програмування, історія створення та використовування. Програма мовою Паскаль складається з лексем і символів – розділювачів. Робота з масивами, створення алгортимів. Складання програм з використанням процедур та функцій.
-
Розробка програми передачі даних через послідовний порт мікроконтролера
Розрахунок часових затримок для формування імпульсів у програмі передачі даних через послідовний порт мікроконтролера, а також розрахунок швидкості передачі даних через послідовний порт. Алгоритм підпрограми обробки переривань від послідовного порту.
-
Програмування алгоритмічною мовою VBA
Розв'язання задач мовою програмування VBA з використанням алгоритмів лінійної, розгалуженої та ітераційної циклічної структури. Розробка блок-схеми алгоритму, таблиці ідентифікаторів та тексту програми. Створення власної панелі інструментів користувача.
-
Завдання з програмування на Visual Basic
Обчислення наближеного значення суми спадного ряду. Складання блок-схеми та програми, яка б виводила на друк сгенерований, сформований та впорядкований масиви. Використання операторів умовного переходу If - Then - Else. Розроблення програми на VBA.