Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка по С Живицкая (Мет пособие).doc
Скачиваний:
112
Добавлен:
15.06.2014
Размер:
2.11 Mб
Скачать

2.3.Структурированные типы данных.

К структурированным типам данных относятся массивы, записи и файлы.

2.3.1.Массив.

Массив – это совокупность элементов одного типа, который обращается с помощью общего имени. Доступ к отдельному элементу массива может осуществляться с помощью индекса, в С все массивы состоят из соприкасающихся участков памяти. Наименьший адрес соответствует первому элементу массива. Наибольший адрес соответствует последнему элементу. Массивы могут иметь одну или несколько размерностей. Стандартный вид обьявления одномерного массива.

Тип имя_переменной [размер];

В С массивы должны определяться однозначно, чтобы компелятор мог выделить для них место памяти. Здесь тип обьявляет базовый тип массива и является типом каждого элемента массива. Параметр "размер" определяет сколько элементов содержит массив. Размер должен задаваться только const-н целым выражением. Не допускается использования переменных при описании размера массива. У всех массивов первый элемент имеет индекс ноль (0).

Пример:

Если написать char K [10];, то будет обьявлен массив из 10-ти элементов, причем эти элементы адресуются индексами от 0...до 9.

Пример:

inta[20];

Определяет массив из 20-ти элементов. Причем под этот массив будет отведено 2*20, т.е. 40 байтов памяти ЭВМ. Размер обычно указываемый в квадратных скобках, после имени массива при его описании может отсутствовать.

Пример:

int b [ ];

int b [ ] = { 1,2,3 };

В первом случае память под массив не выделяется. Выделяется только память под указатель. Во втором случае память под массив отводится в соответствии с приведенным списком начальном значении, т.е. 3*2=6 байт. Обращение к элементу массива осуществляется с помощью операции индексации

имя [ выражение ];

где имя - имя массива.

Выражение, заключенное в квадратные скобки после имени массива является индексом массива и определяет порядковый номер элемента в массиве. Выражение должно быть целого типа. С - компелятор не контролирует случая выхода индекса за пределы границ массива. Имя массива, используемое без последующих квадратных скобок, представляет адрес начала массива. Двухмерный массив представляется, как одномерный элементы которого тоже являются массивами.

Пример:

int b[5] [10];

Это обьявление задает 2-х мерный массив. Аналогично можно установить число измерений. Элементы 2-х мерного массива хранятся по строкам, т.е. если переходить по ним в порядке их расположения в памяти, то быстрее всего изменяется крайний правый индекс.

Пример обращения к 8 - му элементу3-й строки.

b[3] [8];

Над массивами в С допускается только две операции:

1) Получение адреса массива с помощью операции указатель.

2) Обращение к элементу массива с помощью операции - индексации.

В некоторых реализациях компелятора допускается использование операции sizeof.

2.3.1.1. Связь между массивами и указателями.

Существует тесная связь между массивами и указателями. Имя массива является указателем const-й и представляет собой стартовый адрес массива.

Пример:

int a [5];

Массив из 5-ти элементов, где а есть адрес нулевого элемента (& a[0]).

Пример: В массив заносятся элементы от 1 до 12 и после чего выводится массив на экран.

# include <stdio h>

int main ( void )

{ int t, i, num [3] [4];

/* загрузка чисел */

for (t=0, t<3; ++t);

for (i=0, i<4, ++i);

num [t] [i] = (t*4)+i+1;

/* вывод чисел */

for ( t=0; t<3, ++t) {

for ( i=0; i<4, ++i)

printf ( " % d ", num [t] [i]);

printf ( " \n ");

}

}

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

1000 1002 1004 1006 1008-адрес

A[0]

A[1]

A[2]

A[3]

A[4]

Символическое обозначение адреса 1000 в массиве - это а. К третьему элементу массива можно обратиться с помощью операции индексации (а [2]). Существует другой способ обращения к третьему элементу массива а. Это использование стартового адреса массива и операции сложения указателя с константой. Выражение: а+2 дает значение адреса 1004 (1000 + 2 * 2). Взяв значение по этому адресу можно добраться до третьего элемента массива а, т.е. *(а+2). Следовательно обратиться например к i-тому элементу массива а можно с помощью выражения а [i] или *(а+i). Оба способа эквивалентны, но второй быстрее.

Пример вариантов вывода элементов массива

# (include <stdio.h>

int a[] = {10;20;30;40;50;60};

/ * обьявление и инициализация массива * /

main( )

{ int i, * p )

for ( i=0, i< 6; i++)

printf ( " a [% d] = % d, % c, i, a [i] (i= =2)?'\ n':'__');

printf ( " \ n \ n ");

for ( p = & a [0]; p < = & a [5]; p++ )

printf ( " значение * p % d; % c", * p, (p = = & a [2] ) ? '\ n'; '__');

printf ( " \ n \ n " );

for ( p = & a [0], i = 0, i < b; i++ )

printf ( " p [ % d ] = % d; % c", i, p [i], (i= =2)?'\ n':'__');

printf (" \ n \ n");

for ( a = 0, i = 0, p+i < = a+4; p++,i++)

printf ( " * ( p + % d ) = % d \ t ", i, * (p + i ) );

printf( "n\n" );

/ * вывод на печать 2-го, 4-го элемента М* /

}

Результат работы.

a[0]=10; a[1]=20; a[2]=30; a[3]=40; a[4]=50; a[5]=60

_________________________________________________________________

Значение * р:10; значение * р:20; значение * р:30; значение * р:40;

значение * р:50; значение * р:60;

─────────────────────────────────────────────

р[0]=10; p[1]=20; p[2]=30; p[3]=40; p[4]=50; p[5]=60;

─────────────────────────────────────────────

* [p+0]=10 * (p+1)=30 * (p+2)=50

─────────────────────────────────────────────

Операция р++ увеличивает значение указателя на еденицу. Если р=&a[i],то после операции р++, р содержит адрес элемента а[i+1].