Билет 6
Вопрос 1:Указатели и операции с ними в языке c.Примеры.
Указатель — переменная, содержащая адрес объекта. Указатель не несет информации о содержимом объекта, а содержит сведения о том, где размещен объект. Указатели широко используются в программировании на языке Си. Указатели часто используются при работе с массивами.
Память компьютера можно представить в виде последовательности пронумерованных однобайтовых ячеек, с которыми можно работать по отдельности или блоками.
Каждая переменная в памяти имеет свой адрес - номер ячейки, где она расположена, а также свое значение. Указатель — это тоже переменная, которая размещается в памяти. Она тоже имеет адрес, а ее значение является адресом некоторой другой переменной. Переменная, объявленная как указатель, занимает 4 байта в оперативной памяти (в случае 32-битной версии компилятора).
Указатель, как и любая переменная, должен быть объявлен. Общая форма объявления указателя
тип *имя_объекта;
Тип указателя— это тип переменной, адрес которой он содержит.
Для работы с указателями в Си определены две операции:
операция * (звездочка) — позволяет получить значение объекта по его адресу - определяет значение переменной, которое содержится по адресу, содержащемуся в указателе;
операция & (амперсанд) — позволяет определить адрес переменной.
Например,
сhar c; // переменная char *p; // указатель p = &c; // p = адрес c
Для
указанного примера обращение к одним
и тем же значениям переменной и адреса
представлено в таблице
|
Переменная |
Указатель |
Адрес |
&c |
p |
Значение |
c |
*p |
Пример
#include <stdio.h> #include <stdlib.h> int main() {
int a, *b;
system("chcp 1251");
system("cls");
a=134;
b=&a;
printf("\n Значение переменной a равно %d.", a);
printf("\n Адрес переменной a равен %d.", &a);
printf("\n Данные по адресу указателя b равны %d.",*b);
printf("\n Значение указателя b равно %d.",b);
printf("\n Адрес расположения указателя b равен %d.", &b);
getchar();
return 0; }
Результат
выполнения программы:
Расположение
в памяти переменной a и указателя
b:
Необходимо
помнить, что компиляторы высокого уровня
поддерживают прямой
способ адресации:
младший байт хранится в ячейке, имеющей
младший адрес.
Вопрос 2:Классы в С++:объявление, спецификаторы доступа
1)Классы
Классы в С++ определяются ключевым словом class. Они представляют собой форму структуры, у которой спецификация доступа по умолчанию – private, то есть
class s { ...}
есть сокращенная запись
struct s { private: ...}
Хотя такое определение класса и справедливо, базовым в языке С++ является понятие класса. В С++ принято считать, что структура struct – это просто класс, все члены которого общие, то есть
struct s { ...};
есть просто сокращенная запись
class s { public: ...}
Структуры необходимо использовать в тех случаях, когда сокрытие данных неуместно. В качестве иллюстрации, представим абстрактный тип данных для комплексных чисел с помощью структуры и с помощью класса. Единственное отличие — в использовании ключевых слов: private и public. С использованием структуры:
struct complex {
void assign(double r, double i);
void print() { cout << real << "+"<< imag << "i"; } private:
double real;
double imag; }; void complex :: assign(double r, double i=0.0) {
real = r;
imag = i; }
С использованием структуры:
class complex {
double real;
double imag;
public:
void assign(double r, double i);
void print() { cout << real << "+"<< imag << "i"; } }; void complex :: assign(double r, double i=0.0) {
real = r;
imag = i; }
2)Объявление
В объявлениях в программу вводятся имена переменных, пространств имен, функций, классов и т. д. В объявлениях также указываются типы данных и другие характеристики объявляемых объектов. Перед использованием имени его необходимо объявить. В C++ точка, в которой объявляется имя, определяет, будет ли оно видимо для компилятора. Нельзя сослаться на функцию или класс, объявленные в блоке компиляции после предполагаемой ссылки. Чтобы обойти это ограничение, вы можете использовать опережающее объявление.
Объявление включает в программу одно или несколько имен. Объявления могут возникать в программе несколько раз. Следовательно, классы, структуры, перечисляемые типы и другие пользовательские типы можно объявить для каждого блока компиляции. В отношении этого множественного объявления действует следующее ограничение: все объявления должны быть идентичными. Объявления также служат как определения. Исключение составляют ситуации, когда объявление:
является прототипом функции (объявлением функции без тела функции).
содержит описатель extern, но не содержит инициализатор (объекты и переменные) или основную часть функции (функции). Это означает, что определение в текущей записи преобразования не является обязательным, и предоставляет имени внешнюю компоновку.
Является статическими данными-членом внутри объявления класса.
Поскольку статические данные-члены являются дискретными переменными, общими для всех объектов класса, их необходимо определять и инициализировать за пределами объявления класса. (Дополнительные сведения о классах и членах классов см. в разделе Классы.)
является объявлением имени класса без последующего определения, такого как class T;.
является оператором typedef.
Ниже приводятся примеры объявлений, которые также являются определениями.
// Declare and define int variables i and j.
int i;
int j = 10;
// Declare enumeration suits.
enum suits { Spades = 1, Clubs, Hearts, Diamonds };
// Declare class CheckBox.
class CheckBox : public Control
{
public:
Boolean IsChecked();
virtual int ChangeState() = 0;
};
К объявлениям, не являющимся определениями, относятся следующие.
extern int i;
char *strchr( const char *Str, const char Target );
Имя считается объявленным сразу после его декларатора, но перед его (необязательным) инициализатором. Дополнительные сведения см. в разделе Точка объявления.
Объявления находятся в области видимости. Область видимости определяет видимость объявленных имен, а также срок жизни определенного объекта (при наличии). Дополнительные сведения о том, как правила области видимости взаимодействуют с объявлениями, см. в разделе Область.
Объявление объекта одновременно является определением, кроме случаев, когда в нем содержится спецификатор класса хранения extern, описанный в разделе Спецификаторы классов хранения. Объявление функции одновременно является определением, если оно не является прототипом. Прототип — это заголовок функции без определения тела функции. Определение объекта выполняет выделение области хранения и соответствующие инициализации этого объекта.
3)Спецификаторы доступа
В С++ члены класса классифицируются в соответствии с правами доступа на следующие три категории: публичные (public), частные (private) и защищенные (protected). Любая функция программы имеет доступ к публичным членам. Доступ к частному члену имеют только функции-члены класса или функции-друзья класса. Защищенные члены аналогичны частным членам. Разница между ними появляется только при наследовании классов.
Когда один класс наследует другой, все публичные члены базового класса становятся публичными членами производного класса. В противоположность этому частные члены базового класса не доступны внутри производного класса. Например, рассмотрим следующий фрагмент: class X { int i; int j; public: void get_ij(); void put_ij(); }; class Y: public X { int k; public: int get_k(); void make_k(); };
Класс Y наследует и имеет доступ к публичным функциям get_ij() и put_ij() класса X, но не имеет доступа к i и j, поскольку они являются частными членами X. Во всех случаях частные члены остаются частными, т. е. доступными только в том классе, в котором они объявлены. Таким образом, частные члены не могут участвовать в наследовании.
В связи с тем, что частные члены не могут быть наследованы, возникает интересный вопрос: что если необходимо оставить член частным и вместе с тем позволить использовать его производным классам? Для таких целей имеется другое ключевое слово — protected (защищенный). Защищенный член подобен частному, за исключением механизма наследования. При наследовании защищенного члена производный класс также имеет к нему доступ. Таким образом, указав спецификатор доступа protected, можно позволить использовать член внутри иерархии классов и запретить доступ к нему извне этой иерархии. Например: class X { protected: int i; int j; public: void get_ij(); void put_ij(); }; class Y: public X { int k; public: int get_k(); void make_k(); };
Здесь класс Y имеет доступ к i и j, и в то же время они остаются недоступными для остальной части программы. Когда элемент объявляется защищенным, доступ к нему ограничивается, но вместе с тем можно наследовать права доступа. В отличие от этого в случае частных членов доступ не наследуется.
Другой важной особенностью ключевых слов private, protected и public служит то, что они могут появляться в объявлении в любом порядке и в любом количестве. Например, следующий код является вполне законным: class my_class { protected: int i; int j; public: void f1(); void f2(); protected: int a; public: int b; };
Однако считается хорошим стилем, чтобы каждый из спецификаторов доступа встречался в объявлении класса не более одного раза.
Билет 7
