Правила записи программы на языке Си 5 Правила формального описания синтаксиса языка программирования 6

Вид материалаЛекции

Содержание


13.5.Поля бит в структурах.
15.Дополнительные сведения о препроцессоре языка C.
Подобный материал:
1   ...   20   21   22   23   24   25   26   27   28

13.5.Поля бит в структурах.


Для целых чисел допускается использовать область памяти меньше байта:

struct {

int c1:4; -8
int c2:12 -2
} ab;

ab.c1 будет преобразовано в целый тип, затем будет использоваться. На преобразование тратится время и память. Рекомендуется использовать для беззнаковых типов данных и в крайних случаях.


/* Пример использования структур */


#include

#include

#include


typedef struct {

char name[21];

int number;

float price;

} GOODS;


void in_goods ( GOODS gs[], int *n );

int in_goods1 ( GOODS *g );

void out_goods ( GOODS gs[], int n );

void sort_goods ( GOODS gs[], int n);


void main( void )

{

int n; GOODS goods[100];

in_goods ( goods, &n );

sort_goods ( goods, n );

out_goods ( goods, n );

{ float f=0; sin(f); }

}


void in_goods( GOODS gs[], int *n)

{

printf("Введите характеристики товаров в виде:\n" \

"наименование количество цена\n" \

"-----окончание ввода \"end\"-------\n");

*n=0;

while( in_goods1(&gs[*n]) ) (*n)++;

}


int in_goods1( GOODS *g )

{

scanf( "%s", g->name );

if ( strcmp(g->name, "end")==0 ) return 0;

scanf( "%d%f", &g->number, &g->price );

return 1;

}


void out_goods( GOODS gs[], int n )

{

int i;

printf("*----------------------------------*\n");

printf("| Наименование | Кол-во | Цена |\n");

printf("|---------------|--------|--------|\n");

for( i=0; i
printf( "| %20s | %6d | %10.2f |\n",

gs[i].name, gs[i].number, gs[i].price );

printf("*-------------------------------*\n");

}


void sort_goods( GOODS gs[], int n )

{

int i, j, GOODS r;

for (i=0; i
for(j=i+1; j
if( gs[i].price )

{ r=gs[j]; gs[j]=gs[i]; gs[i]=r; }

}

14.Объединения.


Объединяются ключевым словом union. Способы описания такие же, как и в случае структур, только вместо слова struct используется слово union.

union {int a; long b;} pr;

Для переменной pr выделяется память, достаточная для хранения самого длинного элемента объединения, т. е. в нашем примере - 4 байта.

Если использовать pr.a, то выделенная память будет использоваться как int, в случае pr.b как long. Однако, участок памяти один и тот же. Поэтому одновременно существовать pr.a и pr.b не могут. Ответственность за некорректное использование памяти лежит на программисте. Объединения используются для экономии памяти:

union {int bc[100]; double kk[20];} cc;

На все отводится 200 байт.


int bc[100] 200 байт

______________________________

|----------------------------|

double kk[20] (160 байт)

Одновременно работать с массивом cc.bc и cc.kk нельзя.

Объединения нельзя инициализировать.

15.Дополнительные сведения о препроцессоре языка C.


Препроцессор обрабатывает текст программы перед компиляцией.
  1. Включение файлов (рассмотрено ранее):

#include - файл из специального каталога;

#include "d:\\user\\ff.h" - файл ищется по правилам MS DOS.
  1. Текстовые подстановки (рассматривалось ранее):

#define N 21

#define ABC (a*b*c+\

d*sin(x))

\ - переход на следующую строку.
  1. Создание макросов.

#define SQR(x) ((x)*(x))

В результирующую строку подставляется фактическая строка x. Например, если в тексте программы встречается SQR(y), то после макрораскрутки получим ((y)*(y)). Скобки нужны для того, чтобы не получилось недоразумений, например

#define SQR(x) x*x

SQR(y+2); превратится в

y+2*y+2;

Конечно, это не то, что хотелось.
  1. Отмена ранее созданного имени:

#undef SQR.
  1. Условная компиляция:

#if константное выражение

.

. строки программы

.

#else

.

. строки программы

.

#endif

Если константное выражение истинно, то в программу будут включены строки из первого блока, иначе из второго.

Пример:

#define DEBUG 1

.

.

.

#if DEBUG

printf("%d", x);

#endif

Можно проверить наличие или отсутствие какого-либо имени:

#ifdef имя (если имя определено, то истина)

.

.

.

#else

.

.

.

#endif


#ifndef имя (если имя не определено)

.

.

.

#else

.

.

.

#endif

Это свойство широко используется в библиотечных включаемых файлах, чтобы избежать противоречия. Например, в conio.h имеются следующие строки:

#ifndef COLORS

enum COLORS {BLACK, ...};

#endif