17111

Розробка програм з покажчиками

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторна робота № 20 Тема: Розробка програм з покажчиками Ціль роботи: вивчити конструкції й оператори мови С для роботи з покажчиками. Обладнання: ПКПО Borland C Теоретичні відомості Самим могутнім інструментом у С безумовно є покажчики і для того щоб опанув...

Украинкский

2013-06-29

88.5 KB

1 чел.

Лабораторна робота № 20

Тема: Розробка програм з покажчиками

Ціль роботи: вивчити конструкції й оператори мови С++ для роботи з покажчиками.

Обладнання: ПК,ПО Borland C++

Теоретичні відомості

Самим могутнім інструментом у С, безумовно, є покажчики і для того, щоб опанувати програмуванням у З, необхідно опанувати умінням використовувати покажчики.

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

 Розглянемо основні поняття і принципи роботи з покажчиками.

Покажчик - це адреса пам'яті, розподіленої для інший перемінний заданого типу. Значення покажчика повідомляє про тім, де розташований об'єкт даних, але не говорить про його вміст.

Синтаксис оголошення покажчиків:

тип*ім'я_покажчика.

Читається даний запис так:

ім'я_покажчика є покажчиком на тип. Символ «*» (зірочка) говорить про те, що дана перемінна є покажчик на заданий тип.

Приклад:

 int * x; // x є покажчиком на тип int (ціле).

Таким чином, можна оголосити покажчик на будь-який тип: стандартний чи створений користувачем, у тому числі може бути оголошений покажчик на покажчик, на будь-який тип-void.

Покажчик на тип void сполучимо з будь-яким іншим покажчиком. Наприклад, припустимий запис:

int *x;

void *y;

y = x;

Розмір покажчика, тобто розмір ділянки пам'яті, відведеного під адресу, залежить від моделі пам'яті, у якій пишеться програма. Відзначимо їхню назву і вкажемо розмір покажчиків у байтах: малюсінька (2), маленька (2), середня (4), компактна (4), велика (4), величезна (4).

Для вказівки розміру покажчика використовують модифікатори: за замовчуванням near (2 байти), far (4 байти), huge (4 байти).

Покажчик може використовуватися як константний, котрий зв'язаний з однією постійною коміркою пам'яті:

float const  ptr;    // константний покажчик

Покажчик може бути зв'язаний і з константами:

const  float ptr;   // покажчик на константний тип

Можливо також наступне вираження:

сonst  float сonst ptr;   // константний покажчик на константний тип.

Основні операції з покажчиками

 Найбільш важливі операції з покажчиками: операція звертання за адресою "*" (називається також разйменуванням покажчика, разадресуванням, операцією непрямої адресації) і операція визначення адреси "&". Операція звертання за адресою служить для доступу до даних описаного типу, тобто для присвоєння і зчитування даних.

Приклад:

   int*x; int d; // не плутати разадресуванням з зірочкою при оголошенні покажчика

int у = *х                                       // у = 4;

 У першому рядку перемінн-покажчику х привласнюється адреса, де зберігається значення перемінної d у другому рядку перемінної в привласнюється разіменоване значення покажчика х, тобто значення 4. Якщо першу операцію написати без адреси, тобто х = d х оголошений як int*x), то х буде вказувати на комірку пам'яті з адресою ??:4 (?? -  у залежності від моделі пам'яті) і значення перемінної в буде дорівнює значенню, що зберігається по зазначеній адресі.

Операція визначення адреси & повертає адресу пам'яті свого операнда (перемінної, константи, функції і т.д.). Формат одержання адреси наступний:

 адреса = & перемінна;

Приклад: int x, *y; y = &a;  // покажчик y містить адреса х

Крім того, покажчики можна привласнювати один одному, якщо вони одного типу.

Приклад: int a, *x, *y; x =y;

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

Покажчики і цілі величини

Вираження цілого типу може складатися і відніматися з перемінної типу покажчик. Два покажчики на об'єкти того самого типу можуть відніматися; у цьому випадку результат має цілий тип.

char*a = "Slovo", c;

c = *(a+3);  // c = 'v'

char*a, *b = "ABCDE";

a = b + 2; c = *(- - a;

char k = *a; int d = b-a)

Динамічне розміщення покажчиків у пам'яті

Щоб не викликати конфлікт в операційній чи системі не порушити роботу додатка, потрібно виділяти місце для зазначеного типу даних у припустимому просторі пам'яті, що називається «heap» чи «купа». 

Виділення (якщо є можливість) пам'яті і присвоєння її адреси покажчику, по якому можна працювати з описаним типом здійснюється бібліотечною функцією malloc ( ) чи alloc(), (заголовний файл <mem.h>), яку необхідно попередньо включити в програму директивою # include. Ці функції при наступних виділеннях пам'яті запобігають конфлікти між покажчиками.

Формат використання даної функції:

покажчик = (тип_покажчика*) malloc (розмір_виділюваної_пам'яті_байт);

 Покажчик на один тип може бути перетворений у покажчик на інший тип. При цьому забезпечується можливість перетворення покажчика на об'єкт даного розміру в покажчик на об'єкт меншого розміру в покажчик на об'єкт меншого розміру і зворотного без змін.

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

double*dp;

d = (double*) malloc (sizeof(double));  // функція malloc () виділяє пам'ять

free dp: *dp = 22. / 7.0  // звільнення динамічних виділень пам'яті.

При використанні функції забезпечується перетворення значення, що повертається, з покажчика на тип void у покажчик на тип double.

Приклад

/*    ЗАНЯТТЯ N 8

Виконав студент групи .........   Петров Ю.В.

Застосування покажчиків при роботі з перемінними

різних типів, зміна значень перемінних за адресою

і по посиланню. Приклади операцій з покажчиками  */

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <alloc.h>

  int a;       //Оголошення глобальної перемінної типу int

int main(void)

 {char c1,c2,buf[20];     //buf-покажчик на тип char

  char   *pc;

  char   *pst="\"slovo\"";//Оголошення покажчиків на тип char

  int    *pi= &a;

  float  *pf, f=26.6;     //Оголошення покажчика на тип float

  double *pd, d;          //Оголошення покажчика на тип double

  double &sd= d;          //Оголошення посилання на тип double

  void   *pv;             //Оголошення покажчика на тип void

  char   *pchar=(char *)malloc(20);//Виділення пам'яті в купі

  clrscr();   // Оголошення функції void *malloc(size_t size);

  pc=&c1;     pf=&f;       pd=&d;

  printf(" Уведення перемінної c1 типу char:   ");

  scanf("%c",pc);   //Функція введення даних, & - операція узяття

    //адреси відсутня

  printf(" Виведення перемінної c1 типу char:  ");

  printf("%c\n",*pc);

  fflush(stdin);

  pc=&c2;

  printf(" Уведення перемінної c2 типи char:   ");

  scanf("%c",pc);   //Функція введення даних, & - операція узяття

    //адреси відсутня

  printf("Виведення перемінної c2 типи char:  ");

  printf("%c\n",*pc);

  printf("\n Уведення перемінної (a) типу int:  ");

  scanf("%d",pi);

  a+=5; ++*pi;       //Зміна а = а+5+1

  printf(" \t Виведення (a) після зміни а=а+5+1\n");

  printf(" Формат висновку (int): +6d     #6o     #8x\n");

  printf("\t\t     |%+6d|%#6o|%#8x|\n ",a,*pi,*pi);

  printf("\n Виведення вихідного рядка:  %s\n",pst);

  pc=pst;

  printf("Виведення рядка в циклі:\n");

  while(*pc!='\0') { printf("  %s",pc); pc++; }

  printf("\n Уведення рядка в масив:    ");

  scanf("%s",buf);

  pv=buf;              //Використання покажчика (pv) на тип void

  printf("Виведення рядка з масиву: %s\n",(char *)pv); //pv -void

  printf(" Уведення рядка в динамічну пам'ять:   ");

  scanf("%s",pchar);

  printf("Виведення рядка з динамічної пам'яті: %s\n",pchar);

  printf(" Уведення перемінних типу float and double (через пробіл):\n");

  printf("\t\t      ");

  scanf("%f %lf",pf,pd);

  pv=pf;               //Використання покажчика (pv) на тип void

  *pf=*(float *)pv*10; //f*=10;

  *pd=sd+*(float *)pv; //Використання посилання (sd) на тип double

  pv=pd;               //d+=f;

  printf("\t Виведення результатів розрахунку f*=10   d+=f\n");

  printf(" Формат Виведення (float):  10.6f       10.6e       +10.6g\n");

  printf("\t\t     |%10.6f|%10.6e|%+10.6g|\n",f,*pf,*pf);

  printf(" Формат Виведення (double): 10.8lf      10.8e        10.8g\n");

  printf("\t\t     |%10.8lf|%10.8e|%+10.8g|\n ",*pd,*(double *)pv,sd);

  getche();

  return 0;

}

/* Уведення перемінної  c1 типу char:  w

  Виведення перемінної c1 типу char:  w

  Уведення перемінної  c2 типи char:  t

  Виведення перемінної c2 типи char:  t

  Уведення перемінної (a) типу int:   40

  Виведення (a) після зміни а=а+5+1

Формат Виведення (int): +6d     #6o     #8x

   |   +46|   056|    0x2e|

Виведення вихідного рядка:  "slovo"

Виведення рядка в циклі:

  "slovo"  slovo"  lovo"  ovo"  vo"  o"  "

Уведення рядка в масив:    unsigned

Виведення рядка з масиву: unsigned

Уведення рядка в динамічну пам'ять:    dinamo

Виведення рядка з динамічної пам'яті:  dinamo

Уведення перемінних типу float and double (через пробіл):

     1.5       20.4

Виведення результатів розрахунку *pf=*pf*10; *pd=*pd+f;

Формат Виведення (float):  10.6f       10.6e       +10.6g

   | 15.000000|1.500000e+01|       +15|

Формат Виведення (double): 10.8lf      10.8e        10.8g

   |35.40000000|3.54000000e+01|  +35.4|

*/

Приклад програми на С++

Привласнити раз іменованому покажчику на тип Р1 значення арифметичного вираження АВ, яке включає покажчики на типи Р2 і Р3. Арифметичне вираження реалізувати у виді функції, яка повертає   покажчик на тип Р1. Вивести на екран значення покажчика Р2 і значення на який він посилається. Індивідуальні завдання взяти з таблиці 8.1.

Варіант

Р1

АВ

Р2

Р3

long

sin(p2)/tan(p3)

int

float

#include<iostream.h>

#include<math.h>

long int *AB(int i,float f);

void main()

{long z,*P1=&z;

int x,*P2=&x;

float y,*P3=&y;

*P2=2;

*P3=1.1;

*P1=*AB(*P2,*P3);

cout<<"P1="<<*P1<<"\n";

cout<<"Значение P2: "<<P2<<"\nЗначение данного P2: "<<*P2;

}

long int *AB(int i,float f)

{long a,*rezultat=&a;

*rezultat=sin(i)/tan(f);

return rezultat;

}

Хід роботи

1.Вивчити теоретичні відомості.

2.Відповідно до індивідуального завдання розробити алгоритм застосування покажчиків.

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

4.Набрати програму на комп'ютері й усунути помилки.

5.Одержати результат.

6.Оформити звіт і зробити Захист роботи по роботі.

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

Індивідуальне завдання

Привласнити раз іменованому покажчику на тип Р1 значення арифметичного вираження АВ, яке включає покажчики на типи Р2 і Р3. Арифметичне вираження реалізувати у виді функції, яка повертає   покажчик на тип Р1. Вивести на екран значення покажчика Р2 і значення на який він посилається. Індивідуальні завдання взяти з таблиці 8.1.

Таблиця 8.1 - індивідуальні завдання

Варіант

Р1

АВ

Р2

Р3

long

(1/sin((р2)2))р3

int

float

float

(abs(p3))1/p2

long

double

double

tan((p3)2)p2/3

int

long

float

(ln(p2)p3)p2

char

unsigned long int

long double

sin(abs(p3)p2)

double

long int

long

sin(p2)/tan(p3)

int

float

unsigned long int

(++p3)/(--p2)

short int

int

long double

((1+(++p2))/p3)p2

long int

float

signed long int

(sin(--p2)-(p3))p3

char

int

long int

(1/sin(p2))p3

unsigned long int

int

double

sin(p3)1/p2

double

float

double

cos(p2/p3)

int

double

int

(--p2)+(++p3)

unsigned int

short int

signed int

(sin(p2)/tan(p3))p3

short int

char

long double

ln(--p2)1/p3

float

double

double

1.2*(10-(
--p3))+p3

double

short int

double

tan((p3)2)p2/3

double

float

float

(ln(p2)p3)p2

int

double

long double

sin(abs(p3)p2)

unsigned int

short int

long double

((1+(++p2))/p3)p2

double

long int

signed long int

(sin(--p2)-(p3))p3

int

float

long int

(1/sin(p2))p3

short int

int

long double

sin(abs(p3)p2)

char

int

long

sin(p2)/tan(p3)

unsigned long int

int

double

sin(p3)1/p2

double

float

double

cos(p2/p3)

int

double

int

(--p2)+(++p3)

unsigned int

short int

long double

((1+(++p2))/p3)p2

short int

char

signed long int

(sin(--p2)-(p3))p3

float

double

long int

(1/sin(p2))p3

double

short int

Вимоги до змісту звіту приведені в лабораторній   роботі   №1.

Контрольні запитання

1.Дайте визначення покажчику.

2.Який синтаксис оголошення покажчика?

3.З якими модифікаторами може бути використаний покажчик?

4.Чим відрізняється (*) в оголошенні покажчика й у вираженні, де він використовується?

5.Що таке операція звертання за адресою?

6.Що таке операція узяття адреси?

7.Як би Ви привласнили адресу перемінної з крапкою, що плаває, salary покажчику з ім'ям pt_sal?

8.Чи обов'язково  покажчик при його оголошенні?

9.У чому особливості використання покажчика на тип void?

10.Для чого застосовується константа NULL?

11.Що таке динамічне виділення пам'яті, де вона виділяється і за допомогою яких функцій?

12.Чи можна привласнювати покажчики одного типу?

13.Як здійснити приведення типу покажчика?Поясните приклади, приведені в теоретичній частині.


 

А также другие работы, которые могут Вас заинтересовать

9957. Организационно-правовые формы коммерческих компаний 39.5 KB
  Организационно-правовые формы коммерческих компаний. Общество с дополнительной ответственностью: Внося деньги в уставной капитал...
9958. Формы оформления договоров 35 KB
  Формы оформления договоров Устная сделка. Простая письменная форма. нотариально удостоверенная форма. Государственная ре...
9959. Расторжение договора 45 KB
  Расторжение договора. Пролонгация - продление договора. Расторжение договора по взаимному согласию: деньги потрачены, какие-то действия...