
- •220300 - Системы автоматизированного проектирования
- •Состав языка и принцип работы компилятора языка высокого уровня
- •Идентификаторы
- •Альтернативный ввод-вывод в стиле с
- •Константы
- •Манипуляторы
- •Преобразования типов
- •Арифметические операции
- •Функции стандартной библиотеки
- •Операции отношения и логические операции
- •Базовые конструкции структурного программирования
- •Цикл с параметром (for)
- •Цикл с предусловием (while)
- •Цикл с постусловием (do while)
- •Рекомендации по программированию циклов
- •Ветвления
- •Условный оператор if
- •Вложенные конструкции
- •Проблемы соответствия if и else во вложенных ветвлениях
- •Условная операция
- •Оператор switch
- •Операторы передачи управления
- •Контрольная работа
- •Массивы
- •Сортировка массива методом выбора
- •Сортировка массива методом пузырька
- •Многомерные массивы
- •Операции со строками
- •Функции
- •Void starline(); // объявление функции (прототип)
- •Передача аргументов в функцию по значению
- •Void charline(char sim, int n); // объявление функции (прототип)
- •Возвращение функцией значения
- •Передача аргументов по ссылке
- •Возвращение значения по ссылке
- •Перегруженные функции
- •Переменные и функции
- •Передача массивов в функции
- •Указатели
- •Указатели и массивы
- •Указатели и функции
- •Указатели и строки
- •Динамический массив и динамическое выделение памяти
- •Ввод/вывод
- •Форматированный ввод/вывод
- •Конструкторы и методы
- •Двоичный ввод/вывод. Бинарные файлы
- •Двунаправленный ввод/вывод
- •Функции стандартной библиотеки для работы с файлами или ввод/вывод в стиле с
Указатели и массивы
Доступ к элементам массива можно получить как используя прямой доступ, так и используя указатели. Приведём пример.
int main() {
int array[5] = { 31, 54, 77, 52, 93 }; // набор целых чисел
for(int j = 0; j < 5; j++) // для каждого элемента массива напечатаем его значение
cout << *(array + j) << endl; // *(array + j) – это то же самое, что и array[j]
getch(); return 0;
}
Указатели и функции
Напомним, что передача аргументов в функцию может быть произведена тремя способами: по значению, по ссылке, по указателю. Мы уже рассматривали ситуации, когда необходимо использовать передачу аргументов по ссылке. В этой же ситуации можно использовать и передачу по указателю.
Рассмотрим две версии программы, в которой используется функция для перевода дюймов в сантиметры.
Передача аргумента по ссылке
#include <iostream> #include <conio> using namespace std; void centimize(double& v); int main() { double var; cout << "Vvedite kol-vo duymov: "; cin >> var; centimize(var); cout << "Eto " << var << " sm" << endl; getch(); return 0; } void centimize(double& v) { v = v*2.54; // v — это то же самое, что и var } |
Передача аргумента по указателю
#include <iostream> #include <conio> using namespace std; void centimize(double* ptr); int main() { double var; cout << "Vvedite kol-vo duymov: "; cin >> var; centimize(&var); cout << "Eto " << var << " sm" << endl; getch(); return 0; } void centimize(double* ptr) { *ptr = *ptr * 2.54; // *ptr — это то же, что и var } |
Как видно из приведённого примера, передача указателя в функцию в качестве аргумента довольно похожа на передачу по ссылке. Эти два механизма позволяют переменной вызывающей программы быть изменённой в функции. Однако эти механизмы различны. Ссылка – это псевдоним (синоним) переменной, а указатель – это адрес переменной. Таким образом, при использовании указателей функция передаёт в качестве аргумента адрес переменной centimize(&var);. Так как функция получает адрес, то необходимо использовать операцию разыменовывания для доступа к значению, расположенному по этому адресу.
Рассмотрим следующий пример, демонстрирующий использование указателей при передаче массивов в функцию.
…
const int MAX = 5; // количество элементов в массиве
void centimize(double* ptr); // прототип функции
int main() {
double arr[MAX] = { 10.0, 43.1, 95.9, 58.7, 87.3 }; //дюймы
centimize(arr); // переводим все элементы массива в сантиметры
for(int j = 0; j < MAX; j++) // покажем, что у нас получилось
cout << "Element [" << j << "] = " << arr[j] << " sm" << endl;
getch(); return 0;
}
//---------------------------------------------------------------------------
void centimize(double* ptr) {
for(int j = 0; j < MAX; j++)
*ptr++ *= 2.54; // или *(ptr + j) *= 2.54;
}
Так как имя массива является его адресом, то нет надобности использовать операцию взятия адреса & при вызове функции: centimize(arr);. Унарные операции * и ++ имеют правую ассоциативность, поэтому компилятор интерпретирует выражение *ptr++ как *(ptr++) и увеличивает указатель, а не то, на что он указывает. Таким образом, здесь сначала увеличивается указатель, а затем к результату применяется операция разыменовывания.