Обратите внимание, что они отличаются на 1. Почему это произошло?




САОД. Задание 2

Темы

· указатели и ссылки,

· массивы,

· z-строки,

· передача параметров.

Задания

1. Запустить Visual Studio и создать на рабочем столе проект “ pointer ”. Убедиться, что стоит птичка “Создать каталог для проекта”.

a. Подключить в stdafx.h ввод-вывод.

b. В main ввести код:
int x = 3;
int *p = &x;
cout << x << ' ' << *p << ' ' << p << endl;

c. Убедиться, что х и *p равны 3, а p – адрес x, т.е. *p получили значение.

d. Добавить строчки p++; cout << p << endl;

e. Убедиться, что p++ передвинула адрес на 4 байта (размер целого).

f. Добавить cout << p - &x<< endl;
Убедиться, что результат (разность двух указателей) равен 1 (между ними 1 целое число);

 

2. Следующее упражнение трудно сделать без указателей. Посмотрим, как целое число размещено в памяти по байтам. Преобразуем тип указателя к byte* и выведем байты в цикле:

typedef unsigned char byte; // Нет встроенного byte

byte *pb = (byte *)--p; // вернули указатель на x и преобразовали

for (byte *pt = pb; pt - pb<sizeof(int); pt++)

cout << (int)*pt << ' '; // выводим как int

cout << endl;

 

Разобрать текст. Задать вопросы, если что-то непонятно.

Обратите внимание, что целое 3 расположено в памяти не как 0 0 0 3, а как 3 0 0 0. Расположение в памяти зависит от платформы.

 

3. Самостоятельно. Разработать функцию Swap с использованием указателей.

a. Закомментируйте весь код в main.

b. Объявите две целочисленных переменных int a = 3, b=5; и прямо в main напишите код, который приведет к обмену переменных значениями.

c. Убедитесь, что он работает. До обмена a = 3, b =5, после обмена a = 5, b =3.

d. Добавьте функцию типа
void Swap(int a, int b)
перед main и перенесите в нее код обмена значениями.

e. Вызовите ее в main и убедитесь, что она не работает. Подумайте почему.

 

Очевидно, что если бы в функцию попали адреса фактических параметров, то задачу бы выполнить удалось.

 

f. Самостоятельно доработайте функцию, чтобы оп-на принимала параметры-указатели void Swap(int *pa, int *pb).

g. Убедитесь, что теперь функция работает. Вызывать конечно нужно, передавая в нее адреса переменных (& a, & b).

h. Вспомните (по лекции) про параметры, которые передаются по ссылке.
Изменяем на void Swap(int &pa, int &pb) и внесите необходимые изменения в ее реализацию и вывод (теперь при вызове указываем только имена переменных, а не адреса).
Убедитесь, что так удобнее и более естественно, а функция работает

 

ИТОГ:

Теперь стало более понятно, как работают указатели.

 

4. Переносим функцию Swap в отдельный модуль (utils.cpp и utils.h)

a. Добавляем оба файла в проект;

b. В utils.h переносим прототип функции, а в utils.cpp реализацию;

c. В utils.cpp первой строкой добавляем #include “stdafx.h ” (т.к. проект сконфигурирован на использование прекомпилированных файлов).

d. В основном модуле включаем заголовок “ utils.h ”;

e. Проверяем, что все работает, или добиваемся, чтобы работало.

 

5. Знакомство с массивами.

a. Создать новый проект arrays. Подключить консольный ввод-вывод;

b. В main объявить массив и вывести его на консоль в одну строку
int a[5]{1,2,3,4,5};
for(int i = 0; i<5; i++)
cout<<a[i] << ' ';
cout<<endl;

c. Вывести массив с помощью указателя на целое:

for (int *p = a; p-a<5; p++)

cout << *p << ' ';

cout << endl;

d. Разберитесь как работает цикл!

 

6. Передача массива как параметр:

a. Создать функцию, которая выполняет циклическую перестановку массива
void rotate (int a[], int n) { int x = a[0];

for (int i = 1; i < n; i++)

a[i - 1] = a[i];

a[n - 1] = x;}

b. Проверить, что функция работает или добиться, чтобы работала!

 

Обратите внимание, что при передаче в функцию размер массива нужно указывать. Имя массива – это просто указатель на блок памяти и размер его не известен!

 

c. Реализуйте функцию через указатели без использования целочисленного счетчика i.

 

7. Z -строки.

a. Создать новый проект strings.

b. Необходимо объявить строку вывести ее на консоль.

Встроенного типа string в C++ нет. Используется массив символов.
char str[] = "Hello!";

cout << str << endl;

c. Вывести на консоль размер массива и длину строки:
cout << strlen(str) << ' ' << sizeof(str) << endl;

Обратите внимание, что они отличаются на 1. Почему это произошло?

 

d. Создайте дополнительный массив символов и скопируйте в него строку:
char t[32];
for (char *pd = t, *ps = str; *pd++ = *ps++;);

e. Убедитесь, что произошло копирование. Разберитесь с текстом как происходит копирование. Перепишите цикл менее компактно, но более понятно.

f. Вынесите текст в функцию void string_copy(char *d, char*s);

8. Вынесите функцию в utils.

9. Реализуйте самостоятельно функции:

a. int len(const char *s); // Функция возвращает количество символов в строке.

b. int compare(const char *s, const char *t);
Функция должна возвращать целое > 0, если s > t, < 0, если s < t и 0, если s == t;

 

Если не успеваете, то проделайте эти упражнения дома.

 

10. Завершайте работу, удалите ненужные файлы, архивируйте решение и сохраняйте на сетевом диске или на флэшке.

 

ИТОГ:

Теперь мы умеем:

· Объявлять и использовать указатели;

· Передавать параметры по ссылке;

· Объявлять и использовать массивы;

· Работать с z-строками. (сами не будем, есть много стандартных функций, но, в принципе, умеем)

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2020-01-14 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: