Студопедия
Новини освіти і науки:
МАРК РЕГНЕРУС ДОСЛІДЖЕННЯ: Наскільки відрізняються діти, які виросли в одностатевих союзах


РЕЗОЛЮЦІЯ: Громадського обговорення навчальної програми статевого виховання


ЧОМУ ФОНД ОЛЕНИ ПІНЧУК І МОЗ УКРАЇНИ ПРОПАГУЮТЬ "СЕКСУАЛЬНІ УРОКИ"


ЕКЗИСТЕНЦІЙНО-ПСИХОЛОГІЧНІ ОСНОВИ ПОРУШЕННЯ СТАТЕВОЇ ІДЕНТИЧНОСТІ ПІДЛІТКІВ


Батьківський, громадянський рух в Україні закликає МОН зупинити тотальну сексуалізацію дітей і підлітків


Відкрите звернення Міністру освіти й науки України - Гриневич Лілії Михайлівні


Представництво українського жіноцтва в ООН: низький рівень культури спілкування в соціальних мережах


Гендерна антидискримінаційна експертиза може зробити нас моральними рабами


ЛІВИЙ МАРКСИЗМ У НОВИХ ПІДРУЧНИКАХ ДЛЯ ШКОЛЯРІВ


ВІДКРИТА ЗАЯВА на підтримку позиції Ганни Турчинової та права кожної людини на свободу думки, світогляду та вираження поглядів



Ініціалізація

 

Якщо явна ініціалізація відсутня, то зовнішнім і статичним змінним присвоюється значення нуль; автоматичні і регістрові змінні мають в цьому випадку невизначені значення (сміття).

Прості змінні (не масиви або структури) можна ініціалізувати при їх описі, додаючи вслід за ім'ям знак рівності і константний вираз:

 

int x = 1; char squote = '\’'; long day = 60*24; /* minutes in а day */

 

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

Автоматичні і регістрові змінні необхідно ініціалізувати кожний раз при вході в функцію або блок.

 

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


Наприклад, ініціалізація в програмі бінарного пошуку могла б бути записана у вигляді

 

binary(x, v, n)

int x, v[], n;

{ int low = 0;

int high = n - 1;

int mid; ... }

замість

binary(x, v, n)

int x, v[], n;

{ int low, high, mid;

low = 0; high = n - 1; ...

}

 

За своїм результатом, ініціалізація автоматичних змінних є скорочений запис операторів присвоєння. Використовують явні присвоєння, тому що ініціалізація в описах менш помітна.

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


Оголошенняtypedef

 

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

Формат:

typedefспецификатор-типу описувач [опис]...,

 

Наприклад, опис

 

typedef int length; робить ім'я length синонімом для int.

 

З цього моментуту "Тип" length може бути використаний в деклараціях(описах) типів точно таким же чином, як і тип int:

 

length len, maxlen; length *lengths[];

 

 

Аналогічно опису typedef char *string; робить string синонімом для char*, тобто для вказівника на символи, що потім можна використати в інших описах.


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

 

 

Цей ідентифікатор може використовуватися разом з ключовим словом const для оголошення даного, що не модифікується.

 

 

Будь-який тип може бути оголошений з typedef, включаючи типи вказівника, функції і масиву.

 

 

Ім'я з ключовим словом typedef для типів вказівника, структури може бути оголошено раніше, ніж ці типи будуть визначені, але в межах видимості оголошення.


Вказівники типуnearіfar

 

Як і звичайні вказівники на дані, вказівники на функцію можуть мати тип near, far або huge. Вказівник типу nearзаймає в пам’яті 2 байти, вказівники far і huge– 4 байти. Тип вказівника на функцію, який встановлюється по замовчуванню, залежить від моделі пам’яті.

 

В моделях пам’яті compact, tiny i small по замовчуванню вказівник на функцію має тип nearі задає тільки зміщення до точки входу в функцію відносно значення в сегментному регістрі CS.

При прямому чи побічному виклику функції через near-вказівник використовується машинна команда “близького” прямого чи побічного виклику процедури, яка пов’язана з установкою нового значення тільки у регістрі IP.

 

Для моделей пам’яті medium, large і huge по замовчуванню вказівник на функцію займає 4 байти і включає як зміщення, так і адресу сегмента точки входу у функцію. При прямому чи побічному виклику функції через far-вказівник на функцію використовується машинна команда далекого прямого чи побічного виклику процедури, яка пов’язана як з установкою нового значення в регістрі IP,так і зі зміною значення сегментного регістра CS.


В моделі пам’яті huge при вході у функцію додатково встановлюється значення регістра DS, яке відповідає сегменту даних функції. Пряма адресація при виклику процедури відповідає виклику функції через вказівник-константу. Побічний виклик використовується при виклику функції по вказівнику-змінній.

 

Прийнятий по замовчування формат вказівника на функцію може бути відмінений явним заданням типу функції з використанням ключових слів near, far або huge. Наприклад:

 

int far function (int, int); / * Прототип функції */

. . .

int far function (int a, int b) /* Визначення функції */

{ Тіло функції}

 

Синтаксис мови С вимагає співпадіння модифікаторів типу функції як в прототипі, так і у визначенні функції. Компілятор завжди трактує першу частину визначення як тип значення, яке повертає функція, а наступне слово, як модифікатор.


Тому, наприклад,

 

char far *far str_func(void);

 

є прототипом far-функції, яка повертає значення вказівника типу char far *. Сама функція є far-функцією. Опис, наведений нижче, визначає вказівник func_ptr на far-функцію (можна сказати, і far-вказівник на функцію), яка приймає два аргументи типу int і повертає значення типу char far *:

 

char far *far (*func_ptr) (int, int);

 

При порівнянні far-вказівників операціями <, >, <=, >= використовуються тільки зміщення (вказівники порівнюються як числа типу int), а операціями != і == far-вказівники порівнюються як числа типу long.

Нехай, наприклад, оголошені наступні вказівники:

 

void far* vp1=0xb8000000;

 

void far* vp2=0xb4004000;

 

void far* vp3=0xb0008000;

 

Дані вказівника вказують на одну і ту ж фізичну адресу, але операція порівняння == дає результат FALSE, != дає значення TRUE.

 

 

При нарощенні вказівника типу farвикористовується тільки його зміщення. Якщо при цьому результат не вміщається у зміщення, то відбувається відрізання старших розрядів результату.

 

 

Наприклад, після додавання до vp3 числа 8000h зміщення вказівника стане рівним b0000000h. Таким чином, за межі сегмента вийти неможливо.

 

 



Читайте також:

  1. Ініціалізація і встановлення зв'язку
  2. Ініціалізація початкових умов.
  3. Ініціалізація СOM-порту




Переглядів: 1067

<== попередня сторінка | наступна сторінка ==>
Специфікатори класу пам'яті | Складні оголошення мови

Не знайшли потрібну інформацію? Скористайтесь пошуком google:

  

© studopedia.com.ua При використанні або копіюванні матеріалів пряме посилання на сайт обов'язкове.


Генерація сторінки за: 0.177 сек.