Учебная работа. Лабораторная работа: Массивы и указатели в языке программирования Си
«Массивы и указатели в языке программирования Си++»
1.
Теоретические сведения
Цель работы: ознакомиться с главными механизмами работы с одномерными и двумерными массивами. Освоить работу с указателями и операциями над указателями.
Массивы
Массив состоит из нескольких частей 1-го и такого же типа. Можно выбирать хоть какой элемент массива. Для этого нужно задать индекс, который показывает относительную позицию элемента. число частей массива задается при его объявлении и в предстоящем не изменяется. Если массив объявлен, к хоть какому его элементу можно обратиться последующим образом: указать имя массива и индекс его элемента в квадратных скобках.
Массивы объявляются так же, как и переменные. к примеру:
int a[100];
float c[10][20];
В первой строке объявляем массив а из 100 частей целого типа: а[0],a[1], … ,a[99] (индексация постоянно начинается с нуля). Во 2-ой строке объявлен двумерный массив вещественного типа. Двумерный массив представляется как одномерный, элементы которого являются тоже массивами. В первых квадратных скобках указывается количество строк в массиве, во вторых – количество столбцов.
Пример 1. Задан одномерный массив S, состоящий из 10 частей вещественного типа. Вывести на экран монитора значения частей этого массива в оборотном порядке.
#include <stdio.h>
main()
{float s[10];
int i;
for (i=0;i<10;i++)
scanf(«%f»,&s[i]); /*ввод частей массива*/
for (i=9;i>=0;i—)
printf(«%f»,s[i]); /* вывод частей в оборотном порядке*/
}
Пример 2. Задана двумерная матрица а, имеющая 5 строк и 5 столбцов. Найти номер строчки с большим числом единиц в данной для нас строке.
#include <stdio.h>
main()
{int i,j,p,q=0,f=0,a[5][5];
for (i=0;i<5;i++)
for (j=0;j<5;j++)
scanf(«%d», &a[i][j]); /*ввод матрицы*/
/*поиск в матрице а строчки с большим числом единиц*/
for (i=0;i<5;i++)
{p=0;
for (j=0;j<5;j++)
if (f[i][j]==1) p++;
if (q<p) {q=p; f=i;}
}
/*f – номер строчки с большим числом единиц, q – число единиц в f-й строке*/
printf(«%d %d»,f,q);
}
Пример 3. Переставить местами элементы главной и побочной диагоналей массива D(6,6). Полученную матрицу вывести на экран монитора.
#include <stdio.h>
main()
{int i,j,a,d[6][6];
for (i=0;i<6;i++)
for (j=0;j<6;j++)
scanf(«%d», &d[i][j]); /*ввод матрицы*/
/*перестановка местами частей главной и побочной диагоналей*/
for (i=0; i<5; i++)
{a=d[i][i];
d[i][i]=d[i][6-i];
d[i][6-i]=a;
}
for (i=0; i<6; i++)
for (j=0; j<6; j++)
printf(«%d%c», d[i][j], (j==5)?»n»:» «);
/*вывод по строчкам частей матрицы*/
}
При выводе частей матрицы по строчкам использована тернарная операция. Смысл данной для нас операции сводится к последующему: если j=5 (закончен вывод частей по строке), то курсор переводится в начало последующей строчки (работает символьная константа «n»), в неприятном случае выводится один пробел. Потому что в операторе вывода употребляется символьная константа, то использована спецификация %c.
В заключении этого раздела отметим, что массив можно инициализировать, т.е. присвоить его элементам исходные значения. Это делается при объявлении типа массива, к примеру: int a[5]= { 0, 0, 0, 0, 0};
Это означает, что все элементы массива получают нулевое
Двумерный массив можно инициализировать последующим образом:
int a[3][3] = {{10,20,30},
{40,50,60},
{70,80,90}};
При инициализации число частей можно не указывать, т.к. в этом случае оно быть может вычислено по количеству присваиваемых значений (в фигурных скобках), к примеру:
int a[] = {10,20,30,40,50};
Указатели
Указатели и одномерные массивы
Указатель – это переменная, которая содержит адресок переменной. Потому что указатель – это адресок некого объекта, то через него можно обращаться к данному объекту.
В СИ существует тесноватая связь меж указателями и массивами. Хоть какой доступ к элементу массива, осуществляемый операцией индексирования, быть может выполнен с помощью указателя.
Декларация
int a[10];
описывает массив а размера 10, т.е. блок из 10 поочередных объектов, представленных на рисунке, с именами a[0], a[1], … ,a[9].
Запись a[i] отсылает нас к i-му элементу массива. Если ра есть указатель, т.е. определен как int *pa;, то в итоге присваивания
pa = &a[0];
pa будет указывать на нулевой элемент массива а; по другому говоря, ра будет содержать адресок элемента a[0] (см. рис.). сейчас присваивание
x=*pa;
будет копировать содержимое а[0] в х.
Если ра показывает на некий элемент массива, то ра+1 по определению показывает на последующий элемент (см. рис.).Таковым образом, если ра показывает на a[0], то *(ра+1) есть содержимое a[1], ра+1 – адресок a[1], *(ра+i) – содержимое a[i].
Так как имя массива есть не что другое как адресок его исходного элемента, присваивание
pa=&a[0];
можно также записать в последующем виде:
pa = a;
Потому что ра – указатель , то в выражениях его можно употреблять с индексом, другими словами запись pa[i] эквивалентна записи *(pa+i). Элемент массива идиентично разрешается изображать и в виде указателя со смещением, и в виде имени массива с индексом.
Меж именованием массива и указателем, выступающим в роли имени массива, существует одно различие. Указатель – это переменная, потому можно написать pa=a либо pa++. Но имя массива не является переменной, и запись типа a=pa не допускается. Следует также различать выражения *(a+2) и *a+2: *(а+2) –
Пример 4. Вывести значения одномерного массива обыденным методом и с внедрением указателей.
#include <stdio.h>
int a[6]={10,20,30,40,50,60};
/*объявление и инициализация массива*/
main ()
{int i, *p;
for (i=0; i<6; i++)
printf(«%d»,a[i]); /*вывод массива обыденным методом*/
for (p=&a[0];p<=&a[5];p++)
printf(«%d»,*p); /*вывод массива с внедрением указателя*/
for (p=&a[0],i=0; i<6; i++)
printf(«%d»,p[i]); /*еще один вариант с внедрением указателя*/
}
Дадим еще некие пояснения. Операция р++ наращивает адресок элемента a[i+1].
Пример 5. Отыскать среднее арифметическое массива, состоящего из 6 частей, с внедрением указателя.
#include <stdio.h>
int a[]={10,20,30,40,50,60}
main()
{int i,*p;
float s;
p=a; /*указатель получает
for (s=0,i=0; i<6; i++)
s+=*(p+i); /*получение суммы частей массива*/
s=s/6; /*среднее арифметическое массива*/
printf(«%f»,s);
}
Пример 6. Решить задачку, приведенную в примере 1, с внедрением указателя.
#include <stdio.h>
main()
{float s[10];
int *p,i;
for (i=0;i<10;i++)
scanf(«%f»,s[i]);
p=&s[9]; /*указатель получает
for (i=0; i<10; i++)
printf(«%f»,*(p-i)); /*вывод частей в оборотном порядке*/
for (p=&a[9]; p>=&a[0]; p—) /*еще один метод вывода частей в оборотном порядке*/
printf(«/n%d»,*p);
}
Указатели и двумерные массивы
Представим, что у нас есть описания:
int z[4][2]; /**/
int pz; /
**/
Тогда pz=z показывает на нулевой столбец нулевой строчки, т.е.
pz=&z[0][0];
Пример 7. Вывести на экран значения нулевого, второго и 4-ого частей массива.
#include <stdio.h>
int a[]=(10,20,30,40,50,60); /*объявление и инициализация массива а*/
main()
{
for (p=a,i=0; p+i<=a+4; p++, i++)
printf(«%d»; (p+i)); /
*вывод на экран значений нулевого, второго и 4-ого частей*/
}
В цикле происходит одновременное повышение указателя р и индекса i на единицу, вследствие что на экран опосля нулевого элемента выводится 2-ой, и потом 4-ый. Так как элементы двумерного массива хранятся в памяти ЭВМ по строчкам, то
pz+1 = &z[0][1], pz+2 = &z[1][0], pz+3 = &z[1][1] и т.д.
Двумерный массив описан как массив массивов. Если z является именованием массива, то каковы имена 4 строк, любая из которых является массивом из 2-ух частей? имя первой строчки z[0], 2-ой — z[1], и т.д. Но имя массива является также указателем на этот массив в том смысле, что оно ссылается на 1-ый его элемент. означает:
z[0]=&z[0][0], z[1]=&z[1][0], z[2]=&z[2][0], z[3]=&z[3][0].
Пример 8. Задана матрица а. Вывести на экран элементы главной диагонали, первой строчки и значений первых частей каждой строчки матрицы, применив для этого указатели.
#include <stdio.h>
int a[3][3]={{10,20,30},
{40,50,60},
{70,80,90}};
/*объявление и инициализация двумерного массива*/
int *pa[3]={a[0],a[1],a[2]};
/*объявление и инициализация указателя ра на строчки массива а и присвоение исходных значений : pa[0]=a[0]; pa[1]=a[1]; pa[2]=a[2]*/
int p=a[0]; /
*объявление указателя на нулевой элемент нулевой строчки массива а*/
main ()
{int i;
for (i=0;i<9;i+=4)
printf(«%d»,*(p+i)); /*вывод на экран частей главной диагонали*/
for (i=0; i<3; i++)
printf(«%d»,*p[i]); /*вывод на экран частей первой строчки*/
for (i=0; i<3; i++)
printf(«%d»,pa[i]); /*вывод на экран первых частей каждой строчки матрицы*/
}
Создадим некие пояснения для первого оператора цикла. Представим матрицу в виде одномерного массива, записанного по строчкам:
a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2],a[2][0],a[2][1],a[2][2]
Тогда элементы, стоящие на главной диагонали, занимают нулевое, 4-ое и восьмое места, т.е. интервал меж интересующими нас элементами равен четырем, потому переменная i меняется с шагом 4. Соответственно с таковым же шагом изменяются адреса ячеек, содержимое которых выводится на экран.
2. Задание
Задание взять из таблицы согласно данному варианту. Написать два варианта программки: без внедрения указателей и с указателями.
Таблица
№ варианта
Задание
1
Найти, является ли данная квадратная матрица А(5,5) симметричной относительно главной диагонали.
2
Задана матрица В(4,4). Найти, отсортированы ли все элементы первого столбца в вырастающем порядке.
3
Задана матрица С(5,5). Поменять местами наибольший элемент каждой строчки с первым элементом соответственной строчки.
4
Переписать 1-ые элементы каждой строчки матрицы D(3,3), которые больше 10, в массив В.
5
Задана матрица Q(5,5). Поменять крайний нуль в каждой строке на 5.
6
Задана матрица D(4,4). Найти наибольший посреди положительных, малый посреди отрицательных и поменять их местами.
7
Задана матрица А(4,4). Поменять 1-ый нуль в любом столбце на количество нулей в этом столбце.
8
Задана матрица F(9,3). найти, равны ли все элементы первого столбца подходящим элементам главной диагонали. Если нет, то поменять их местами.
9
Задана матрица C(5,5). Получить вектор В, любой элемент которого равен количеству нулей, стоящих в столбце матрицы.
10
Задана матрица В(4,4). Если в строке есть хотя бы одна единица, то поменять эту строчку нулями.
11
Задана матрица Q(3,3). Если на главной диагонали стоит нуль, то подобающую строчку поменять единицами.
12
Задана матрица D(4,4). Если наибольший элемент матрицы стоит на главной диагонали, то все элементы главной диагонали создать равными наибольшему.
13
Задана матрица С(5,5). Если малый элемент стоит в первой строке, то все элементы, стоящие в строке за ним, поменять нулями.
14
Задана матрица А(4,4). Если наибольший элемент матрицы равен сумме частей первой строчки, то поменять местами первую строчку с той строчкой, где находится наибольший элемент.
15
Задана матрица А(4,4). Если наибольший элемент матрицы равен сумме частей первой строчки, то поменять местами первую строчку с той строчкой, где находится наибольший элемент.
Литература
1. Подбельский В.В. язык Cu ++: Учебное пособие. — М.: Деньги и статистика,1995, — 560 с.
2. Страуструп Б. язык программирования Сг ++. — М.: Радио и связь, 1991. — 352 стр.
3. Собоцинский В.В. Практический курс Turbo Cu ++. Базы объктно- нацеленного программирования. — М.: свет, 1993. — 236 с.
4. Романов В.Ю. Программирование на языке Cu ++. Практический подход. — М.: Компьтер, 1993. — 160 с.
5. Уинер Р. язык турбо Cu . — М.: Мир, 1991. — 384 с.
6. Юлин В.А., Булатова И.Р. Приглашение к Cu. — Мн.: Высш. Шк., 1990,- 224 с.
7. Котлинская Г.П., Галиновский О.И. Программирование на языке Cu. -Мн.: Высш. Шк., 1991. — 156 с.
]]>