Введение
В программировании на языке C указатели (pointers) являются мощной возможностью, которая позволяет нам манипулировать данными, напрямую обращаясь к ячейкам памяти и изменяя их содержимое. Одна из распространенных применений указателей - это обмен значениями между двумя переменными без использования третьей переменной.
В этом лабораторном занятии (LabEx) мы научимся создавать программу на языке C, которая меняет местами два числа с использованием указателей. Этот метод является фундаментальным в различных сценариях программирования и демонстрирует практическое применение указателей для манипуляции памятью.
В рамках лабораторной работы вы научитесь создавать программу с нуля, компилировать ее и запускать, чтобы увидеть, как происходит обмен значениями.
Понимание указателей в языке C
Перед тем, как приступить к написанию кода, давайте разберемся, что такое указатели (pointers) и как они работают в языке C.
Что такое указатель?
Указатель - это переменная, которая хранит адрес памяти другой переменной. Указатели являются важной частью языка C, так как они позволяют напрямую обращаться к памяти и обеспечивают более эффективную манипуляцию данными.
Синтаксис указателей
В языке C указатели объявляются с использованием символа звездочки (*):
int *ptr; // Declares a pointer to an integer
При работе с указателями мы используем два важных оператора:
- Оператор взятия адреса (
&) - возвращает адрес памяти переменной - Оператор разыменования (
*) - позволяет получить значение, хранящееся по адресу, который содержится в указателе
Создание первого файла
Начнем с создания основного файла на языке C в директории проекта. Откройте среду разработки (IDE) и создайте новый файл с именем main.c:
- В панели проводника файлов (слева) перейдите в директорию
/home/labex/project - Щелкните правой кнопкой мыши и выберите "Новый файл"
- Назовите файл
main.c - Добавьте в файл следующую базовую структуру:
#include <stdio.h>
int main() {
// We will add our code here
return 0;
}
Это создаст простую программу на языке C с подключенной стандартной библиотекой ввода-вывода и главной функцией, которая возвращает 0 при успешном завершении программы.
Создание структуры программы для обмена значений
Теперь, когда мы понимаем, как работают указатели, давайте построим программу для обмена значений пошагово.
Объявление переменных и указателей
Нам нужно объявить:
- Две целочисленные переменные (
aиb), в которых будут храниться значения, которые мы хотим поменять местами. - Два целочисленных указателя (
ptraиptrb), которые будут хранить адреса переменныхaиb. - Временную переменную (
temp), которая поможет в операции обмена значений.
Обновите файл main.c следующим кодом:
#include <stdio.h>
int main() {
// Declare variables
int a, b;
int *ptra, *ptrb;
int temp;
// Get input from user
printf("Enter value for a: ");
scanf("%d", &a);
printf("Enter value for b: ");
scanf("%d", &b);
// Display original values
printf("\nOriginal values:\n");
printf("a = %d\n", a);
printf("b = %d\n", b);
// We will add more code here in the next step
return 0;
}
Понимание кода
Давайте проанализируем, что мы сделали до сих пор:
- Мы объявили две целочисленные переменные
aиb, в которых будут храниться значения, которые мы хотим поменять местами. - Мы объявили два целочисленных указателя
ptraиptrb, которые будут хранить адреса памяти переменныхaиb. - Мы объявили временную целочисленную переменную
temp, которая поможет нам в операции обмена значений. - Мы добавили код, чтобы запросить у пользователя значения для переменных
aиb. - Мы добавили код, чтобы отобразить исходные значения переменных
aиb.
Обратите внимание, что в функции scanf мы используем оператор взятия адреса (&), чтобы сообщить функции, где в памяти хранить введенные значения.
Реализация логики обмена значений
Теперь давайте реализуем фактическую логику обмена значений с использованием указателей.
Присваивание адресов указателям
Сначала нам нужно сделать так, чтобы наши указатели указывали на наши переменные, присвоив адреса переменных a и b соответственно указателям ptra и ptrb:
// Assign addresses to pointers
ptra = &a;
ptrb = &b;
Алгоритм обмена значений с использованием указателей
Ключ к обмену значений с помощью указателей - это манипулирование значениями в ячейках памяти, а не просто указателями самими по себе. Вот как мы это сделаем:
- Сохраните значение переменной
a(доступное через*ptra) во временной переменнойtemp. - Присвойте значение переменной
b(доступное через*ptrb) переменнойa(с использованием*ptra). - Присвойте временное значение (исходное значение переменной
a) переменнойb(с использованием*ptrb).
Обновите файл main.c, добавив следующий код в место, указанное на предыдущем шаге:
#include <stdio.h>
int main() {
// Declare variables
int a, b;
int *ptra, *ptrb;
int temp;
// Get input from user
printf("Enter value for a: ");
scanf("%d", &a);
printf("Enter value for b: ");
scanf("%d", &b);
// Display original values
printf("\nOriginal values:\n");
printf("a = %d\n", a);
printf("b = %d\n", b);
// Assign addresses to pointers
ptra = &a;
ptrb = &b;
// Display memory addresses (optional but helpful for understanding)
printf("\nMemory addresses:\n");
printf("Address of a: %p\n", ptra);
printf("Address of b: %p\n", ptrb);
// Swap the values using pointers
temp = *ptra; // Store value of a in temp
*ptra = *ptrb; // Assign value of b to a
*ptrb = temp; // Assign original value of a to b
// Display swapped values
printf("\nAfter swapping:\n");
printf("a = %d\n", a);
printf("b = %d\n", b);
return 0;
}
Понимание логики обмена значений
Давайте разберёмся, как именно работает обмен значений:
temp = *ptra;- Оператор*разыменовывает указатель, давая доступ к значению в ячейке памяти. Эта строка сохраняет значение переменнойaв переменнойtemp.*ptra = *ptrb;- Эта строка присваивает значение переменнойbячейке памяти переменнойa, фактически изменяя значение переменнойa.*ptrb = temp;- Эта строка присваивает исходное значение переменнойa(сохраненное вtemp) ячейке памяти переменнойb, завершая обмен значений.
После этих операций переменные a и b поменяли значения без прямого изменения их - мы только изменили значения в их ячейках памяти.
Компиляция и тестирование программы для обмена значений
Теперь, когда мы завершили написание программы, давайте скомпилируем и запустим ее, чтобы увидеть результаты.
Компиляция программы
Для компиляции программы мы будем использовать GNU C Compiler (gcc). Откройте терминал в WebIDE и выполните следующую команду:
cd ~/project
gcc main.c -o swap_program
Эта команда компилирует наш файл main.c и создает исполняемый файл с именем swap_program.
Запуск программы
Теперь давайте запустим нашу программу, чтобы проверить, правильно ли она меняет местами значения:
./swap_program
Вам будет предложено ввести значения для переменных a и b. Например, введем:
a= 5b= 10
Программа должна отобразить:
- Исходные значения: a = 5, b = 10
- Адреса памяти переменных a и b
- Поменянные местами значения: a = 10, b = 5
Понимание вывода программы
При запуске программы вы увидите несколько разделов вывода:
- Исходные значения - показывает значения до обмена.
- Адреса памяти - показывает, где в памяти хранятся переменные (каждый раз при запуске программы они будут разными).
- После обмена - показывает значения после операции обмена.
Попробуйте запустить программу несколько раз с разными входными значениями, чтобы убедиться, что обмен работает стабильно.
Как это работает "под капотом"?
Давайте визуализируем, что происходит в памяти:
- Изначально, если
a = 5иb = 10, каждая из них имеет свою собственную ячейку памяти. ptraуказывает на ячейку памяти переменнойa.ptrbуказывает на ячейку памяти переменнойb.- Во время обмена:
tempполучает значение по адресуptra(которое равно 5).- Значение по адресу
ptraменяется на значение по адресуptrb(которое равно 10). - Значение по адресу
ptrbменяется на значениеtemp(которое равно 5).
- После обмена
a = 10иb = 5, фактически поменяв местами свои значения.
Это демонстрирует мощь указателей - они позволяют нам косвенно изменять значения, напрямую манипулируя ячейками памяти.
Резюме
В этом практическом занятии (лабораторной работе) мы научились использовать указатели в языке C для обмена значений двух переменных. Основные концепции, которые были рассмотрены:
- Указатели: Переменные, которые хранят адреса памяти других переменных.
- Адреса памяти: Уникальные места в компьютерной памяти, где хранятся данные.
- Операции с указателями:
- Оператор взятия адреса (
&) для получения адреса памяти переменной. - Оператор разыменования (
*) для доступа к значению по адресу памяти.
- Оператор взятия адреса (
- Алгоритм обмена: Использование временной переменной и указателей для обмена значений.
Эта техника является фундаментальной концепцией в программировании на языке C и демонстрирует мощь указателей для манипуляции памятью. Она может быть применена в различных сценариях программирования, таких как алгоритмы сортировки, операции с структурами данных и реализация функций.
Понимая, как манипулировать данными через адреса памяти, вы сделали важный шаг в овладении программированием на языке C и концепциями компьютерной памяти.



