Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Уч. пос. МПТ (2.04.12).pdf
Скачиваний:
407
Добавлен:
22.03.2015
Размер:
10.95 Mб
Скачать

unsigned int B=10;

double D;

 

...

 

D=(int)(A*B);

// D=-10

И то же с примером 1:

 

int A=75, B=10;

 

double C;

 

...

 

C=(double)A/B;

// C=7.5

C=A/(double)B;

// C=7.5

2.2.7 Массивы

Массив — это совокупность однотипных элементов, которые идентифицируются по индексу или нескольким индексам.

Одномерные массивы объявляются следующим образом

Тип Имя[Размерность]={Значениие1, ... ,ЗначениеN};

Массивы могут быть многомерными. Рассмотрим синтаксис для двумерных массивов.

Тип Имя[Размерность1][Размерность2]=

{{Знач.11, ... ,Знач.1N}, ... ,{Знач.M1, ... ,Знач.MN}};

Начальные значения при объявлении присваивать не обязательно. В то же время, если присваивание выполняется, можно не указывать размерность, поставив две скобки подряд «[]». Тогда размерность автоматически определяется числом элементов в фигурных скобках.

Обращение к элементам массива производится с указанием индексов в квадратных скобках

A[5]

B[m][n]

В Си индексация элементов массива всегда начинается только с нуля. Индекс является смещением относительно базового адреса.

Часто применяется компактная запись, сочетающая обращение к элементу массива с изменением индекса:

A[k++]=...

...=B[m][++n]

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

2.2.8 Строки символов

Строка представляет собой одномерный массив элементов типа char, последний из которых всегда равен нулю (обозначает конец строки). Строковые константы записываются в двойных кавычках. Ниже приведены эквивалентные примеры

char S[7]="Превед";

char S[7]={'П','р','е','в','е','д',0};

107

Обратим внимание на то, что в основной программе строковую константу нельзя присвоить строковой переменной, также как нельзя одной командой присвоить значение массиву. Это допустимо только в разделе объявления переменных. Вместе с тем строковые константы, заключенные в кавычки могут быть параметрами функций.

Для символов, которые невозможно набрать с клавиатуры, предусмотрено специальное обозначение: «\xКод». Код используется шестнадцатеричный. Например

"I \x01 ARM7"

// Дает "I ♥ ARM7"

2.2.9 Структуры

Структура, в отличие от массива, — это совокупность разнотипных данных, называемых полями, идентифицируемых по имени. Среди полей могут быть и массивы. Объявление структуры имеет вид

struct

{

Объявление1 ;

...

ОбъявлениеN ; } Имя ;

При обращении к элементам структуры ее имя отделяется от имени поля точкой, например

Structure1.Field2=...

Может быть задано начальное значение, например:

struct

{

int Header; int CRC;

char Data[8];

} Frame={0x12345678,0,{1,2,3,4,5,6,7,8}};

2.2.10 Объединения

Объединения дают возможность обращаться к одной и той же области памяти, как к данным разных типов.

union

{

Объявление1 ;

...

ОбъявлениеN ; } Имя ;

Обычно (но не обязательно) все элементы объединения имеют одну и ту же длину. Приведем пример записи области памяти как массива четырех байтов и чтения той же области уже как числа с плавающей точкой, состоящего из этих байтов.

108

union

{

float F; char C[4];

} Buffer;

...

for (k=0; k<4; k++) Buffer.С[k]=...;

...=Buffer.F;

2.2.11 Указатели

Указатель представляет собой 32-разрядную величину, хранящую адрес переменной произвольного типа. При объявлении указателя после типа данных ставится символ «*», например,

float* F;

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

Имя_указателя = ( Тип* ) Значение;

Например, в нашем случае

F=(float*)0x40000010;

Однако это изменит не данные, а адрес, на который ссылается указатель. При программировании для ARM7 распределение памяти, как правило, полностью доверяется компилятору. В таком случае с уверенностью сказать, что конкретный адрес памяти свободен, — невозможно. Поэтому инициализация (присваивание значения) указателя обычно выполняется так

F=&D;

Здесь D — имя переменной, а & оператор взятия адреса (таблица 2.2.1). Такая команда приведет к тому, что указатель F будет ссылаться на переменную D.

Для обращения к самим данным используется такой синтаксис

*F=23;

//

Запись

по адресу, хранящемуся в F

...=*F;

//

Чтение

адреса, хранящегося в F

Здесь * — оператор обращения по адресу (таблица 2.2.1).

Внашем примере следующие операции будут идентичны.

*F=...; D=...;

Всущности, массивы тоже являются указателями на нулевой элемент (базовый адрес). Поэтому наряду с традиционным обращением к массиву

M[2]=100;

вполне допустимо

*(M+2)=100;

2.2.12 Ветвление

Конструкция ветвления имеет следующую структуру

109

if ( Выражение )

{

... ; // Блок операторов 1

}

else

{

... ; // Блок операторов 2

}

Здесь Выражение — любое арифметическое выражение целого типа. Если это Выражение имеет ненулевое значение, выполняется блок операторов 1, иначе — блок операторов 2. Такую форму записи можно назвать полной. Сокращенная форма записи не содержит ветви else.

Если блок операторов состоит лишь из одной команды, то операторные скобки { } можно опустить.

Пример 1

if ((A>0) && B) // Выполнить операторы 1–2, если

{

// A>0 и B≠0

 

Оператор 1 ;

 

Оператор 2 ;

}

Else // Иначе выполнить оператор 3

Оператор 3 ;

Отметим, что в Си допустимо совмещать вычисления и проверку условия. Приведем несколько примеров.

Пример 2.

if (--k==0)

//

Декремент k, если результат

{

// равен нулю, то выполнять операторы

Операторы ;

 

 

}

 

 

Пример 3.

 

 

if (k++>100) // Если k>100, то выполнять операторы

{

// После проверки увеличить k на 1

Операторы ;

 

 

}

 

 

Пример 4.

 

 

if (A|=B)

// Присвоить A поразрядное ИЛИ A и B

{

// Выполнять операторы, если результат ≠0

Операторы ;

 

 

}

 

 

2.2.13 Множественное ветвление

Конструкция множественного ветвления имеет следующую структуру

switch ( Выражение )

110