Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели



страница1/8
Дата29.04.2013
Размер0.57 Mb.
ТипПрактикум
  1   2   3   4   5   6   7   8


МИНИСТЕРСТВО ОБЩЕГО И

ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
УНИВЕРСИТЕТ ВОЛГОГРАДСКИЙ ГОСУДАРСТВЕННЫЙ
КАФЕДРА “Теоретической физики и Волновых

процессов

ПРОГРАММИРОВАНИЕ,

МАТЕМАТИЧЕСКОЕ МОДЕЛИРОВАНИЕ
Лабораторный практикум по ПММ

( 2 курс, 3 семестр )


Волгоград, 1998


Лабораторная работа № 1

Массивы и указатели

Массив - это объект, состоящий из элементов одного типа и расположенных в памяти подряд. Синтаксис определения одномерного массива следующий:

Тип Имя_массива [константа или константное выражение];

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

Нумерация элементов массива начинается с нуля. Номер элемента массива обычно называют индексом. При определении массива может выполняться инициализация его элементов. Если она явно не производится, то компилятор неявно присваивает всем неинициализированным элементам массива нулевые значения. Например, предложение: float A[5]; определяет массив, состоящий из 5 вещественных переменных типа float. Все элементы этого массива компилятор обнулит.

Имя массива является указателем-константой, значением которой служит адрес элемента с индексом 0. Перемещение указателя от одного элемента к другому выполняется в порядке увеличения его индекса, и обратиться к какому либо элементу массива можно по этому индексу. При этом запись имя_массива [индекс] является на самом деле выражением. Например, A[i] означает *(A+i).

Обратите внимание на разный смысл, который имеют квадратные скобки [] при определении массива и при обращении к элементу массива. В операторе описания типа квадратные скобки [] служат модификаторами типа, которые определяют размеры и размерность массива. В остальных случаях [] - это бинарная операция над именем массива и индексом, которая возвращает значение объекта, расположенного по адресу, равному сумме адреса нулевого элемента и смещения, вычисляемого как i*sizeof(тип элементов массива A). Так как сложение - коммутативная операция, выражения *(A+i) и *(i+A) являются эквивалентными. А это означает, что A[i] именует тот же объект, что и i[A].
Таким образом, обратиться к элементу массива можно либо явно с использованием операции разыменования, либо неявно с использованием операции индексирования. Следующая программа [2] иллюстрирует обе возможности.
Пример 1.

/*Program 9.1*/

#include

void main()

{

float A[5] = { 10., 20., 30., 40. } ; // (1)

int i = 1; // (2)

printf(“\n A[i] = %2f”, A[i] ); // (3)

printf(“\n *(A+i) = %2f”, *(A+i) ); // (4)

printf(“\n *(i+A) = %2f”, *(i+A) ); // (5)

printf(“\n i[A] = %2f”, i[A] ); // (6)

printf(“\n A[0] = %2f 0[A] = %2f”, A[0], 0[A] ); // (7) printf(“\n A[1] = %2f 1[A] = %2f”, A[1], 1[A] ); // (8)

printf(“\n A[2] = %2f 2[A] = %2f”, A[2], 2[A] ); // (9)

printf(“\n A[3] = %2f 3[A] = %2f”, A[3], 3[A] ); // (10)

printf(“\n A[4] = %2f 4[A] = %2f”, A[4], 4[A] ); // (11)

printf(“\n *(A + i++) = %2f”, *(A + i++) ); // (12)

printf(“\n *(++i + A) = %2f”, *(++i + A) ); // (13)

printf(“\n *(i-- + A) = %2f”, *(i-- + A) ); // (14)

printf(“\n i--[A] = %2f”, i--[A] ); // (15)

printf(“\n--i[A] = %2f”, --i[A] ); // (16)

}
В строке (1) определяется массив A, состоящий из 5 простых переменных типа float. Первый элемент массива A[0] инициализируется значением 10. Второй элемент A[1] - значением 20, третий A[2] - значением 30., четвертый A[3] - значением 40. . Наконец, последний пятый элемент массива явно не инициализируется, поэтому компилятор занесет в него значение 0. В строке (15) в соответствии с приоритетом выполнения операций в выражении i--[A] сначала вычисляется i[A] , а затем i-- . В строке (16) в выражении --i[A] сначала вычисляется i[A], а затем результат уменьшается на единицу. (Смотри задание 20 лабораторной работы N6.3.)

Так как имя массива - это указатель-константа, то значение имени невозможно изменить. Например, выражение *(++A) - ошибочно.

Операция sizeof, примененная к имени массива, возвращает размер области памяти, занимаемый всем масивом, т.е. число равное числу элементов массива, умноженному на sizeof(тип элемента массива). Например, для массива A, описанного выше, операция sizeof(A) возвратит 20 (байт). Следовательно, отношение sizeof(имя) / sizeof(тип элементов ) равно числу элементов в массиве.
Пример 2.

/*Program 9.2*/

#include

void main()

{

char C[5]; int I[5];

float F[5]; double D[5];

int i,j,k,n;

i = sizeof(C) / sizeof(char) ;

j = sizeof(I) / sizeof(int) ;

k = sizeof(F) / sizeof(float) ;

n = sizeof(D) / sizeof(double) ;

printf(“\n\n\n\n\ Размеp массива C - %d байт(ов)”/

\n Число элементов в массиве C = %d”, sizeof(C), i);

printf(“\n\n Размеp массива I - %d байт(ов)”/

\n Число элементов в массиве I = %d”, sizeof(I), j);

printf(“\n\n Размеp массива F - %d байт(ов)”/

\n Число элементов в массиве F = %d”, sizeof(F), k);

printf(“\n\n Размеp массива D - %d байт(ов)”/

\nЧисло элементов в массиве D = %d”, sizeof(D), n);

}
Многомерный массив в языке С - это массив, элементами которого являются массивы. Синтаксис определения многомерного массива следующий:

Тип Имя_массива [][]...[];

В квадратных скобках - константы или константные выражения целого типа. Например, предложение:

double B[10][5];

определяет массив B, состоящий из 10 элементов, каждый из которых в свою очередь является одномерным массивом, состоящим из пяти переменных типа double. В памяти элементы многомерных массивов располагаются в порядке возрастания самого правого индекса. Для массив B это означает, что самый младший адрес имеет элемент B[0][0] за ним идет B[0][1], потом B[0][2], и т.д. до B[0][4]; потом располагаются B[1][0], B[1][1] и т.д. до B[1][4] и т.д. до B[9][0], B[9][1], ..., B[9][4].

В вычислительных задачах двумерные массивы часто используются для хранения матриц, поэтому иногда говорят, что массивы в языке С хранятся по строкам. Как и в случае одномерных массивов, доступ к элементам многомерных массивов возможен и с помощью индексированных переменных, и с помощью указателей. Возможно объединение этих двух способов в одном выражении. Так, например, *(B+2) адресует начал третьей строки массива B, а выражения:

*(*(B+1)) *(B[1]+1) *(1+1[B]) *(B+1)[1] B[1][1] - эквивалентны.

Доступ к элементам массива осуществляется с помощью адресной арифметики, т.е. с помощью указателей и операции разыменования. Чтобы получить доступ к элементу B[i][j], описанному выше массива B, компилятор выполнит следующие действия:

1. Для вычисления адреса i-той строки к адресу начала массива добавит смещение равное i*5*sizeof(double).

2. Для вычисления адреса j-того элемента в этой строке добавит смещение равное j*sizeof(double). Общее смещение становится равным (i*5+j)*sizeof(double).

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

В следующей программе проиллюстрированы различные способы доступа к элементам двумерного массива B, который предварительно формирутся и выводится на экран.
Пример 3.

/*Program 9.3*/

#include

void main()

{

double B[10][5]; int i,j;

for (i=0; i<10; i++) {

for (j=0; j<5; j++)

B[i][j] = i*10 + (j+1);

}

for (i=0; i

printf (“\n”);

for (j=0; j

printf (“%8.2f “, B[i][j] );

}

printf(“\n\n B = %X”, B);

printf(“\n *B = %X”, *B);

printf(“\n **B = %G”, **B);

printf(“\n *(B+1) = %X”, *(B+1));

printf(“\n *(B+2) = %X”, *(B+2));

printf(“\n *(*(B+1)+2) = %G”, *(*(B+1)+2));

printf(“\n B[1][2] = %G”, B[1][2] );

}
В С допускается использовать массивы указателей. Например, предложение float *C[10]; вводит массив из 10 указателей на элементы типа float.

И указатели на массивы, например, предложение float(*D)[10]; вводит указатель на массив из 10 элементов.

Выражение (C+1) соответствует перемещению в памяти на sizeof(float*) байт от начала массива. (D+1) перемещает на 10*sizeof(float) байтов т.е. на длину всего массива.

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

/*Program 9.4*/

#include

#include

void main()

{

float a[10][10], *p_a[10], *pa, as[10], s;

int i,j,n;

// Задание с консоли матрицы a.

printf (“\n Введите размер матрицы a “);

scanf ( “%d”,&n);

printf (“\n Введите элементы матрицы a по строкам\n”);

for (i=0; i

for (j=0; j

scanf (“%f”,&a[i][j]); }

// Настройка элементов массива указателей p_a на строки матрицы a

for (i=0; i

// Вычисление сумм элементов в каждой строке.

for (i=0; i

for (s=0.,j=0; j

s += fabs(a[i][j]); }

as[i] = s; }

// Сортировка

for (j=0; j

for (i=j+1; i

if (as[j] < as[i]) { s=as[j]; as[j]=as[i]; as[i]=s;

pa = p_a[i]; p_a[i]=p_a[j]; p_a[j]=pa;

}

}

}

// Вывод результирующей матрицы и суммы элементов в каждой //строке на экран

printf (“\n\n”);

for (i=0; i

for (j=0; j

printf (“%7.2f”,p_a[i][j]); }

printf (“%12.2f\n”,as[i]); }
}

Задания.
1. Откомпилируйте программы примеров и запустите их на выполнение. Изучите результаты работы этих программ.

2*. Напишите программу, заносящую все простые числа, лежащие между 2 и N, в одномерный массив и выводящую на экран по требованию простые числа находящиеся между задаваемыми L и M. N должно быть не менее 10000.

Указание. Начните с числа 2 как первого простого. Следующее число I будет простым, если оно не делится нацело на ранее найденные простые числа до SQRT(I) включительно. (Решето Эратосфена).

3*. Напишите программу, которая сортирует в порядке возрастания абсолютных значений вещественные переменные типа double, хранящиеся в одномерном массиве и найдите медиану. Медиана - это число, расположенное в середине упорядоченной последовательности чисел. Если число элементов этой последовательности четно, то нужно взять среднее арифметическое двух чисел, расположенных в середине. Исходная последовательность вводится с консоли. Алгоритм сортировки выберите самостоятельно.

4*. Напишите программу, выполняющую транспонирование исходной матрицы. Организуйте вывод обеих матриц - исходной и транспонированной на экран

5*. Напишите программу для ввода с консоли по строкам матрицы размера N на M. Прочтите и занесите в двумерный массив с ее помощью таблицу распределения Стьюдента. Ограничтесь числом измерений 2-11, 16, 21, 26, 51 и надежностью 0.6, 0.8, 0.9, 0.95, 0.98. Таблицу Стьюдента наберите и отредактируйте в файле. Для чтения используйте функцию перенаправления DOS << .

6.* Пусть в эксперименте получена серия прямых наблюдений величины A - {} Среднее квадратичное отклонение ряда измерений вычисляется по формуле :

,

где - погрешность i-того измерения, - среднее.

Доверительный интервал вычисляется как, где -коэффициент распределения Стьюдента с надежностью при числе наблюдений . Тогда с этой надежностью величина лежит в пределах-<< +

Напишите программу, обрабатывающую результаты измерений и выводящую на экран пределы доверительного интервала [-,+] и относительную погрешность (/)*100% . Величины {}и надежность задаются с консоли. Коэффициент Стьюдента выбирается автоматически из таблицы, которая строится в предыдущем задании.

7*. Напишите программу для вычисления биномиальных коэффициентов :



a) по формуле



б) используя определение треугольника Паскаля



Занесите значения этих коэффициентов в двумерный массив. Для задаваемого с консоли N выведите на экран и запишите в файл, используя функцию перенаправления DOS >>, треугольник Паскаля.
8*. Получите первые 20 чисел последовательности Каталана (1,2,5,14, ...), занесите их в массив и выведите на экран. Последовательность постройте одним из двух способов :

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

b) Используя нерекуррентную формулу для n-го числа последовательности



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

10**. Напишите программу, которая по запрашиваемым с консоли коэффициентам и правым частям системы линейных алгебраических уравнений (СЛАУ) :









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

11**. Напишите программу, переставляющую строки исходной матрицы таким образом, чтобы след получающейся матрицы был максимально возможным. След матрицы - это сумма диагональных элементов.
  1   2   3   4   5   6   7   8

Похожие:

Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа №1 36 Лабораторная работа №2 47 введение данное учебно-методическое пособие представляет собой сборник лабораторных работ
Предлагаемый лабораторный практикум является руководством для выполнения лабораторных работ. Практикум охватывает основные темы дисциплины....
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа по теме: «Одномерные массивы»
Дан массив целых чисел. Найти максимальный элемент массива и его порядковый номер
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа №1 Работа в Oracle Database Express Edition 1 Лабораторная работа №6
Лабораторная работа Выполнение расчетов с использованием программирования в среде Visual Basic for Applications
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по курсу Информатика (раздел Работа с пакетами прикладных программ) для студентов заочной формы обучения
Лабораторная работа №6. Обобщение данных. Создание таблицы подстановки. Подведение итогов 28
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconК ф. м н. А. О. Беляков. Список публикаций
Замечания к статье Л. Д. Акуленко и С. В. Нестерова "Устойчивость равновесия маятника переменной длины". Пмм. 2009. Т. 73. Вып. С....
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconРабочая учебная программа «История и культура страны изучаемого языка»
Форма контроля: 1 курс, второй семестр – зачет; 2 курс, третий семестр – экзамен
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconРабочая учебная программа «История и культура страны изучаемого языка»
Форма контроля: 1 курс, второй семестр – зачет; 2 курс, третий семестр – экзамен
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по гидробиологии Выписка из учебного плана. Форма обучения: очная Курс: IV семестр: VII
Реквизиты составителя. Доцент кафедры зоологии, к б н. Анастасия Михайловна Ларионова
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа «Одномерные массивы»
Цели: формирование практических умений и навыков составления блок-схем и записи на языке программирования Паскаль алгоритмов заполнения,...
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по герпетологии Выписка из учебного плана. Форма обучения: очная Курс: IV семестр: VIII
Реквизиты составителя. Старший преподаватель кафедры зоологии Василий Егорович Колодезников
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org