сновные понятия языка
Программа, написанная на языке Си, состоит из операторов. Каждый оператор вызывает выполнение некоторых действий на соответствующем шаге выполнения программы.
При написании операторов применяются латинские прописные и строчные буквы, цифры и специальные знаки. К таким знакам, например, относятся: точка (.), запятая (,), двоеточие (:), точка с запятой (;) и др. Совокупность символов, используемых в языке, называется алфавитом языка.
В персональном компьютере символы хранятся в виде кодов. Соответствие между каждым символом и его кодом задается специальной кодовой таблицей. На нее разработан стандарт ASCII, поэтому коды символов называют ASCII-кодами.
Различают видимые и управляющие символы. Первые могут быть отображены на экране дисплея либо отпечатаны на принтере. Вторые вызывают определенные действия в машине, например: звуковой сигнал - код 710, возврат курсора на один шаг - код 810, горизонтальная табуляция - код 910, перевод курсора на новую строку - код 1010, перемещение курсора в начало строки - код 1310 и т.д. Такие управляющие символы имеют десятичные номера 0 - 31, 127.
Для представления каждого символа в персональном компьютере используется один байт, поэтому общее число символов равно 28 = 256. Кодовая таблица, которая устанавливает соответствие между символом и его кодом, имеет 256 строк вида:
код_символа_в_заданной_системе_счисления - символ.
Первая половина кодовой таблицы является стандартной, а вторая используется для представления символов национальных алфавитов, псевдографических элементов и т.д.
Важным понятием языка является идентификатор, который используется в качестве имени объекта (функции, переменной, константы и др.). Идентификаторы должны выбираться с учетом следующих правил:
- Они должны начинаться с буквы латинского алфавита (а,...,z, А,...,Z) или с символа подчеркивания (_).
- В них могут использоваться буквы латинского алфавита, символ подчеркивания и цифры (0,...,9). Использование других символов в идентификаторах запрещено.
- В языке Си буквы нижнего регистра (а,...,z), применяемые в идентификаторах, отличаются от букв верхнего регистра (А,...,Z). Это означает, что следующие идентификаторы считаются разными: name, NaMe, NAME и т.д.
- Идентификаторы могут иметь любую длину, но воспринимается и используется для различения объектов (функций, переменных, констант и т.д.) только часть символов. Их число меняется для разных систем программирования, но в соответствии со стандартом ANSI C не превышает 32 (в Си++ это ограничение снято). Если длина идентификатора установлена равной 5, то имена count и counter будут идентичны, поскольку у них совпадают первые пять символов.
- Идентификаторы для новых объектов не должны совпадать с ключевыми словами языка и именами стандартных функций из
2)Структура программы:
Программа на языке Си состоит из одной или более подпрограмм, называемых функциями.
Язык Си является блочно-структурированным. Каждый блок заключается в фигурные скобки {}.
Основным блоком в программе консольного приложения на языке Си является главная функция, имеющая имя main().
Каждое действие в языке Си заканчивается символом "точка с запятой" -;. В качестве действия может выступать вызов функции или осуществление некоторых операций.
Имя функции — это коллективное имя группы описаний и операторов,
заключенных в блок (фигурные скобки). За именем функции в круглых скобках указываются параметры функции.
Комментарии в языке Си
В языке Си для комментариев используются символы
/* - начало комментария;
*/ - конец комментария.
Вся последовательность, заключенная между этими символами, является комментарием.
Это удобно для написания многострочных комментариев:
int a; /* целая
переменная */
Многострочные комментарии также удобно использовать при отладке для сокрытия от выполнения части кода.
В дополнение к этому, для написания коротких комментариев могут использоваться символы //. При этом комментарием является все, что расположено после символов // и до конца строки:
float b; // вещественная переменная
Главная функция
При выполнении консольного приложения, написанного на языке Си, операционная система компьютера передаёт управление функции с именем main(). Функцию main() нельзя вызывать из других функций программы, она является управляющей.
Следующие за именем функции круглые скобки предназначены для указания параметров (аргументов), которые передаются в функцию при обращении к ней. В данном случае операционная система не передаёт в функцию main() никаких аргументов, поэтому список аргументов в круглых скобках пустой.
Главную функцию можно записать по-разному:
int main()
void main().
Перед именем функции указывается тип возвращаемого значения. При обращении к главной функции значение возвращается операционной системе. Последняя запись не будет возвращать значения. Однако void main() - не совсем корректная запись, так как сообщает компилятору, что функция main() не возвращает никакого значения.
При этом запись int main() сообщает компилятору о возвращении целочисленного значения, которое необходимо операционной системе и сообщает ей о том, что программа завершилась корректно. Если же это значение не возвращено, то операционная система понимает, что программа завершилась в аварийном режиме.
Для возврата целочисленного значения перед завершением функции добавляется строка
return 0; // вещественная переменная
В фигурные скобки заключены описания и операторы.
В общем случае программа может содержать несколько функций. Каждая функция имеет список передаваемых в нее параметров, указанный в круглых скобках, и набор операций, заключенных в блок, ограниченный фигурными скобками.
Пример: Вывод на экран сообщения "Hello, world!".
#include <stdio.h> // Подключение библиотеки ввода-вывода
int main() // Главная функция
{
printf("Hello, world!"); // Вывод сообщения
getchar(); // Задержка окна консоли
return 0;
}
Результат работы программы:
Результат работы Hello world
Теперь попробуем написать текст на русском языке.
#include <stdio.h>
int main()
{
printf("Здравствуй, мир!");
getchar();
return 0;
}
Результат работы программы:
Результат работы Здравствуй, мир!
Проблема русского языка в консольных приложениях заключается в том, что консоль и редактор кода Microsoft Visual Studio поддерживают разные кодовые страницы. Для того, чтобы увидеть русские символы в консоли необходимо поменять кодовую страницу в консоли, чтобы она соответствовала кодовой странице редактора (1251). С этой целью вызывается функция system("chcp 1251") с соответствующей командной строкой. Прототип функции system() содержится в библиотеке <stdlib.h>.
При этом текст программы будет выглядеть следующим образом:
#include <stdio.h>
#include <stdlib.h>
int main()
{
system("chcp 1251"); // Текущая кодовая страница 1251
system("cls"); // Очистка консоли
printf("Здравствуй, мир!"); // Вывод сообщения
getchar();
return 0;
}
Результат работы программы:
Результат работы Здравствуй, мир!
3)допустимые символы
По таблице ASCII символы с номерами (кодами) от 0 до 127 жестко определены. В этом диапазоне номера присвоены символам цифр, латинским (английским) маленьким и большим буквам, а также используемым в языке иным символам ('!', '%', '~' и т.п.). Здесь же заданы коды для различных управляющих символов, которые никак не экране не отображаются, а что-то делают (например, создают новою строку или отступ, подают звуковой сигнал и др.). Расширенная таблица ASCII кодирует символы национальных алфавитов (например, русского языка) числами лежащими в диапазоне от 128 до 255. Символы цифр от '0' до '9' имеют последовательные коды от 48 до 57. Этот факт обычно используют, при "переводе" символов цифр в числа. Если мы знаем, что у '0' код 48, а был задан символ '5', имеющий код 53, то если вычесть из 53 число 48, получим число 5. Знание кодов символов цифр позволяет программировать извлечение чисел из текста. Английские большие буквы (прописные) имеют последовательные коды от 65 (A) до 90 (Z), маленькие (строчные) — от 97 до 122.
Специальные символы в программном коде обозначаются двумя символами, т.к. одним их обычно обозначить невозможно. Но по сути представляют собой один символ. Например, букву 'a' можно обозначить одним символом, а как обозначить символ создания новой строки, если ему не соответствует ни один знак? Приходится выкручиваться и представлять такой неординарный символ комбинацией пары других символов: '\n'. Помните при этом, что на самом деле это всего лишь один символ. Ниже перечислен ряд управляющих символов (не все) и то, что они делают: '\n' — создание новой строки и переход на нее; '\t' — табуляция (отступ в несколько пробелов); '\r' — возврат каретки (перевод курсора в первую позицию текущей строки); '\b' — возврат курсора на один символ назад с удалением этого символа. В программном коде, помимо управляющих, специальными символами могут записываться некоторые вполне обычные символы, такие как кавычки, одиночные кавычки, обратная косая черта и др. Некоторые из этих символов можно задать одним символом в одиночных кавычках. Но многие из них невозможно вставить просто так внутрь строки, т.к. они что-то значат с точки зрения синтаксиса языка. Например, обратная косая черта в строке сообщает, что начинается обозначение специального символа, двойная кавычка обозначает начало или конец строки. Поэтому такие символы также обозначаются парной комбинацией других символов: '\\' — обратный косая черта; '\'' — одиночная кавычка; '\"' — двойная кавычка (не в строке можно просто '"'); '\0' — пустота, символ с кодом 0 по таблице ASCII.
4)Синтаксис:
Основные элементы программирования
Ключевые слова и синтаксис языка
Большинство программ предназначено для решения прикладных задач. В программах это выполняется путем обработки информации. Для решения задачи программа должна выполнить следующие действия:
- ввести информацию в программу;
- запомнить введенную информацию;
- задать команды для обработки информации;
- передать информацию из программы пользователю,
Команды в программе должны быть организованы таким образом, чтобы:
- некоторые из них выполнялись только при истинном значении заданного условия (или набора условий);
- другие команды выполнялись многократно;
- отдельные команды разделены на части, и выполняемые из разных участков программы.
Итак, из выше описанных действий можно выделить семь основных элементов программирования: ввод, типы данных, операции, вывод, условное выполнение, циклы и подпрограммы (функции для языка Си).
В большинстве языков программирования имеются все указанные элементы. Во многих языках, включая Си, имеются и другие средства. Однако, наиболее быстрый способ изучения нового языка основан на понимании того, как в данном языке реализованы перечисленные основные элементы программирования.
Есть шесть классов лексем: идентификаторы, ключевые слова, константы, строки, операторы и разделители.
Идентификаторы: последовательность букв и цифр произвольной длины. Первый символ-буква, например, NAME1, name 1, Name 1, name_1…
Ключевые слова: Они зарезервированы для языка и не могут использоваться другим образом. Список ключевых слов языка представлен в табл.1.1
Таблица 1.1
Ключевые слова языка
Типы данных | Операторы | |||||
Eng | Рус | Eng | Рус | |||
Сhar | Символ | Asm | ||||
Class | Класс | Break | Прерывание | |||
Double | Двойной | Case | Выбор | |||
Enum | Перечень | Continue | Продолжение | |||
Float | Плавающий | Default | По молчанию | |||
Продолжение табл. 1.1 | ||||||
Int | Целый | Delete | Удалять | |||
Long | Длинное целое | Do | Делать | |||
Short | Короткое целое | Else | Иначе | |||
Struct | Структура | For | Для | |||
Union | Объединение | Go to | Идти (переход) | |||
Unsigned | Беззнаковый | If | Если | |||
Void | Пустой | New | Новый | |||
Return | Возврат | Switch | Прерывать | |||
Extern | Внешняя | Inline | В линию | |||
Register | Регистр | Const | Постоянный | |||
Overload | Переопределение | Typedef | Тип переменной | |||
Auto | Автоматически | While | Пока | |||
Static | Статический | Public | Открытый | |||
Константы: целые, символьные, с плавающей точкой, строки.
Целая – последовательность цифр. Константа - восьмеричная, если начинается с 0, в противном случае – десятичная. Цифры 8 и 9 не являются восьмеричными цифрами. Последовательность цифр 0X или 0x воспринимается как шестнадцатеричное целое число. В шестнадцатеричные цифры входят буквы от A до F(f), имеющие значения 10 – 15.
Примеры: 0x53=83; 0xF=15; 0xA = 10.
Константа, значение которой превышает наибольшее машинное целое со знаком, считается длинной (long), в остальных случаях константы считаются целыми (int).
Длинные константы: десятичная, восьмеричная или шестнадцатеричная константа, за которой непосредственно стоит буква L (l), считается длинной константой.
Примеры: 12l - десятичная,
0123L - восьмеричная,
0xaaaal - шестнадцатеричная.
Перевод чисел из одной системы счисления в другую приведен в табл. 1.2.
Для представления шестнадцатеричного числа в двоичном коде надо заменить двоичной записью каждую цифру этого числа. Например, числа 0xAB01 и 0x53, представленные в двоичном виде, переводятся в десятичные по известной формуле перевода [1].
Таблица 1.2
Таблица перевода чисел
Десятичное число | Шестнадцате-ричное число | Двоичная запись числа | Восьмерич-ная запись числа | Шестнадцате-рич-ная запись числа |
0x0 | ||||
0x1 | ||||
0x2 | ||||
0x3 | ||||
0x4 | ||||
0x5 | ||||
0x6 | ||||
0x7 | ||||
0x8 | ||||
0x9 | ||||
A | 0xA | |||
B | 0xB | |||
C | 0xC | |||
D | 0xD | |||
E | 0xE | |||
F | 0xF |
A B 0 1
1010 1011 0000 0001 –> 1010101100000001=
1 * 215 + 0 * 214 + 1 * 213 + 0 * 212 + 1 * 211 + 0 * 210 + 1 * 29+ 1 * 28 + … 1 * 20 = 43777;
0x53 = 01010011 = 0 * 27 + 1 * 26 + 0 * 25 + 1 * 24 + 0 * 23 + 0 * 22 + 1* 21 + 1 * 20 = 83;
Символьная константа состоит из символа, заключенного в апострофы (например, ‘x’). Значением символьной константы считается численное значение константы в машинном наборе (алфавите). Символьные константы считаются данными типа char. Использование неграфических символов, однозначная кавычка ‘ и обратная косая \ производится в соответствии с табл.1.3
Таблица 1.3
Использование специальных символов
Название | Обозначение |
Символ новой строки | \n |
Горизонтальная табуляция | \t |
Вертикальная табуляция | \v |
Возврат на шаг | \b |
Возврат каретки | \v |
Продолжение табл. 1.3 | |
Название | Обозначение |
Перевод формата | \f |
Обратная кавычка | \\ |
Апостроф | \’ |
Набор битов 0ddd | \ddd |
Набор битов 0xddd | \xddd |
Пустой символ | \0 |
Последовательность \ddd состоит из обратной косой, за которой следуют 1, 2, 3 - восьмеричные цифры, задающие значение требуемого символа. \xddd та же последовательность, где 1, 2, 3 – шестнадцатеричные цифры.
Константы с плавающей точкой (с Е) используются для представления больших чисел в компактной форме.
Примеры: 345. = 345
3.14159
2.1Е5 = 210000
.123Е3 = 123
4037е-5 =.04037
Строки. Строка – это последовательность символов, заключенная в двойные кавычки “…”. Строка имеет тип char, а класс памяти static. Она инициализируется заданными символами. Все строки, даже если они занесены одинаково, различны. Компилятор располагает в конце каждой строки нулевой (пустой) байт \O с тем, чтобы сканирующая строку программа могла найти ее конец. В строке перед символом двойной кавычки должна стоять обязательно \. Кроме того, могут использоваться те же обозначения, что были описаны для символьных констант.
Примеры:
“Это строковая константа”
“A”
“Это одна \*\
строка”
Имена и типы. Имя обозначает объект, функцию, тип, значение или метку. Имя может использоваться только внутри части текста программы, называемой его областью видимости. Имя имеет тип, определяющий его использование.
Объект – это область памяти. Объект имеет класс памяти, определяющий время его жизни.
Область видимости. Существует четыре ее вида: локальная, файл, программа и класс.
Локальная область- имя, описанное в блоке, локально в этом блоке и может использоваться только в нем. Исключения составляют метки, которые могут использоваться в любом месте функции, в которой они описаны.
Файл – имя, описанное вне любого блока. Программа – имя, описанное в файле, может использоваться в любом другом файле.
Класс - имя члена класса, локально для его класса и может использоваться только в функции-члене этого класса.
Вопрос 2:Объекты в C++.Массивы объектов. Привести пример
1)Объекты в C++:
Объект – это структурированная переменная, содержащая всю информацию о некотором физическом предмете или реализуемом в программе понятии.
ассивы объектов
Можно создавать массивы объектов точно так же, как создаются массивы данных других типов. Например, следующая программа создает класс display, содержащий информацию о различных адаптерах дисплеев, которые могут быть подключены к PC. В частности, он содержит число цветов, которые могут быть получены, и тип видеоадаптера. В функции main() создается массив из трех объектов display. Доступ к элементам этого массива осуществляется с помощью обычной процедуры с использованием индексов.
// пример массива объектов
#include <iostream.h>
enum disp_type {mono, cga, ega, vga};
class display {
int colors; // число цветов enum
disp_type dt; // тип дисплея
public:
void set_colors(int num) {colors = num; }
int get_colors() {return colors;}
void set_type (enum disp_type t) {dt = t; }
enum disp_type get_type() {return dt; }
};
char names [4 ] [5] = {
"mono",
"cga",
"ega",
"vga"
};
int main()
{
display monitors [3];
register int i;
monitors[0].set_type(mono);
monitors[0].set_colors(1);
monitors[1].set_type(cga);
monitors [1].set_colors(4);
monitors[2].set_type(ega);
monitors [2].set_colors(16);
for (1=0; i<3; i++) {
cout << names[monitors[i].get_type()] << " ";
cout << "has " << monitors[i].get_colors();
cout << " colors" << "\n";
}
return 0;
}
Эта программа выводит на экран следующий текст:
mono has 1 colors
cga has 4 colors
ega has 16 colors
Хотя это и не относится специально к массивам объектов, обратим внимание, каким образом двумерный символьный массив names использован для преобразования перечисляемых значений к их строковым эквивалентам. Для всех переменных перечисляемого типа, не содержащих явной инициализации, первая константа имеет значение 0, вторая 1 и т. д. Поэтому возвращаемое функцией get_type() значение может быть использовано для индексации массива names, что позволяет вывести подходящее имя.
Многомерные массивы объектов индексируются в точности так же, как и массивы любых других типов данных.
Билет 2
Вопрос 1:Типы данных C.Примеры
В языке различают понятия "тип данных" и "модификатор типа". Тип данных - это, например, целый, а модификатор - со знаком или без знака. Целое со знаком будет иметь как положительные, так и отрицательные значения, а целое без знака - только положительные значения. В языке Си можно выделить пять базовых типов, которые задаются следующими ключевыми словами:
- char - символьный;
- int - целый;
- float - вещественный;
- double - вещественный двойной точности;
- void - не имеющий значения.
Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям и способ реализации хранения значений и выполнения операций.
Процесс проверки и накладывания ограничений на типы используемых данных называется контролем типов или типизацией программных данных. Различают следующие виды типизации:
· Статическая типизация — контроль типов осуществляется при компиляции.
· Динамическая типизация — контроль типов осуществляется во время выполнения.
Язык Си поддерживает статическую типизацию, и типы всех используемых в программе данных должны быть указаны перед ее компиляцией.
Различают простые, составные и прочие типы данных.
Простые данные
Простые данные можно разделить на
· целочисленные,
· вещественные,
· символьные
· логические.
Составные (сложные) данные
· Массив - индексированный набор элементов одного типа.
· Строковый тип - массив, хранящий строку символов.
· Структура - набор различных элементов (полей записи), хранимый как единое целое и предусматривающий доступ к отдельным полям структуры.
Другие типы данных
· Указатель - хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — указатель на переменную.
Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).
Идентификатор — это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a - z, A - Z, цифры 0 - 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.
Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.
Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.
Верно | Неверно |
int a = 2, b; b = a+3; | Int a=2; // правильно int INT a=2; |
int a = 2, b; b = A + 3; // идентификатор А не объявлен | |
int a = 2; b = a + 3; // идентификатор b не объявлен |
Целочисленные данные могут быть представлены в знаковой и беззнаковой форме.
Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2n-1, где n-количество занимаемых битов.
Знаковые целые числа представляются в диапазоне -2n-1...+2n-1-1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).
Основные типы и размеры целочисленных данных:
Количество бит | Беззнаковый тип | Знаковый тип |
unsigned char 0...255 | char -128...127 | |
unsigned short 0...65535 | short -32768...32767 | |
unsigned int | int | |
unsigned long int | long int |
Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме. Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как
12345,678 = 1,2345678·104
Число 0,009876 в нормированной форме можно представить как
0,009876 = 9,876·10-3
В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.
Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.
В общем случае вещественное число в разрядной сетке вычислительной машины можно представить в виде 4 полей.
знак - бит, определяющий знак вещественного числа (0 для положительных чисел, 1 - для отрицательных).
степень - определяет степень 2, на которую требуется умножить число в нормированной форме. Поскольку степень 2 для числа в нормированной форме может быть как положительной, так и отрицательной, нулевой степени 2 в представлении вещественного числа соответствует величина сдвига, которая определяется как
N-1
где n - количество разрядов, отводимых для представления степени числа.
целое - бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1.
мантисса - значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.
Различают три основных типа представления вещественных чисел в языке Си:
Тип | Обозна- чение в Си | Кол-во бит | Биты степени | Мантисса | Сдвиг |
простое | float | 30...23 | 22...0 | ||
двойной точности | double | 62...52 | 51...0 | ||
двойной расширен- ной точности | long double | 78...64 | 62...0 |
Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде:
Пример: представить число -178,125 в 32-разрядной сетке (тип float).
Для представления числа в двоичной системе счисления преобразуем отдельно целую и дробную части:
17810 = 101100102.
0,12510 = 0,0012.Тогда 178,12510 = 10110010,0012=1,0110010001·2111
(для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево).
Для определения степени числа применяем сдвиг:
0111111+00000111 = 10000110.
Таким образом, число -178,125 представится в разрядной сетке как
Символьный тип хранит код символа и используется для отображения символов в различных кодировках. Символьные данные задаются в кодах и по сути представляют собой целочисленные значения. Для хранения кодов символов в языке Си используется тип char.
Подробнее о кодировке символов
Логический тип имеет два значения: истина и ложь - применяется в логических операциях, используется при алгоритмических проверках условий и в циклах.
В программе должно быть дано объявление всех используемых данных с указанием их имени и типа. Описание данных должно предшествовать их использованию в программе.
Пример объявления объектов
int n; // Переменная n целого типа
double a; // Переменная a вещественного типа двойной точности
Вопрос 2:Ссылки в C++.Ограничение на ссылки.
В С++ введен новый тип данных – ссылка. Ссылка позволяет определять альтернативное имя переменной.
Формат объявления ссылки:
тип &идентификатор = идентификатор2;
Такое объявление назначает переменной с именем идентификатор2 второе имя идентификатор.
сылка при объявлении всегда должна быть проинициализирована!
int a,b;
int &alt=a; // alt — другое имя переменной а (ссылка на a)
alt = b; // a=b;
alt++; // a++;
Если объявлен указатель
int *ptr = &a;
то истины следующие выражения:
*ptr == alt; // истина, сравниваются значения
ptr == &alt; // истина, сравниваются адреса
Ссылку можно рассматривать как постоянный указатель, который всегда разыменован, для него не надо выполнять операцию косвенной адресации *.
Ссылка не создает копии объекта, а является лишь другим именем объекта.
Возможно инициализировать ссылка на константу:
const char &new_line='\n';
В этом случае компилятор создает некоторую временную переменную temp и ссылку на нее:
char temp = '\n';
const char &new_line = temp;
Основной причиной введения в С++ нового типа данных – ссылки явилась необходимость передачи параметров в функцию через ссылку и получение возвращаемого значения в виде ссылки. Это используется в двух случаях:
· для передачи в функцию больших структур, чтобы избежать копирования аргументов в стек;
· для передачи функции аргументов, которые должны быть изменены самой функцией.
В обоих случаях можно использовать указатели, но это влечет за собой дополнительные расходы:
· во-первых, в функции для данного параметра надо выполнять операцию разыменования,
· во-вторых, при вызове функции надо передавать не саму переменную, а ее адрес.
Пример. Функция, меняющая местами два целых числа:
Без использования ссылок | С использованием ссылок |
void swap (int *a, int *b) { int temp = *a; *a = *b; *b = temp; } | void swap (int &a, int &b) { int temp = a; a = b; b = temp; } |
Вызов: int x = 10; int y = 5; swap(&x, &y); | Вызов: int x = 10; int y = 5; swap(x, y); |
При использовании ссылок в качестве параметров, наряду с указанными преимуществами есть два существенных недостатка:
· Фактический аргумент, переданный в функцию по ссылке, может быть изменен функцией без ведома вызывающей программы. Чтобы этого избежать, параметры, которые не должны изменяться, должны определяться с ключевым словом const. При попытке изменить параметр, объявленный как const будет сообщение об ошибке.
· Если при вызове функции происходит несоответствие типов фактических и формальных параметров, С++ выполняет преобразование типа, но для ссылок преобразование типа выполняется через создание промежуточной переменной.
void swap (int &, int &);
int main() {
int x=10;
unsigned int y;
y=5;
swap(x, y);
...
}
Компилятор будет выполнять следующие преобразования:
int temp = (int)y;
int &t = temp;
swap(x, t);
В результате swap() поменяет местами значения x и temp. После выхода из функции переменная temp удалится, а y останется неизменной.
В С++ функции могут не только принимать ссылку в качестве аргумента, но и возвращать ссылку на переменную. Выражение вызова такой функции может появиться в любой части операции присваивания. При этом необходимо учитывать, что
· если возвращаемое значение — указатель, то нельзя оператором return; возвращать адрес локальной переменной.
· если возвращаемое значение — ссылка, то нельзя оператором return возвращать локальную переменную. (Так как после выхода из функции переменная не существует, и мы получим повисшую ссылку).
Чаще всего потребность в ссылках возникает при перегрузке операций.
Билет 3:
Вопрос 1:Формативный ввод/вывод в языке C.Примеры
Основной задачей программирования является обработка информации,
поэтому любой язык программирования имеет средства для ввода и вывода информации. В языке Си нет операторов ввода-вывода.
Ввод и вывод информации осуществляется через функции стандартной библиотеки. Прототипы рассматриваемых функций находятся в файле stdio.h. Эта библиотека содержит функции
· printf() - для вывода информации
· scanf() - для ввода информации.
Вывод информации
Функция printf() предназначена для форматированного вывода. Она переводит данные в символьное представление и выводит полученные изображения символов на экран. При этом у программиста имеется возможность форматировать данные, то есть влиять на их представление
на экране.
Общая форма записи функции printf():
printf("СтрокаФорматов", объект1, объект2,..., объектn);
СтрокаФорматов состоит из следующих элементов:
· управляющих символов;
· текста, представленного для непосредственного вывода;
· форматов, предназначенных для вывода значений переменных различных типов.
Объекты могут отсутствовать.
Управляющие символы не выводятся на экран, а управляют расположением выводимых символов. Отличительной чертой управляющего символа является наличие обратного слэша '\' перед ним.
Основные управляющие символы:
· '\n' — перевод строки;
· '\t' — горизонтальная табуляция;
· '\v' — вертикальная табуляция;
· '\b' — возврат на символ;
· '\r' — возврат на начало строки;
· '\a' — звуковой сигнал.
Форматы нужны для того, чтобы указывать вид, в котором информация будет выведена на экран. Отличительной чертой формата является наличие символа процент '%' перед ним:
· %d — целое число типа int со знаком в десятичной системе счисления;
· %u — целое число типа unsigned int;
· %x — целое число типа int со знаком в шестнадцатеричной системе счисления;
· %o — целое число типа int со знаком в восьмеричной системе счисления;
· %hd — целое число типа short со знаком в десятичной системе счисления;
· %hu — целое число типа unsigned short;
· %hx — целое число типа short со знаком в шестнадцатеричной системе счисления;
· %ld — целое число типа long int со знаком в десятичной системе счисления;
· %lu — целое число типа unsigned long int;
· %lx — целое число типа long int со знаком в шестнадцатеричной системе счисления;
· %f — вещественный формат (числа с плавающей точкой типа float);
· %lf — вещественный формат двойной точности (числа с плавающей точкой типа double);
· %e — вещественный формат в экспоненциальной форме (числа с плавающей точкой типа float в экспоненциальной форме);
· %c — символьный формат;
· %s — строковый формат.
Пример
int a=5;
float x = 2.78;
printf("\n Значение переменной a=%d", a);
printf("\n Значение переменной x=%f", x);
Результат работы программы
Значение переменной a=5
Значение переменной x=2.780000
При указании формата можно явным образом указать общее количество знакомест и количество знакомест, занимаемых дробной частью.
Пример
float y=1.2345;
printf("\n Значение переменной y=%10.5f\n", y);
Результат работы программы
Значение переменной y= 1.23450
В приведенном примере 10 — общее количество знакомест под значение переменной; 5 — количество позиций после десятичной точки. В указанном примере количество знакомест в выводимом числе меньше 10, поэтому свободные знакоместа слева от числа заполняются пробелами. Такой способ форматирования часто используется для построения таблиц.
Ввод информации
Функция форматированного ввода данных с клавиатуры scanf() выполняет чтение данных, вводимых с клавиатуры, преобразует их во внутренний формат и передает вызывающей функции. При этом программист задает правила интерпретации входных данных с помощью спецификаций форматной строки.
Общая форма записи функции scanf()
scanf ("CтрокаФорматов", адрес1, адрес2,...);
Строка форматов аналогична функции printf(). Для формирования адреса переменной используется символ амперсанд '&':
адрес = &объект
Строка форматов и список аргументов для функции обязательны.
Пример
#include <stdio.h>
#include <stdlib.h>
int main()
{
float y;
system("chcp 1251");
system("cls");
printf("Введите y: ");
scanf("%f",&y); // Ввод значения переменной y
printf("Значение переменной y=%f",y);
getchar(); getchar();
return 0;
}
Результат работы программы:
Вопрос 2:Указатели на объекты в C++.Указатель this
1)Указатели на объекты в C++
В языке С можно получить доступ к структуре непосредственно или с использованием указателей на эту структуру. Аналогичным образом в С++ можно ссылаться на объект непосредственно, или используя указатель на этот объект. Указатели на объекты являются одним из важнейших понятий С++.
Для доступа к членам объекта через сам объект используется оператор «точка» (.). Если же используется указатель на объект, тогда необходимо использовать оператор «стрелка» (—>). Использование операторов «точка» и «стрелка» аналогично их использованию для структур и объединений.
Указатель на объект объявляется с использованием того же синтаксиса, что и указатели на данные других типов. В следующей программе создается простой класс с именем P_example и определяется объект этого класса ob, а также указатель р на объект P_example. Ниже проиллюстрировано, как получить доступ к объекту ob непосредственно и опосредованно с использованием указателя:
// простой пример использования указателя на объект
#include <iostream.h>
class P_example {
int num;
public:
void set_num(int val) {num = val; }
void show_num();
};
void P_example::show_num()
{
cout << num << " \n";
}
int main()
{
P_example ob, *p; // объявление объекта и указателя на него
ob.set_num(1); // прямой доступ к ob
ob.show_num();
р = &ob; // присвоение р адреса ob
p->show_num(); // доступ к ob с помощью указателя
return 0;
}
Обратим внимание, что адрес объекта ob получен с использованием оператора взятия адреса & точно так же, как берется адрес переменной любого типа.
Инкремент или декремент указателя изменяет его таким образом, что он всегда указывает на следующий элемент базового типа. То же самое справедливо и для объектов. Следующий пример модифицирует предыдущую программу, в результате чего ob становится массивом из двух элементов типа P_example. Обратим внимание на инкремент и декремент указателя р, с помощью которого осуществляется доступ к элементам массива:
// увеличение указателя на объект
#include <iostream.h>
class P_example {
int num;
public:
void set_num(int val) {num = val;}
void show_num();
};
void P_example::show_num()
{
cout << num << "\n";
}
int main()
{
P_example ob[2], *p;
ob[0].set_num(10); // прямой доступ к объекту
ob[1].set_num(20);
p = &ob[0]; // получение указателя на первый элемент
p->show_num(); // вывод значения ob[0] с помощью указателя
р++; // переход к следующему объекту
p->show_num(); // вывод значения ob[1] с помощью указателя
р--; // переход к предыдущему объекту
p->show_num(); // вывод значения оb [0]
return 0;
}
Программа выводит на экран числа 10, 20, 10.
2)Указатели this
Всякий раз, когда вызывается функция-член, автоматически передается указатель на объект, вызывающий данную функцию. Можно получить доступ к этому указателю, используя this. Указатель this служит неявным параметром всех функций-членов. (Функции-друзья не имеют указателя this.) Например, в операторе:
оb.f();
функции f() автоматически передается указатель this, указывающий на объект ob.
Как известно, функции-члены имеют непосредственный доступ к данным класса. Например, если задан следующий класс:
class cl {
int i;
//...
};
то функция-член может присвоить переменной i значение 10, используя следующую инструкцию:
i = 10;
Фактически эта инструкция является сокращенной записью следующий инструкции:
this->i = 10;
Для того, чтобы увидеть, как работает указатель this, рассмотрим следующую короткую программу:
#include <iostream.h>
class cl {
int i;
public:
void load_i(int val) { this->i = val; } // то же самое, что и i = val
int get_i() { return this->i; } // то же самое, что и return i
};
int main ()
{
cl o;
o.load_i(100);
cout << o.get_i();
return 0;
}
Эта программа выводит на экран число 100.
Билет 4
Вопрос 1:Типы данных C.Примеры
В языке различают понятия "тип данных" и "модификатор типа". Тип данных - это, например, целый, а модификатор - со знаком или без знака. Целое со знаком будет иметь как положительные, так и отрицательные значения, а целое без знака - только положительные значения. В языке Си можно выделить пять базовых типов, которые задаются следующими ключевыми словами:
- char - символьный;
- int - целый;
- float - вещественный;
- double - вещественный двойной точности;
- void - не имеющий значения.
Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям и способ реализации хранения значений и выполнения операций.
Процесс проверки и накладывания ограничений на типы используемых данных называется контролем типов или типизацией программных данных. Различают следующие виды типизации:
· Статическая типизация — контроль типов осуществляется при компиляции.
· Динамическая типизация — контроль типов осуществляется во время выполнения.
Язык Си поддерживает статическую типизацию, и типы всех используемых в программе данных должны быть указаны перед ее компиляцией.
Различают простые, составные и прочие типы данных.
Простые данные
Простые данные можно разделить на
· целочисленные,
· вещественные,
· символьные
· логические.
Составные (сложные) данные
· Массив - индексированный набор элементов одного типа.
· Строковый тип - массив, хранящий строку символов.
· Структура - набор различных элементов (полей записи), хранимый как единое целое и предусматривающий доступ к отдельным полям структуры.
Другие типы данных
· Указатель - хранит адрес в памяти компьютера, указывающий на какую-либо информацию, как правило — указатель на переменную.
Программа, написанная на языке Си, оперирует с данными различных типов. Все данные имеют имя и тип. Обращение к данным в программе осуществляется по их именам (идентификаторам).
Идентификатор — это последовательность, содержащая не более 32 символов, среди которых могут быть любые буквы латинского алфавита a - z, A - Z, цифры 0 - 9 и знак подчеркивания (_). Первый символ идентификатора не должен быть цифрой.
Несмотря на то, что допускается имя, имеющее до 32 символов, определяющее значение имеют только первые 8 символов. Помимо имени, все данные имеют тип. Указание типа необходимо для того, чтобы было известно, сколько места в оперативной памяти будет занимать данный объект.
Компилятор языка Си придерживается строгого соответствия прописных и строчных букв в именах идентификаторов и лексем.
Верно | Неверно |
int a = 2, b; b = a+3; | Int a=2; // правильно int INT a=2; |
int a = 2, b; b = A + 3; // идентификатор А не объявлен | |
int a = 2; b = a + 3; // идентификатор b не объявлен |
Целочисленные данные могут быть представлены в знаковой и беззнаковой форме.
Беззнаковые целые числа представляются в виде последовательности битов в диапазоне от 0 до 2n-1, где n-количество занимаемых битов.
Знаковые целые числа представляются в диапазоне -2n-1...+2n-1-1. При этом старший бит данного отводится под знак числа (0 соответствует положительному числу, 1 – отрицательному).
Основные типы и размеры целочисленных данных:
Количество бит | Беззнаковый тип | Знаковый тип |
unsigned char 0...255 | char -128...127 | |
unsigned short 0...65535 | short -32768...32767 | |
unsigned int | int | |
unsigned long int | long int |
Вещественный тип предназначен для представления действительных чисел. Вещественные числа представляются в разрядной сетке машины в нормированной форме. Нормированная форма числа предполагает наличие одной значащей цифры (не 0) до разделения целой и дробной части. Такое представление умножается на основание системы счисления в соответствующей степени. Например, число 12345,678 в нормированной форме можно представить как
12345,678 = 1,2345678·104
Число 0,009876 в нормированной форме можно представить как
0,009876 = 9,876·10-3
В двоичной системе счисления значащий разряд, стоящий перед разделителем целой и дробной части, может быть равен только 1. В случае если число нельзя представить в нормированной форме (например, число 0), значащий разряд перед разделителем целой и дробной части равен 0.
Значащие разряды числа, стоящие в нормированной форме после разделителя целой и дробной части, называются мантиссой числа.
В общем случае вещественное число в разрядной сетке вычислительной машины можно представить в виде 4 полей.
знак - бит, определяющий знак вещественного числа (0 для положительных чисел, 1 - для отрицательных).
степень - определяет степень 2, на которую требуется умножить число в нормированной форме. Поскольку степень 2 для числа в нормированной форме может быть как положительной, так и отрицательной, нулевой степени 2 в представлении вещественного числа соответствует величина сдвига, которая определяется как
N-1
где n - количество разрядов, отводимых для представления степени числа.
целое - бит, который для нормированных чисел всегда равен 1, поэтому в некоторых представлениях типов этот бит опущен и принимается равным 1.
мантисса - значащие разряды представления числа, стоящие после разделителя целой и дробной части в нормированной форме.
Различают три основных типа представления вещественных чисел в языке Си:
Тип | Обозна- чение в Си | Кол-во бит | Биты степени | Мантисса | Сдвиг |
простое | float | 30...23 | 22...0 | ||
двойной точности | double | 62...52 | 51...0 | ||
двойной расширен- ной точности | long double | 78...64 | 62...0 |
Как видно из таблицы, бит целое у типов float и double отсутствует. При этом диапазон представления вещественного числа состоит из двух диапазонов, расположенных симметрично относительно нуля. Например, диапазон представления чисел типа float можно представить в виде:
Пример: представить число -178,125 в 32-разрядной сетке (тип float).
Для представления числа в двоичной системе счисления преобразуем отдельно целую и дробную части:
17810 = 101100102.
0,12510 = 0,0012.Тогда 178,12510 = 10110010,0012=1,0110010001·2111
(для преобразования в нормированную форму осуществляется сдвиг на 7 разрядов влево).
Для определения степени числа применяем сдвиг:
0111111+00000111 = 10000110.
Таким образом, число -178,125 представится в разрядной сетке как
Символьный тип хранит код символа и используется для отображения символов в различных кодировках. Символьные данные задаются в кодах и по сути представляют собой целочисленные значения. Для хранения кодов символов в языке Си используется тип char.
Подробнее о кодировке символов
Логический тип имеет два значения: истина и ложь - применяется в логических операциях, используется при алгоритмических проверках условий и в циклах.
В программе должно быть дано объявление всех используемых данных с указанием их имени и типа. Описание данных должно предшествовать их использованию в программе.
Пример объявления объектов
int n; // Переменная n целого типа
double a; // Переменная a вещественного типа двойной точности
Вопрос 2:Ссылки в C++.Ограничение на ссылки.
В С++ введен новый тип данных – ссылка. Ссылка позволяет определять альтернативное имя переменной.
Формат объявления ссылки:
тип &идентификатор = идентификатор2;
Такое объявление назначает переменной с именем идентификатор2 второе имя идентификатор.