Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Voprosy_po_lektsiam_6_9.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
351.23 Кб
Скачать

Указатель-константа

int var1=5, *pvar1=&var1;

int var2=6;

const int cvar1 = 1; // cvar1 – целая константа

const int *pcvar1 = &cvar1; // pcvar1 – указатель на константу

int *const cp1 = &var1; // cp1 – константный указатель, //запрещено изменение его значения

cout << *cp1 << endl; // 5

// cp1 = pvar1; // error!!! l-value specifies const object

*cp1 = var2; //OK!!! разрешено изменение содержимого по указателю

cout << *cp1 << endl; // 6

*cp1 = *pcvar1; //OK!!! разрешено изменение содержимого по указателю

cout << *cp1 << endl; // 1

// int *const cp2 = &cvar1; // error!!! //cannot convert from 'const int *' to 'int *const‘

// cp1 = pcvar1; // error!!! //cannot convert from 'const int *' to 'int *const‘

// cp1 = reinterpret_cast <int *const> (pcvar1); // error!!!

//'reinterpret_cast': cannot convert from 'const int *' to 'int *const'

Указатель-константа на константу

int var1=5, *pvar1=&var1;

int var2=6;

const int cvar1 = 1; // cvar1 – целая константа

// сpc1, сpc2 – константные указатели на константу

const int *const cpc1 = &var1; //const запрещает изменение значения и указателя,

const int *const cpc2 = &cvar1; //и содержимого *cpc1, *cpc2

cout << *cpc1 << endl; // 5 1

// cpc1 = pvar1; // error!!! l-value specifies const object

// *cpc1 = 8; // error!!! l-value specifies const object

Указатель на указатель

Сам указатель также имеет адрес:

i nt ivar1=5;

int *pivar1 = &ivar1, **pivar2=&pivar1;

cout << *pivar1<< endl; // 5

cout << *pivar2 <<endl; //00AB0100

cout << **pivar2 <<endl; //5

int ivar1=5;

int *pivar1 = &ivar1;

int **pivar2 = &pivar1;

i

//5 0x0012FF7C

//5 0x0012FF78

//5 0x0012FF74

//5 0x0012FF70

nt ***pivar3 = &pivar2;

cout << ivar1 << " " << &ivar1 << endl;

cout << *pivar1 << " " << &pivar1 << endl;

cout << **pivar2 << " " << &pivar2 << endl;

cout << ***pivar3 << " " << &pivar3 << endl;

cout << pivar1 << " " << *pivar1 << endl; // 0x0012FF7C 5

cout << pivar2 << " " << *pivar2 << " " << **pivar2 << endl; // 0x0012FF78 0x0012FF7C 5

cout << pivar3 <<" "<< *pivar3 <<" "<< **pivar3 <<" "<< ***pivar3 << endl;

  1. Возможные присваивания (л.9):

  1. const int* p;

int i = 17;

p = &i;

  1. const int* p;

int i = 17;

*p = 29;

  1. Указать и объяснить ошибку, если она есть (л.9):

  1. int i = 17;

int j = 29;

int* const p;

  1. int i = 17;

int j = 29;

int* const p1 = &i;

  1. int i = 17;

int j = 29;

int* const p1 = &i;

*p1 = 29;

  1. int i = 17;

int j = 29;

int* const p1 = &i;

p1 = &j;

  1. int i = 17;

int j = 29;

const int* const p;

  1. int i = 17;

int j = 29;

const int* const p1 = &i;

  1. int i = 17;

int j = 29;

const int* const p1 = &i;

*p1 = 29;

  1. int i = 17;

int j = 29;

const int* const p1 = &i;

p1 = &j;

__________________________________________________________________________________________________________________________________________________________

1 *из-за особенностей проверки на точное равенство вещественных чисел

2 Это делается для того, чтобы избавится от знака порядка

iВ заданиях 35-45 оператору printf ("%d\n", выражение); соответствует оператор cout << int (выражение) << endl; при спецификаторе %d и

cout << unsigned (выражение) << endl; при спецификаторе %u

printf ("%d\n", char(2&123));  cout << int (char (2&123)) << endl;

здесь: исходный типchar; тип преобразованияint;

printf ("%u\n", char(2&123));  cout << unsigned(char (2&123)) << endl;

здесь: исходный типchar; тип преобразованияunsigned;

Алгоритм преобразования типов:

  • выполняем указанную операцию и получаем логическое представление значения результата в количестве байтов, соответствующих заданному исходному типу;

  • расширяем представление числа до количества байт, определяемых типом преобразования; при этом:

    • если исходный тип числа знаковый (char, short, int,…), то представление числа расширяется знаковым битом (единицей или нулем);

    • если исходный тип числа беззнаковый (unsigned char, unsigned short, …), то представление числа всегда расширяется нулем;

  • дальнейшая интерпретация полученного логического представления значения результата зависит от типа преобразования:

    • для беззнакового – число вычисляем по его развернутой записи: 1*2i + …

    • для знакового типа:

      • если знаковый бит равен 0, то число положительное и получаем его значение по развернутой записи: 1*2i + …

      • если знаковый бит равен 1, то число отрицательное и получаем значение его модуля обычным образом (инверсия, затем +1, а затем приписываем знак - )

Пример 1:

cout << int (char (2&123)) << endl;

  1. 2&123= 2; логическое представление значения для исходного типа char: 000000102

  2. так как исходный тип char знаковый, а число положительное, то расширяем представление нулем

  3. для типа преобразования int имеем: 00000000 00000000 00000000 00000010

4. тип преобразования int – знаковый, знаковый бит содержит 0, значит число положительное и равно 2.

cout << unsigned(char (2&123)) << endl;

  1. 2&123= 2; логическое представление значения для исходного типа char: 000000102

  2. так как исходный тип char знаковый, а число положительное, то расширяем представление нулем

  3. для типа преобразования unsigned имеем: 00000000 00000000 00000000 00000010

  4. тип преобразования unsigned – беззнаковый, число равно 2

cout << int (unsigned char (2&123)) << endl;

  1. 2&123= 2;  логическое представление значения для исходного типа unsigned char: 000000102

  2. так как исходный тип unsigned char беззнаковый, то расширяем представление нулем

  3. для типа преобразования int имеем: 00000000 00000000 00000000 00000010

  4. тип преобразования int – знаковый, знаковый бит содержит 0, значит число положительное и равно 2.

Пример 2:

cout << int (char (~11)) << endl;

1. ~11= -12; логическое представление значения для исходного типа char: 111101002

2. так как исходный тип char знаковый, и число отрицательное, то расширяем представление единицей

3. для типа преобразования int имеем: 11111111 11111111 11111111 11110100

4. тип преобразования int – знаковый, знаковый бит содержит 1, значит число отрицательное и получим его модуль: 00000000 00000000 00000000 00001011 +1=00000000 00000000 00000000 00001100 2 = -12

cout << unsigned (char (~11)) << endl;

1. ~11= -12; логическое представление значения для исходного типа char: 111101002

2. так как исходный тип char знаковый, и число отрицательное, то расширяем представление единицей

3. для типа преобразования unsigned имеем: 11111111 11111111 11111111 11110100

4. тип преобразования unsignedбеззнаковый, значит число положительное и получим его значение по развернутой форме записи: 11111111 11111111 11111111 111101002 = 4294967284

cout << int (unsigned char (~11)) << endl;

1. ~11= -12; логическое представление значения для исходного типа unsigned char: 111101002

2. так как исходный тип unsigned char беззнаковый, то расширяем представление нулем

3. для типа преобразования int имеем: 00000000 000000000 00000000 11110100

4. тип преобразования int – знаковый, знаковый бит содержит 0, значит число положительное и получим его значение по развернутой форме записи: 00000000 00000000 00000000 11110100=244

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]