Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛекцииЛаб(Часть_1_Книги).doc
Скачиваний:
7
Добавлен:
03.05.2019
Размер:
1.04 Mб
Скачать

Упражнения, тесты.

1. Пусть int t=10; int *p=&t; Какие из следующих операторов допустимы и что они означают (что будет выведено, какое значение примет переменная): 1) cout<< p; 2) p=1000; 3) *p=1000; 4) t*=*p; 5) cout<<(*p); 6)cout <<(*p*=2)?

2. Дан код:

void fun1 (int *x, int &y) { (*x)++; y--;} //1

void main() { int a=5, b=2; fun1 (&a, b); //2

cout<< a<< “ “<< b; getch() ; }

Что будет выведено?

Варианты ответов: 1) 6 1; 2) 5 1; 3) 6 2; 4) 5 2; 5) Ошибка в //1;

6) Ошибка в //2; 7) Ошибки в //1 и //2.

3.. Дан код:

void fun4 (int x, int *y) { * y=x*10; } //1

void main() { int a=5, *b=new int (2); //2

fun4 (????????); //3

cout<< a<< “ “<< (*b); getch() ; } //4

Что записать в скобках в строке //3, чтобы вывести 5 50?

Варианты ответов: 1) fun4(a,b); 2) fun4(a, &b); 3) fun4(&a, &b);

4)fun4(a, *b); 5) ошибки (указать номера строк).

4. Дан код:

void fun5(int &x, int *y)

{ ????????????? ; } //1

void main()

{ int a=5, *b=new int; //2

fun5 (a,b); //3

cout<<endl<<a<<" "<<(*b)<<endl; //4

getch(); }

Что записать в тексте функции в строке //1, чтобы вывести 5 15?

Варианты ответов: 1) y=x+10; 2) *y=*x+10; 3) *y=x+10; 4)y=*x+10;

  1. ошибка в //2 6) ошибка в //3 ; 6) ошибка в //4 .

5. Дан код:

int *p1= new int = 11; int *p2; *p2= new int =11; int *p3= new int[11];

int *p4= new int (11); int *p5= new (int) 11; int *p6= new int :11;

Для каких указателей (p1 — p6) правильно резервируется память для одной целочисленной переменной и выполняется её инициализация?

Г л а в а 2

Указатели и массивы

В этой главе изучается связь указателей с одномерными и двумерными массивами, рассматриваются арифметические операции и операции сравнения для указателей на массивы и основанный на них другой метод программирования циклов при работе с одномерными массивами, матрицами и строками. Этот метод явно использует указатели, а не индексы, как это было в первом семестре ([1]). Здесь же рассматривается порядок создания и работы с динамическим одномерным массивом.

§1. Связь указателей и массивов

1.1. Указатели и одномерные массивы

Рассматриваемые выше вопросы усложняются ещё и тем, что для массивов они решаются по-другому. Пусть мы объявили статический массив: const m=10; int a[m]; Этим самым мы не только выделили память для размещения m целых чисел. Без какого-либо дополнительного объявления, без использования символа “*” мы объявили и переменную-указатель с именем a. В этой переменной находится адрес начала массива, т. е. номер первого байта элемента a[0]. Этот адрес можно в программе обозначить ещё и как &a[0].

Идентификатор массива определяется не просто как указатель, а как константный указатель на первый элемент массива. Это означает, что нельзя изменить адрес начала массива, то есть нельзя, например, переменной a присвоить значение другого адреса. Если int *q, то запись a=q; недопустима, а обратное присваивание q=a; или q=&a[0]; разрешено. После этого элементы массива можно обозначать не только a[i], но и q[i], где i =0, 1, 2, …, m-1. Если q=&a[5], то q[0] — это a[5], q[1] — это a[6], и т. д., q[4] — a[9].

При использовании одномерного массива в качестве параметра функции заголовок функции можно записать по-разному. Например, функцию сортировки можно объявить двумя способами:

a) void MySort(int x[], int size); или

b) void MySort(int *x, int size);

В любом случае в качестве параметра передаётся адрес начала массива. Более того, в прототипе можем записать int x[], а в заголовке при определении этой же функции — int * x или наоборот. В тексте функции для доступа к элементу массива можно использовать обычную индексированную переменную x[i]. Но вызов такой функции выполняется одинаково и не зависит от вариантов (a) или b)). В вызывающей функции объявляем статический массив обычным образом, например, const m=10; int a[m]; При вызове функции в качестве фактического параметра надо записать адрес начала массива, если обрабатываем его с самого начала. Поэтому в скобках в таком случае записываем только имя массива a или адрес его первого элемента &a[0], что одно и тоже. Будет ошибка, если при вызове функции в качестве фактического параметра запишем, например, a[i] (так можно писать внутри функции), или a[m] (так объявляем массив), или a[] (так можно определить формальный, а не фактический параметр). Таким образом, функцию можно вызвать одним из следующих способов:

a) MySort (a, m); или MySort (&a[0], m); для сортировки всех m элементов массива;

b) MySort (a, m/2); или MySort (&a[0], m/2); для сортировки m/2 первых элементов массива;

c) Пусть надо рассортировать массив не с самого начала, а, например, с его середины и до конца. Тогда в качестве фактического параметра при вызове такой функции указываем адрес элемента a[m/2], а количество обрабатываемых элементов уменьшаем в два раза: MySort (&a[m/2], m%2 ? m/2+1 : m/2).

Заметим, что в вариантах b) и c) требуется уточнение и пояснение в случае, если m — нечётное. Если, например, m=15, то в варианте b) рассортируем первые 7 элементов массива, то есть меньше половины. В варианте c), начав с a[7], мы должны рассортировать 8= n/2+1 элементов, то есть больше половины. При n чётном (n%2=0, что соответствует false) рассортируем n/2 элементов.

В [1] смотри объяснение, как передаётся одномерный массив в качестве параметра функции.