Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
119
Добавлен:
13.03.2016
Размер:
470.02 Кб
Скачать

1.5.2. Примеры программ с массивами.

Пример 1. Дан массиваиз 20 элементов. Вычислить сумму положительных и количество неположительных элементов массива.

Исходные данные.а заданный массив

Выходные данные.s - сумма положительных элементов массива, k – количество неположительных элементов.

Промежуточные переменные. i – счетчик элементов массива.

Алгоритм состоит из ввода исходных данных, цикла, в котором накапливаются s иk(цикл управляется переменнойi,которая изменяется от 0 до 19) и вывода результатов. Перед циклом накапливаемым переменным присваиваются начальные значения. Основной частью тела цикла является ветвление. Блок-схема алгоритма приведена на рис. 9. Далее приведена Си-программа.

#include <stdio.h>

#include <math.h>

void main()

{float a[20],s; int k,i;

printf("Введите массив из 20 элементов\n");

/* Далее цикл для поэлементного ввода массива*/

for (i=0; i<20; i++)

scanf("%f", &a[i]);/*Далее алгоритм по блок-схеме*/

s=0; k=0;

for (i=0; i<20; i++)

if (a[i]>0)

s=s+a[i];

else

k=k+1;

printf(" s=%f k=%d",s,k );

}

1.5.3. Инициализация массивов

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

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

Одномерные массивы

Пусть число элементов массива задано явно. Например,

сhar a[10]={'A', 'B', 'C', 'D'};

в результате a[0] имеет значение'A', a[1] - 'B', a[2] - 'C', a[3] - 'D',остальные элементы массива не инициализированы.

Пусть число элементов массива явно не задано:

сhar a[]={'A', 'B', 'C', 'D'};

С помощью такой инструкции описан и инициализирован массив из четырех элементов.

Двумерные массивы

Присваивание перечисленных значений происходит по строкам (в соответствии с расположением массивов в памяти компьютера).

Пример: int m[2][3]={0,1,2,5,6,7};

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

int m[ ][3]={0,1,2,5,6,7};приведет к такому же результату.

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

int m[ ][3]={{0},{1,2}}; объявляет матрицуm размером 2*3 и частично инициализирует ее.

, незаполненные элементы не инициализированы: неопределены, еслиm - локальная переменная, и равны нулю, если глобальная.

Таким образом, при объявлении массива количество его элементов должно быть задано или явным указанием в квадратных скобках или количеством значений при инициализации. Исключение из этого правила составляют массивы-аргументы функций (см. п.2.2.1).

1.5.4. Указатели в Си10

Указатель- это специальная переменная, которая содержит адрес другой переменной.

Работа с указателями и динамической памятью обычно относится к области системного программирования. В Си указатели активно используются даже в простых инструкциях языка. По-видимому, это является следствием того, что Си разрабатывался как язык системного программирования. В п.1.3.3 уже показано использование указателей в функции ввода scanf().В следующем параграфе мы рассмотрим применение указателей для работы с массивами. Этот параграф предваряет его и посвящен правилам работы с указателями в Си.

Основные операции для работы с указателями (см., также таблицу 3): * - взятие содержимого по адресу (*i- содержимое переменной с адресомi) &- взятие адреса (&a- адрес переменной а).

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

тип *имя_указателя;

Можно интерпретировать смысл этой конструкции так:: объявляется переменная, содержимое которой имеет данный тип.

Пример: int *i, j, *pointj;

j -переменная целого типа;i, pointj - указатели на значения целого типа.

При описании указателей возможна их инициализация. Пример:

int v1, *pointv1=&v1, *p=(int*)200;

Здесь указателю pointv1 задается начальное значение, равное адресу переменнойv1,а указателю р - значение константы 200, приведенное к типуint*, т. е. адрес двухсотой от начала рассматриваемой области памяти ячейки типаint.

Как данные любого типа, указатели могут быть переменными или константами. Указателями-константами, например, являются адреса переменных, имена массивов, явные константы (например, (int*)200), а также константаNULL (нулевой или несуществующий адрес).

При работе с указателями-константами надо помнить следующее:

  1. нельзя брать содержимое от константы без приведения типа; запись *200 является некорректной в отличие от *(int*)200

  2. нельзя брать адрес константы (например, некорректна запись &200), в Си адрес константы считается недоступным;

  3. нельзя определять адрес выражения.

Размер памяти, отводимой под указатель, зависит от модели памяти. Для "малых" моделей памяти (tiny, small) адресация осуществляется в пределах одного сегмента памяти, и указатель занимает два байта, для "больших" моделей памяти (large, huge) указатели занимают четыре байта.

Кроме операции *, к указателям применимы операции сравнения (<, <=, >, >=, ==, !=), присваивания, арифметические операции сложения, вычитания, инкремента и декремента. Справа от операции присваивания должен стоять указатель того же типа, что и слева (от операции присваивания),или указатель NULL. Сравнивать можно указатели одного типа (или указатель произвольного типа сNULL).

Нельзя суммировать (вычитать) указатели, можно только прибавлять к ним (вычитать из них) целую величину. При этом результат операции зависит не только от значения операндов, но и от типа, с которым связан указатель. Если объявление указателя р имеет вид тип *р,то в результате операторар=р+k, гдеk- некоторое целое значение, р увеличится наk*sizeof (тип).

Пример. int *p; long int pp;... p++; /*p увеличилось на 2*/

pp++; /*pp увеличилось на4*/