- •Материалы для подоговки к экзамену по дисциплине «основы программировния»
- •Тема №1 Основные понятия
- •Способы записи алгоритма
- •Тема №2 Переменные
- •Типы переменных
- •Типы с плавающей точкой
- •Переполнение переменных
- •Постфиксное обозначение типа
- •Шестнадцатеричный и восьмеричный формат
- •Экспоненциальная форма представления чисел
- •Объявление переменных
- •Начальное значение переменной
- •Область видимости переменной
- •Тема №3 Оператор присваивания
- •Ввод-вывод Форматированный вывод
- •Форматированный ввод
- •Непечатные символы
- •Тема №4 Ветвления и логические операторы
- •Оператор Switch
- •Логические операторы
- •Логическое отрицание
- •Логическое и
- •Логическое или
- •Пример: закон де-Моргана.
- •Порядок выполнения логических операторов
- •Тема №5 Циклы
- •Цикл с предусловием
- •Циклы с постусловием
- •Цикл for
- •Вложенные циклы
- •Тема №6 Одномерные массивы
- •Начальная инициализация массива.
- •Размер массива
- •Переполнение массива
- •Пример с одномерным массивом
- •Многомерные статические массивы
- •Пример с многомерным массивом
- •Тема №7 Строки в си. Введение
- •Чтение строк
- •Указатели
- •Определение
- •Арифметика указателей
- •Указатель на указатель
- •Указатели и приведение типов
- •Null pointer - нулевой указатель
- •Пример работы с указателями
- •Тема №8 Указатели и массивы
- •Многомерные массивы и указатели на многомерные массивы
- •Определение макросов
- •Тема №9 Тернарный оператор и оператор запятая
- •Оператор запятая.
- •Сегментация приложения на си
- •Тема №10 Динамическое выделение памяти
- •Освобождение памяти с помощью free
- •Работа с двумерными и многомерными массивами
- •Тема №11 Параметры командной строки
- •Функции
- •Параметры и аргументы
- •Передача аргументов По значению
- •По указателю (ссылке)
- •Передача массива в качестве аргумента
- •Тема №12 Битовые операции
- •Операции побитового сдвига
- •Примеры
- •Вопросы к экзамену по дисциплине «Основы программирования»
Тема №3 Оператор присваивания
Когда мы работаем с переменными, необходимо изменять их значение. Это делается с помощью оператора присваивания «=» .
#include<conio.h>
#include<stdio.h>
int main() {
signed long long a, b, c;
a = 1234567890123456789LL;
b = -1234567890123456789LL;
c = 123;
printf("%lld\n", a);
printf("%lld\n", b);
printf("%lld\n", c);
getch();
}
Оператор присваивания имеет особенность – он возвращает правое значение. Это значит, что можно использовать несколько операторов присваивания подряд, по цепочке.
#include<conio.h>
#include<stdio.h>
int main() {
unsigned a, b, c;
a = b = c = 10;
printf("%u = %u = %u = 10", a, b, c);
getch();
}
В этом примере переменной c присваивается значение 10, после чего оператор присваивания возвращает значение 10, которое используется следующим оператором, и присваивает значение 10 переменной b, после чего возвращает значение 10, которое используется следующим оператором. Это свойство - возвращать значение - часто используется. Например, при выделении памяти мы можем узнать, была ли действительно выделена память.
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
int main() {
int *a = NULL;
printf("Try to allocate memory\n");
if (a = (int*)malloc(1024*1024*1024 * sizeof(int))) {
printf("Memory was allocated");
} else {
printf("Error: can't allocate memory");
}
getch();
free(a);
}
Здесь одновременно выделяется память и проверяется, что было возвращено при попытке получить память. Этот же пример может быть записан и так
a = (int*)malloc(1024*1024*1024 * sizeof(int));
if (a) {
printf("Memory was allocated");
} else {
printf("Error: can't allocate memory");
}
(вам этот пример кажется непонятным, здесь важно для вас только использование оператора = ).
rvalue и lvalue
Любая переменная связана с адресом в памяти и хранит некоторое значение. Выражение типа
int i;
i = 20;
говорит о том, что мы заносим в область памяти, на которую указывает переменная i значение 20. Выражение
20 += 3;
не имеет смысла, поскольку 20 - это литерал, значение, которое не связано с областью памяти.
Для обозначения объектов, которым может быть присвоено значение, используется понятие lvalue (буквально, то, что может стоять слева от оператора присваивания). Для обозначения объектов, которые имеют только значения, используют выражение rvalue (то, что стоит справа от оператора присваивания). lvalues в свою очередь делят на modifiable lvalues, которые могут быть изменены, и non-modifiable lvalues, которые связаны с областью памяти, но не могут быть изменены, например, константы. В том случае, если lvalue стоит справа от оператора присваивания, например:
int i, j;
j = 20;
i = j;
то происходит lvalue-to-rvalue convertion, преобразование lvalue к rvalue.
К rvalue относятся результаты арифметических выражений, преобразование не к ссылочным типам, результат постфиксных операций ++ и --, литералы за исключением строк.
К lvalue относятся переменные, выражения ссылочных типов, результат операции разыменования *, строковые литералы, результат префиксных операций ++ и -- над ссылочными типами.
Имена функций и массивов, также объявленные как немодифицируемые объекты, являются non-modifiable lvalues.
