Язык программирования C. Структура простейшей программы на языке C, страница 9

void swap (int iFirst, int iSecond)

{

int iTemp;

iTemp = iFirst;

iFirst = iSecond;

iSecond = iTemp;

}

Теперь попробуем воспользоваться этой функцией.

void main ()

{

int a = 4;

int b = 7;

swap (a, b);

print (“a = %, b= %”, a, b);

}

И что мы увидим на экране? По прежнему a = 4 а b = 7. Ничего не изменилось. И правильно, ведь в момент вызова функции swap  содержимое переменной a было скопировано в формальный параметр функции iFirst, а содержимое переменной b – в параметр iSecond. Их то мы и меняли местами. Что нужно сдклать? Передать в функцию не копии переменных, а их адреса. Тогда внутри функции мы будем иметь доступ к самим переменным.

Вариант 2.

void swap (int *piFirst, int *piSecond)

{

int iTemp;

iTemp = *piFirst;

*piFirst = *piSecond;

*piSecond = iTemp;

}

void main ()

{

int a = 4;

int b = 7;

swap (&a, &b);

print (“a = %, b= %”, a, b);

}

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

my_strcpy (char *pcSource, char *pcTarget)

{

while (*pcTarget++ = *pcSource++);

}

Этот пример часто приводят в качестве демонстрации возможностей языка С. Разберите это пример сами.

Ранее мы говорили, что структура может содержать в качестве элемента переменную типа другой структуры. А если не другой, а этой же? Если попробовать рекурсивное объявление? Если в качестве элемента структуры использовать указатель на структуру того же типа, то это позволит легко создавать в памяти списки данных:

struct

{

int iData;

struct Node *NextNode;

} Node;

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

Битовые структуры

Когда экономия памяти становится принципиально важным моментом, язык С позволяет создавать структуры с «битовой» организацией. Конечно, с помощью битовых операций можно упаковать в один байт до 8 различных переменных по одному биту на каждую Но доступ к ним будет не очень удобным. Альтернативой является определение битовых структур:

struct

{

unsigned bit_0:        1;

unsigned bits_1_6:   6;

unsigned bit_7:        1;

unsigned bit_8:        1;

unsigned bits_9_15: 7;

} MyWord;

Теперь можно присваивать значения непосредственно битовым полям внутри 16-разрядного слова. Следует отметить, что для хранения битовых структур память выделяется кратно машинному слову. То есть, если мы добывим к представленной структуре еще одно поле длиной только в один бит, то размер всей структуры увеличится еще на одно слово – 16 бит.

Объединения

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

union

{

int iScanCode;

char cBytes[2];

} Input;

Input.iScanCode = bioskey();

if(Input.cBytes[0] == 0)

{

ParseSimpleInput (Input.cBytes[1]);

}

else

{

ParseSpecialInput (Input.cBytes[0]);

}

Препроцессор

#define

#include

Условная компиляция

#ifdef

#else

#endif

Пример с использованием глобальных переменных

Главный файл main

#define MAIN

#include “extern.h”

Прочие рабочие файлы

#include “extern.h”

Заголовочный файл с объявлением глобальных переменных

#ifdef MAIN

#define DCL

#else

#define DCL extern

#endif

DCL int iGlobalValue;

Библиотека стандартных функций языка С