Содержание:
Теория
1. Основы работы с указателями
- Указатели — это способ указать местоположение переменной. Вместо хранения значения (
5
или символ ‘c
’), значением указателя является адрес другой переменной. - Переменные-указатели имеют размер (количество байт в памяти), имя и значение. Они должны быть объявлены и инициализированы.
- «Указатель» (сам по себе) — это не тип. Это конструктор типов — языковая конструкция, которая при применении к другому типу дает нам новый тип. В частности, добавление звездочки (
*
) после любого типа задает название типу, который является указателем на этот тип. - Объявление указателя сообщает нам имя переменной и тип переменной, на которую будет указывать этот указатель.
- Можно выполнять присваивание указателям, изменяя их значения. Изменение значения указателя означает изменение того, куда он указывает.
- Прежде чем использовать указатель, необходимо инициализировать его (дать ему что-то, на что можно указывать).
- Если мы не инициализируем указатель перед его использованием, то он будет указывать на какое-то случайное место в программе (это может привести к сбою программы).
- Чтобы получить указатель, указывающий на некоторый адрес, нужно назначить имя полю памяти, а затем нам нужно использовать оператор
&
. x
инициализируется значением 5 в той же строке, в которой оно объявлено;- значение
xptr
инициализируется местоположениемx
; - после того, как он инициализирован,
xPtr
указывает на переменнуюx
. - Код
&x = 5;
не будет скомпилирован. Программист может получить доступ к местоположению переменной, но изменить местоположение переменной невозможно. - Как только у нас появятся указатель на адреса переменных, мы хотим использовать их, «следуя за стрелкой» и изменить ячейку, на которую ссылается указатель.
- Символ звездочка
*
— унарный оператор, который разыменовывает указатель. - Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была извлечена, следовательно, x все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 6.
- Обратите внимание, что зеленая стрелка указывает на то, что эта строка еще не была выполнена, следовательно,
x
все еще имеет значение 5 в концептуальном представлении. Однако, как только строка 7 будет выполнена, значение будет равно 6. - При работе с указателями, вы будете использовать звездочку сначала для объявления переменной, а затем для ее разыменования. Только переменные, имеющие тип указателя, могут быть разыменованы.
- Существует только три основных действия с указателем: объявление, присваивание (включая инициализацию) и разыменование.
/* объявляет переменную с именем my_char_pointer с указателем типа на char (переменная, указывающая на символ) */ char * my_char_pointer; |
/* код, который объявляет целое число x и указатель на целое число xPtr */ int x = 5; int *xPtr; xPtr = &x; // устанавливает значение переменной xPtr на адрес x |
6 7 | // Пример использования оператора разыменования: *xPtr = 6; // изменяет значение, которое хptr указывает на 6 |
Два контекста в которых используется (*
), не путайте их:
1. В объявлении переменной, такой как int *p;
, звездочка является частью имени типа и сообщает нам, что нам нужен указатель на какой-либо другой тип (в нашем примере int *
— это тип p
).
2. Когда звездочка является оператором разыменования. Например, код r = *p;
присваивает переменной r
новое значение, а именно значение внутри ячейки памяти, на которую указывает p
. Код *p = r;
изменяет значение внутри ячейки памяти, на которую указывает p
, на новое значение, а именно на значение переменной r
.
int * q = &y; // совпадает с двумя утверждениями: int *q; q = &y; |
обмен значениями
Выполнение: Необходимо передавать указатели a
и b
через аргументы функции, как показано ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> using namespace std; void swap(int *x, int *y) { int temp = *x; // temp временно сохраняет значение, на которое указывает x, =3 *x = *y; // берем значение, на которое указывает y, которое является значением b (=4) //и сохраняем это в значении, на которое указывает x, а именно в переменной a *y = temp; // берем значение temp = 3 и сохраняем его в виде целого числа, //на которое указывает y, т.е. в переменной b } int main() { int a = 3; int b = 4; swap(&a, &b); cout<<"a = "<< a<< ", b = "<< b << endl; system("pause"); return 0; } |
swap
принимает два аргумента, x
и y
, которые являются указателями на целые числа;— поскольку мы получаем доступ к значениям целых чисел, на которые указывают
x
и y
в коде внутри swap, нам придется отменить ссылки на x и y. Итак, вот почему мы будем видеть эти звездочки (*
) перед x и y по всему коду;— внутри
main
, вместо передачи в a
и b
, мы теперь должны передать в адрес a
и адрес b
.
Работа с памятью
- На 32-разрядной машине, где размер адресов составляет 32 бита, все пространство памяти начинается с адреса
0x000000000
(в шестнадцатеричном формате каждый 0 представляет 4 бита 0) и заканчивается на0xFFFFFFFF
(напомним, что 0x обозначает шестнадцатеричный, и что каждоеF
представляет четыре двоичных 1). Каждая программа имеет в своем распоряжении все адресное пространство, и существует соглашение о том, как программа использует этот диапазон адресов. - Если используется значение NULL — указатель ни на что не указывает.
- Нулевой указатель имеет особый тип — void *. Указатель void указывает на на любой тип — мы можем присвоить ему значение int *, double* или любой другой тип указателя, который мы хотим.
Давайте посмотрим на рисунок, чтобы понять, где в памяти хранятся различные компоненты программы.
2. Указатели и массив
- Массив представляет собой константный указатель на свой первый элемент.
- Доступ к элементу массива с помощью арифметики указателей работает нормально и иногда является естественным способом доступа к элементам. Но в случае, когда нам нужен просто n-й элемент массива, было бы громоздко объявлять указатель, добавлять к нему, а затем разыменовывать его.
- Пример:
- Можно достичь этой цели, проиндексировав массив. Когда мы индексируем массив, мы записываем имя массива, за которым следуют квадратные скобки, содержащие номер элемента, на который мы хотим сослаться. Важно отметить, что в C++ индексы массивов начинаются с нуля — первым элементом массива является
myArray[0]
.
// * array : имя массива является указателем на его первый элемент, то есть на 3 void printArr(int *array, int n) { int *ptr = array; // *ptr - это указатель, который указывает на то, куда указывает *array for (int i = 0; i < n; i++) { cout << *ptr; // вывод 1-й итерации - 3, вывод 2-й итерации - 1, // вывод 3-й итерации - 7, //чтобы указатель указывал на ячейку памяти следующего элемента в массиве: // пример адреса ptr = 0x00b5f9a0 ptr++; // 1st 0x00b5f9a4, 2nd 0x00b5f9a8, 0x00b5f9ac, // в массиве нет элемента, но ошибки быть не может // это вызвало бы проблему, если бы мы разыменовали указатель } } int main(){ int arr[4] = { 3,1,7,2 }; printArr(arr, 4); } |
// * array : имя массива является указателем на его первый элемент, то есть на 3 void printArr(int *array, int n) { for (int i = 0; i < n; i++) { cout << array[i]; // 1-я итерация выводит 3, 2-я итерация - 1, 3-я итерация - 7, а затем 2 } } int main(){ int arr[4] = { 3,1,7,2 }; printArr(arr, 4); } |
int a[] {1,3,5,7,9}; int* p = a; // переместите указатель на второй элемент: p++; p++; |
int a[] {1,3,5,7,9}; int* p = a; cout << *(p + 1) << endl; // = a[1]=3 cout << *(p + 2) << endl; // = a[2]=5 |
Символьная строка и указатели
char s[6] = "Hello"; // в конце автоматически добавляется \0 char s[] = "Hello"; // тот же самый результат char* p = s; // H |
Для перебора символьной строки:
char* p = s; while (*p != 0) cout << *p++; |
или
char* p = s; while (*p) cout << *p++; |
Лабораторные работы
1. Основы работы с указателями
Выполнить: Создайте функцию для вычисления суммы значения указателя и переменной целочисленного типа. То есть функция должна возвращать сумму значения, на которое указывает указатель, и значения переменной.
Указание: Объявление функции должно быть таким:
int addP(int var1, int var2); |
Примерный вывод:
введите первое число (указатель): >>>2 введите второе число (которое прибавить): >>>500 результат: указатель + 500 = 502
✍ Алгоритм:
- Создайте проект
Lesson7
. Добавьте в соответствующие папки проекта файлы:main7lab1.cpp
,L7lab1.cpp
,L7lab1.h
. - Откройте
main7.cpp
и подключите все необходимые директивы и файлы. Выведите сообщение пользователю для ввода двух значений. Первое значение — указатель, второе — для добавления: - Переключитесь на код файла
string7.h
и подключите необходимые файлы и директивы: - Добавим объявление функции, как это было рекомендовано в тексте задания:
- Теперь создадим реализацию функции. Откройте файл
string7.cpp
, подключите все необходимые директивы и добавьте код: - Теперь можно вызвать созданную нами функцию и вывести результаты. Это необходимо сделать в файле
main7.cpp
: - Запустите программу и проверьте выходные данные.
cout << "Lab 1:" << endl; cout << "пожалуйста, введите первое число (для указателя): "<< endl; int var1; cin >> var1; cout << "пожалуйста, введите второе число (для добавления): " << endl; int var2; cin >> var2;
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include
// здесь ваш код
#endif
//lab 0: Создайте функцию для вычисления суммы указателя и переменной целочисленного типа int addP(int var1, int var2);
//lab 1: для вычисления суммы значения указателя и переменной целочисленного типа int addP(int var1, int var2) { int* p_var = &var1; return *p_var + var2; }
p_var
инициализируется адресом переменной var1
. Функция возвращает *p_var + var2
— что означает, что мы берем значение, на которое указывает p_var
(то есть значение var1
), и добавляем к нему значение var2
.
cout << "Результат:" << endl; cout << "указатель + " << var2 << " = " << addP(var1,var2) << endl;
Выполнить: Создайте приложение с функцией, которая принимает два аргумента - целые числа (var1
и var2
), и выполняет следующие вычисления со своими аргументами, используя при этом указатели на переменные (p1
и p2
):
1) произведение указателя и переменной:p1 * var1
2) сумма указателей:p1 + p2
3) изменение значенияvar1 = 5
, используя при этом указательp1
4) изменение адреса указателя:p1
(address) =p2
(address)
Указание 1: Чтобы изменить значение переменной:
int* p1 = &var1; // объявляем и инициализируем указатель p1 *p1 = 1; // 1 - это новое значение переменной |
Указание 2: Объявление функции должно быть следующим:
void task1(int var1, int var2); |
Примерный вывод:
Задание 1: Введите первое значение: >>5 Введите второе значение: >>10 произведение указателя и переменной: 25 сумма указателей: 15 результат смены значения var1, var1 = 5 результат ДО смены адреса, p1 = 0098F7E8 результат смены адреса, p1 = 0116FC90
[Solution and Project name: Lesson_7task1
, file name L7Task1main.cpp
, L7Task1imp.cpp
, L7Task1.h
]
2. Указатель на массив
Выполнить: Создайте функцию для вычисления суммы элементов массива. Задача должна быть выполнена с использованием двух функций. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.
Указание 1: Объявление функции:
int sumArray1(int * array, int n); int sumArray2(int * array, int n); |
Примерный вывод:
array: 1 2 3 4 5 результат выполнения первой функции: sum = 15 результат выполнения второй функции: sum = 15
✍ Алгоритм:
- Сначала давайте создадим функцию, которая выполняет итерацию по элементам массива без использования указателя:
- Рассмотрим работу с памятью:
- Теперь давайте создадим функцию, которая выполняет итерацию по элементам массива, используя указатель, обращающийся к элементу массива по индексу:
- Вызовите функцию в функции
main
и запустите программу.
int sumArray1(int * array, int n) // array указывает на значение 1 { // начинаем с суммы, равной 0 int AnswerSum = 0; // count from 0 to n for (int i = 0; i < n; i++) { // добавляем в сумму array[i] AnswerSum += array[i]; } // возвращаем сумму в качестве результата return AnswerSum; } int main() { int data[] = { 1,2,3,4,5 }; cout << "array: " << endl; for (auto x : data) { cout << x << " "; } cout << endl; int sum= sumArray1(data, 5); cout << "результат с первой функцией: sum = " << sum<< endl;
1. Первая итерация цикла: |
2. Вторая итерация цикла: |
3.Третья итерация цикла: |
4.Последняя итерация цикла: |
Возвращаемся к функции main и область sumArray1 уничтожается: |
int sumArray2(int * array, int n) // массив указывает на значение 1 { // начинаем с суммы, равной 0 int AnswerSum = 0; // счетчик цикла - это указатель, указывающий на адрес 1-го элемента массива for (int *p = array; p < array + n; p++) { // добавим в сумму ссылку на p AnswerSum += *p; } // возвращаем сумму return AnswerSum; }
Выполнить: Дан массив целых чисел (
1, 2, 3, 4, 5, 6, 7, 8, 9
). Необходимо каждый второй элемент массива установить в 0 (то есть четные по порядку элементы должны быть = 0). Необходимо использовать индексацию массива.
Указание 1: Объявление функции должно быть следующим:
void DelEveryEven(int* array, int n); |
Примерный вывод:
Лабораторная работа 3, Массивы: Исходный массив: 1 2 3 4 5 6 7 8 9 Результат: 1 0 3 0 5 0 7 0 9
✍ Алгоритм:
- Откройте приложение, которое вы создали для лабораторной 1, или, если вы ее не сделали, сделайте следующее: создайте пустое консольное приложение с именем Lesson7. Добавьте файлы:
main7.cpp
,string7.cpp
,string7.h
. - Подключите все необходимые библиотеки и файлы (если вы не делали этого раньше).
- Откройте файл
main7.cpp
. Выведите сообщение для пользователя, объявите массив и инициализируйте его значениями: - Распечатайте элементы исходного массива:
- После этого откройте файл
string7.h
и подключим все необходимые директивы (если это не было сделано ранее): - Объявление функции должно быть таким, как рекомендовано в задании:
- Теперь необходимо написать саму функцию, т.е. ее реализацию. Откройте файл
string7.cpp
, подключите все необходимые директивы и добавьте код: array
возвращает ячейку памяти первого элемента. Но нам необходимо установить в 0 второй элемент. Поэтому имеемarray + 1
.- В строке
*p = 0
мы разыменовываем указатель, и второй элемент устанавливаем = 0. - Чтобы проделать те же манипуляции с четвертым элементом (четным), мы можем увеличить указатель на 2 (
p = p + 2
). array + n
- ячейка памяти первого элемента +n
, это 9. Затем происходит выход их цикла.- Теперь можно вызвать функцию и вывести результаты. Это необходимо сделать в
main7.cpp
: - Запустите программу и проверьте выходные данные.
cout << "Лабораторная работа 3, Массивы:\n"; int my_arr[] = { 1,2,3,4,5,6,7,8,9 };
cout << "Исходный массив: " << endl; for (auto x : my_arr) { cout << x << " "; }
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include <iostream>
#endif
// Лабораторная работа 3, Массивы: Дан массив (1, 2, 3, 4, 5, 6, 7, 8, 9). // каждый второй элемент установите в 0 void DelEveryEven(int* , int);
//Лабораторная работа 3, массивы void DelEveryEven(int* array, int n) { for (int* p = array + 1; p < array + n; p = p + 2) { *p = 0; } }
*array
инициализируется адресом массива.Рассмотрим строку
int* p = array + 1;
.
DelEveryEven(my_arr, 9); cout << "Результат: " << endl; for (auto x : my_arr) { cout << x << " "; } cout << endl;
Выполнить: Задан массив целых чисел. Создайте две функции, которые возвращают значение максимального элемента массива. Первая функция не использует указатель, вторая функция должна использовать указатель, обращающийся к элементу массива по индексу.
Указание: Объявления функций должны быть следующими:
int maxArray1(int * array, int n); int maxArray2(int * array, int n); |
Примерный вывод:
array: 1 2 3 4 5 результат для первой функции: max = 5 результат для второй функции: max = 5
[Solution and Project name: Lesson_7task2
, file name L7Task2main.cpp
, L7Task2imp.cpp
, L7Task2.h
]
Выполнить: Задан массив положительных и отрицательных целых чисел. Создайте приложение с функцией, которая отрицательные элементы массива трансформирует в положительные значения.
Указание: Объявление функции должно быть следующим:
void SetNegToPos(int* array, int n); |
Примерный вывод:
Task 2: исходный массив: 1 -2 3 4 5 -6 7 8 -9 результат: 1 2 3 4 5 6 7 8 9
[Solution and Project name: Lesson_7task3
, file name L7Task3main.cpp
, L7Task3imp.cpp
, L7Task3.h
]
Выполнить: Задан массив целых чисел. Создайте функцию, которая возвращает индекс максимального элемента массива.
Указание 1: Объявление функции должно быть следующим:
int findLargestInd(int * array, int n); |
Указание 2: Внутри функции должно быть сравнение:
if (array[i] > array[largestIndex]) { ... } |
Примерный вывод:
Задание 4: массив: 1 5 3 2 1 индекс максимального элемента = 1
[Solution and Project name: Lesson_7task4
, file name L7Task4main.cpp
, L7Task4imp.cpp
, L7Task4.h
]
3. Доступ к с-строкам указателем
Выполнить: Даны две строки. Создайте функцию, которая возвращает
1
, если строки равны, и возвращает 0
в противном случае.
Указание 1: Чтобы получить доступ к символам с-строки указателем, необходимо использовать тип char
для этой строки:
char str1[] = "Apple"; |
Указание 2: Объявление функции должно быть следующим:
int stringEqual(const char * str1, const char * str2); |
Примерный вывод:
// lab 4: результат для 'apple' и 'apple' : 1 ++++ // lab 4: результат для 'apple' и 'apples': 0
✍ Алгоритм:
- Объявим функцию с двумя аргументами - константными с-строками:
- Затем объявим указатели, указывающие на первые символы строк
str1
иstr2
. Добавьте код в функцию: - После этого необходимо создать цикл, который будет повторяться до тех пор, пока совпадают символы, на которые указывают указатели
p1
иp2
. Следует использовать оператор разыменования для получения значений: - Кроме того, в цикле следует проверять, не достиг ли указатель
p1
конца строки:\0
(означает конец строки). В этом случае функция должна возвращать1
(то есть ответ "true"): - После этого, мы передвигаем
p1
иp2
к следующей букве: - После цикла необходимо вернуть значение "нет", что в нашей функции означает
0
: - Теперь откройте функцию
main
и создайте две символьных строки. Затем вызовите функцию: - Запустите проект и проверьте результат.
int stringEqual(const char * str1, const char * str2){ ... }
const char* p1 = str1; const char* p2 = str2;
while (*p1 == *p2) {
}
if (*p1 == '\0') { return 1; }
p1++; p2++;
return 0;
char str1[] = "apple"; char str2[] = "apples"; cout << "результат для \'"<< str1 <<"\' и \'"<< str2 <<"\' = " << stringEqual (str1,str2) << endl;
Выполнить: Создайте функцию проверки, содержит ли строка сочетание букв
'mo'
. Функция должна возвращать 1
(если сочетание найдено) или 0
(не найдено). Запрещено использовать стандартные функции. Необходимо использовать указатель.
Указание 1: Заголовок функции должен быть следующим:
bool findMo(const char * str); |
Указание 2: Чтобы проверить, достигнут ли конец строки, необходимо использовать условие цикла:
while (*str != '\0') |
Примерный вывод:
Задание 5:
результат для строки 'the movie was nice' =: 1
[Solution and Project name: Lesson_7task5
, file name L7Task5main.cpp
, L7Task5imp.cpp
, L7Task5.h
]
Выполнить: Создайте функцию для проверки, содержит ли строковая переменная слово "dog
". Функция возвращает 1 или 0. Необходимо использовать символьную строку (с-строку) и указатель. Не допускается использование каких-либо стандартных функций.
Указание 1: Сигнатура функции должна быть следующей:
bool findDog(char* p) |
Примерный вывод:
задание 6 строка: Hello world результат: 0 --- задание 6 строка: my dog is nice результат: 1
Выполнить: Измените порядок символов в строке на обратный. Используйте указатели на символы в начале и конце строки, и, перемещая оба указателя к середине, меняйте местами соответствующие символы.
Указание 1: Чтобы использовать указатель на символы строки, необходимо, чтобы строка была массивом символьного типа (c-строкой):
char str[] = "Hello world"; |
Указание 2: Заголовок функции должен быть следующим:
void reverseString (char * str); |
Примерный вывод:
// lab 4: Исходная строка: Hello world Результат: dlrow olleH
✍ Алгоритм:
- Создайте консольное многофайловое приложение и добавьте в все необходимые библиотеки в (директивы) в файлы проекта.
- Откройте код главного файла (с функцией
main()
). Выведите сообщение пользователю и инициализируйте массив типаchar
(строка будет обрабатываться как массив символов): - Затем откройте заголовочный файл и подключите необходимые директивы (если они требуются):
- Объявление функции было указано в тексте задачи, давайте добавим этот код:
- Создадим реализацию функции. Откройте файл
....cpp
, добавьте необходимые директивы и вставьте следующий код: - После этого будем присваивать значения переменной
*str
, сдвигая указатель с правого конца к середине. Для этого нам пригодится временная переменнаяt
. В то же самое время мы заменяем значения элементов массива: крайнему элемент справа присваиваем значение первого элемента. Здесь нам необходимо использовать разыменовывание указателя: - Вызовите созданную функцию и распечатайте результаты:
- Запустите программу и проверьте результат.
cout << "Lab 4:" << endl; char str[] = "Hello world"; cout << "Исходная строка: " << str << endl;
#pragma once
#ifndef STRING7_H
#define STRING7_H
#include <iostream>
#endif
// Lab 5: Измените порядок символов в строке на обратный. void reverseString(char* str);
str
получает адрес на str[0]
.// Lab 5: Измените порядок символов в строке на обратный. void reverseString(char* str) { char* str1 = str; char* res = nullptr; // пустой указатель while (*str1) { res = str1; *(str1++); } // конец while // ... } // конец функции
char* res = nullptr;
) присваивает значение "null", что означает адрес 0x00000000
. Затем цикл while
перебирает адреса элементов массива. После цикла переменная res
присваивает адрес последнего символа строки, например, адрес 0x00cffae6
переменной, хранящей символ "d
" ). auto l = res; while ((l) > (str)) { auto t = *l; // временная переменная для хранения значений, начиная с последнего, 'd' *l = *str; // разыменовывая, мы берем значение, на которое указывает *str // и сохраняем по адресу, на который указывает *l *str = t; // изменяем значение, на которое указывает указатель *str l--; // передвигаемся по адресам с конца к середине str++; // передвигаемся по адресам с начала к середине }
reverseString(str); cout << "Исходная строка: " << str << endl;
Выполнить: Дана строка, содержащая, помимо слов, положительное целое число (
"С наступающим 2021 годом вас!"
). Создайте функцию для отображения подстроки, содержащей это число.
Указание 1: Используйте следующий заголовок функции (необходимо будет сделать число из полученных цифр):
void numbFromStr(char* str); |
Чтобы понять, когда "наступит" конец строки, можно использовать следующий цикл:
while (*str1) { pLast = str1; // адрес последнего символа *(str1++); } |
Указание 2: Результат должен иметь строковый тип, поэтому следует подключить библиотеку:
#include <string> |
Указание 3: для проверки того, является ли символ цифрой, следует создать логическую функцию:
bool isdigit(char c) { // проверка символа: например, можно использовать c<='9' и т.п. |
Примерный вывод:
Задание 7: Строка: Happy 2021 year to u! подстрока с числом: 2021
[Solution and Project name: Lesson_7task7
, file name L7Task7main.cpp
, L7Task7imp.cpp
, L7Task7.h
]
Выполнить: Дана строка символов. Преобразуйте в нем все заглавные латинские буквы в строчные. Функция должна возвращать количество выполненных замен.
Указание 1: Необходимо использовать тип символьной строки:
char s[] ="..."; |
Указание 2: Используйте следующий заголовок функции. Функция возвращает целое число (количество замен):
int to_lower(char * str); |
Указание 3: Для проверки, не достигнут ли конец строки, можно использовать следующее условие цикла:
while (*str != '\0') |
Указание 3: Чтобы проверить, является ли буква прописной, нужно использовать следующую функцию:
bool isCappital(char ch) { return (ch >= 'A' && ch <= 'Z'); } |
Указание 4: Для конвертации букв в нижний регистр (в маленькие буквы) нужно использовать стандартную функцию tolower(ch)
.
Примерный вывод:
Задание 8: Исходная строка: HelLo wOrLD Результат: hello world
[Solution and Project name: Lesson_7task8
, file name L7Task8main.cpp
, L7Task8imp.cpp
, L7Task8.h
]
Выполнить: Дана символьная строка (с-строка), которая представляет арифметическое выражение в форме: "<digit>±<digit>±...±<digit>"
, где арифметические операции "+
" или "−
" могут располагаться на месте символа "±
" (например, "4+7-2-8
"). Посчитайте результат выражения. Для решения использовать указатель.
Указание 1: Используйте следующий заголовок функции:
int eval(char * expr); |
Указание 2: Чтобы выделить первый символ из строки, можно использовать следующий код:
int res = *expr++ - '0'; // здесь *expr++ это первый символ в строке |
или так:
char r = *expr; //*expr - код в таблице ascii int res = atoi(&r); // конвертирует код в число |
Указание 3: Для хранения числа или знака операции можно использовать следующую концепцию:
char ch1 = *expr++; // может быть как знаком операции (символом), так и числом |
// чтобы использовать переменную, как число: ch1-'0'; |
Примерный вывод:
Задание 9: Строка: 9+4-2-0 Результат: 11
[Solution and Project name: Lesson_7task9
, file name L7Task9main.cpp
, L7Task9imp.cpp
, L7Task9.h
]