ТЕОРИЧЕСКИЕ ТЕМЫ:
- Введение в указатели
- Указатель арифметический
- Массивы и указатели
- Персонажи и указатели
- Указатели и функции
- Двойной указатель
ВОПРОСОВ:
Объявление указателя
Что из следующего является правильным объявлением указателя?
- int x;
- int
- int * x;
- ptr x;
Ответ: int * x;
Адрес переменной
Что из следующего дает адрес памяти целочисленной переменной a?
- *a;
- a;
- (ANS)
- адрес (а);
Ответ: и а
Объяснение: Переменная a является целым числом, а не целочисленным указателем. Поэтому мы используем & a, чтобы получить его адрес.
Адрес переменной
Что из следующего дает адрес памяти переменной ‘b’, на которую указывает указатель ‘a’, т.е.
int b = 10;
int *a = &b;
- a
- *a
- и
- адрес (а)
Ответ: а
Пояснение: a - указатель, в котором хранится адрес переменной b.
Вывод указателей
Что будет в этом коде?
int a = 100, b = 200;
int *p = &a, *q = &b;
p = q;
- b присваивается
- p теперь указывает на b
- a присваивается b
- q теперь указывает на
Ответ: p теперь указывает на b
Пояснение: a и b - две целочисленные переменные. p хранит адрес a, а q сохраняет адрес b. выполняя p = q, p теперь сохраняет адрес b
Вывод
int a = 7;
int b = 17;
int *c = &b;
*c = 7;
cout << a << " “ << b << endl;
- 7 17
- 17 7
- 7 7
- 17 17
Ответ: 7 7
Пояснение: c хранит адрес переменной b. Затем значение по адресу, хранящемуся в c (который имеет значение b), обновляется до 7 (то есть b = 7).
Вывод
int a = 50;
int *ptr = &a;
int *q = ptr;
(*q)++;
cout << a << endl;
- 50
- 51
- Ошибка
- Ни один из этих
Ответ: 51
Объяснение: ptr указывает на. q указывает на точку ptr напрямую и на сквозную точку ptr. * q = значение p = адрес a. Итак, (* q) ++ увеличивает значение по адресу a. Таким образом, a становится 51 из 50.
Вывод
int *ptr = 0;
int a = 10;
*ptr = a;
cout << *ptr << endl;
- 10
- 0
- Ошибка
- Ни один из этих
Ответ: ошибка
Пояснение: во время печати * ptr указывает на значение по адресу a, равное 10. По адресу 10 не хранится значение.
Вывод
int a = 7;
int b = 17;
int *c = &b;
a = *c;
*c = *c + 1;
cout << a << " " << b << endl;
- 18 18
- 7 18
- 17 17
- 17 18
Ответ: 17 18
Пояснение: c указывает на b. a имеет значение по адресу, хранящемуся в c, который равен b (17). Значение по адресу, хранящемуся в c, увеличивается на 1 (b = 17 + 1 = 18).
Вывод указателей
float f = 10.5;
float p = 2.5;
float* ptr = &f;
(*ptr)++;
*ptr = p;
cout << *ptr << “ “ << f << “ “ << p;
- 2.5 10.5 2.5
- 2.5 11.5 2.5
- 2.5 2.5 2.5
- 11.5 11.5 2.5
Ответ: 2,5 2,5 2,5
Пояснение: ptr указывает на f. f увеличивается на 1 до ptr (теперь f = 11,5). f = p с использованием ptr (сейчас f = 2,5).
Вывод указателей
int a = 7;
int *c = &a;
c = c + 1;
cout << a << " " << *c << endl;
- Garbage_value 7
- 7 Garbage_value
- 8 8
- 7 7
Ответ: 7 Garbage_value
Пояснение: c хранит адрес a (и указывает на значение a). адрес, который хранит c, увеличивается на 1, поэтому теперь он указывает на неизвестное значение.
Вывод
Предположим, что адрес памяти переменной «a»: 400 (а целое число занимает 4 байта), что будет на выходе -
int a = 7;
int *c = &a;
c = c + 3;
cout << c << endl;
Ответ: 412
Пояснение: c хранит адрес a (и указывает на значение a). адрес, который хранит c, увеличивается на 3., поскольку c имеет тип int, приращение в байтах составляет 3 целых адреса, то есть 3 * 4 = 12 байтов. поэтому 400 + 12 = 412
Вывод
Предположим, что целое число занимает 4 байта, а целочисленный указатель - 8 байтов.
int a[5];
int *c;
cout << sizeof(a) << “ “ << sizeof(c);
- 8 8
- 5 8
- 20 8
- 20 4
Ответ: 20 8
Объяснение: массив a имеет размер 5 и тип int (4 байта на int), поэтому общий размер = 5 * 4 = 20. c - целочисленный указатель, поэтому его размер равен 4 ( для 32-битной системы) или 8 (для 64-битной системы).
Заполнить вывод
int a[] = {1, 2, 3, 4};
cout << *(a) << " " << *(a+1);
Ответ: 1 2
Пояснение: * a указывает на первое значение массива a = 1. * (a + 1) = * (второе значение массива a) = 2.
Заполнить вывод
Предположим, что адрес 0-го индекса массива «a»: 200.
Что на выходе -
int a[6] = {1, 2, 3};
cout << a << “ “ << &a;
- Ошибка
- 200 204
- 200 200
- 1 200
- 200 1
Ответ: 200 200
Пояснение: a - первое значение массива a. & a - адрес первого значения массива a, равного 200.
Заполнить вывод
Предположим, что адрес 0-го индекса массива «a»: 200. Каков результат -
int a[6] = {1, 2, 3};
cout << (a + 2);
Ответ: 208
Объяснение: a имеет тип int, поэтому для каждого значения адрес увеличивается на 4. a + 2 - это адрес третьего значения массива a. итак, 200 (1) - 204 (2) - 208 (3)
Вывод
Предположим, что адрес 0-го индекса массива «a» равен 200.
Что на выходе -
int a[6] = {1, 2, 3};
int *b = a;
cout << b[2];
- Ошибка
- 3
- 1
- 200
- 212
Ответ: 3
Пояснение: b хранит адрес первого значения массива a. b [2] будет 0,1,2-м значением массива a, то есть 3.
Вывод
Предположим, что адрес 0-го индекса массива «a» равен 200.
Что на выходе -
int a[] = {1, 2, 3, 4, 5};
cout << *(a) << " " << *(a + 4);
- Ошибка
- 200 216
- 1 5
- Ни один из этих
Ответ: 1 5
Пояснение: * a дает первое значение массива a (1). * (a + 4) дает пятое значение массива a (5).
Вывод
int a[] = {1, 2, 3, 4};
int *p = a++;
cout << *p << endl;
- 1
- 2
- Ценность мусора
- Ошибка
Ответ: ошибка
Объяснение: адрес всего массива нельзя сдвинуть на четыре байта
Вывод указателей
char ch = 'a';
char* ptr = &ch;
ch++;
cout << *ptr << endl;
- a
- b
- 97
- 98
Ответ: б
Пояснение: маленький ascii 97. ptr указывает на ch. ch увеличивается и теперь составляет 98 (b).
Вывод
Предположим, что адрес 0-го индекса массива «b» равен 200. Каков результат -
char b[] = "xyz";
char *c = &b[0];
cout << c << endl;
- 200
- x
- xyz
- Ни один из этих
Ответ: xyz
Пояснение: c хранит адрес начала массива b (а не его значений). Таким образом, при печати c печатается весь массив.
Вывод
Предположим, что адрес 0-го индекса массива «b» равен 200. Каков результат -
char b[] = "xyz";
char *c = &b[0];
c++;
cout << c << endl;
- 201
- y
- xyz
- yz
Ответ: yz
Пояснение: c хранит адрес начала массива b (а не его значений). Поскольку это тип char, один байт увеличивается для адреса c. Таким образом, печатаются все символы массива, кроме пропущенного / первого.
Заполнить вывод
char s[]= "hello";
char *p = s;
cout << s[0] << " " << p[0];
Ответ: чч
Пояснение: p указывает на начальное значение массива s. p [0] вызывает значение 0 символов, пропущенное с его адреса, которое является значением по самому адресу, то есть s [0].
Вывод указателей
void changeSign(int *p){ *p = (*p) * -1; }
int main(){ int a = 10; changeSign(&a); cout << a << endl; }
- -10
- 10
- Ошибка
- Ни один из вышеперечисленных
Ответ: -10
Объяснение: p функции хранит адрес a. Таким образом, это указывает на фактическое значение a. Когда значение, на которое указывает p, становится отрицательным, a также становится отрицательным, и наоборот.
Заполнить вывод
void fun(int a[]) { cout << a[0] << " "; }
int main() { int a[] = {1, 2, 3, 4}; fun(a + 1); cout << a[0]; }
Ответ: 2 1
Объяснение: +1 дает весь массив, кроме первого значения массива в качестве параметра (2 3 4). Таким образом, 0-е значение равно 2.
Вывод
void square(int *p){ int a = 10; p = &a; *p = (*p) * (*p); }
int main(){ int a = 10; square(&a); cout << a << endl; }
- 100
- 10
- Ошибка
- Ни один из этих
Ответ: 10
Пояснение: p указывает на фактическое значение a, поскольку адрес a передается как параметр. Внутри функции p теперь указывает на локальный элемент a внутри функции. Обновление локального а не меняет его внутри основного.
Вывод
int a = 10;
int *p = &a;
int **q = &p;
int b = 20;
*q = &b;
(*p)++;
cout << a << " " << b << endl;
- 10 21
- 11 20
- 11 21
- 10 20
Ответ: 10 21
Объяснение: p указывает на a. q указывает на p напрямую, а a - на p (двойной указатель). * q - значение, хранящееся в p, изменяется на адрес b вместо адреса a. (* p) ++ - значение, на которое указывает p, которое теперь равно b, увеличивается на 1 (b становится 21). Значение остается неизменным.
Вывод
int a = 100;
int *p = &a;
int **q = &p;
int b = (**q)++ + 4;
cout << a << " " << b << endl;
- 100 104
- 101 104
- 101 105
- 100 105
Ответ: 101 104
Объяснение: p указывает на a. q указывает на p напрямую, а на a - через p (двойной указатель). b сохраняет значение от a до p - q плюс 4, что составляет 100 + 4 = 104. Значение, хранящееся в b, увеличивается на 1 с помощью оператора пост-инкремента после конца этого оператора.
Вывод указателей
int a = 100;
int *p = &a;
int **q = &p;
int b = (**q)++;
int *r = *q;
(*r)++;
cout << a << " " << b << endl;
- 102 100
- 101 100
- 101 101
- 102 101
Ответ: 102 100
Объяснение: p указывает на a. q указывает на p напрямую и на a через p. b присваивается значение от a до q (b = 100), а значение от a до q увеличивается пост-инкрементно (a = 101). r указывает на p. Значение в p увеличивается после публикации на r (a = 102).
Вывод указателей
void increment(int **p){ (**p)++; }
int main(){ int num = 10; int *ptr = # increment(&ptr); cout << num << endl; }
- 10
- 11
- Ошибка
- Ни один из этих
Ответ: 11
Объяснение: ptr указывает на число. p указывает на ptr напрямую и на число через ptr. значение в num увеличивается на 1 через q через p (число становится 11).
Вывод
#include <iostream>
using namespace std;
int main()
{
int arr[] = {4, 5, 6, 7};
int *p = (arr + 1);
cout << *arr + 9;
return 0;
}
- 12
- 14
- 13
- ошибка
Ответ: 13
Пояснение: p указывает на адрес начального индекса массива arr плюс 4 байта, которые являются 1-м индексом. * arr указывает на первый индекс, равный 4, прибавив 9 к нему, получим 13.
Вывод
#include <iostream>
using namespace std;
int main ()
{
int numbers[5];
int * p;
p = numbers;
*p = 10;
p = &numbers[2];
*p = 20;
p--;
*p = 30;
p = numbers + 3;
*p = 40;
p = numbers;
*(p+4) = 50;
for (int n=0; n<5; n++) {
cout << numbers[n] << ",";
}
return 0;
}
- 10,20,30,40,50,
- 50,40,30,20,10,
- 10,30,20,40,50,
- Ни один из этих
Ответ: 10,30,20,40,50,
Пояснение: p указывает на первое значение массива чисел, которое обновляется до 10 (числа [0] = 10). p теперь указывает на третье значение массива чисел и обновляет его до 20 (числа [2] = 20). p уменьшается на 4 байта и обновляется до 30 (числа [1]). p теперь указывает на 4-е значение чисел и обновляет его до 40 (числа [3] = 40). p теперь указывает на первое значение массива чисел, обновляет его 5-е значение до 50. Numbers = 10 30 20 40 50
Вывод
#include <iostream>
using namespace std;
int main()
{
char *ptr;
char Str[] = "abcdefg";
ptr = Str;
ptr += 5;
cout << ptr;
return 0;
}
- fg
- cdef
- defg
- abcd
Ответ: fg
Объяснение: ptr указывает на весь массив строк. ptr теперь указывает на шестое значение строкового массива. Печатаются все символы, начиная с шестого индекса.
Символы и указатели
#include <iostream>
using namespace std;
int main()
{
char arr[20];
int i;
for(i = 0; i < 10; i++) {
*(arr + i) = 65 + i;
}
*(arr + i) = '\0';
cout << arr;
return 0;
}
- ABCDEFGHIJ
- AAAAAAAAAA
- JJJJJJJJ
- ни один из упомянутых
Ответ: ABCDEFGHIJ
Пояснение: для первой итерации * (arr + 0) - это ascii (65 + 0), то есть A, и так далее…
Вывод
#include<iostream> using namespace std; void swap (char *x, char *y) { char *t = x; x = y; y = t; }
int main() { char *x = "geeksquiz"; char *y = "geeksforgeeks"; char *t; swap(x, y); cout<<x << " "<<y; t = x; x = y; y = t; cout<<" "<<x<< " "<<y; return 0; }
- вундеркинды викторины вундеркинды викторины
- викторина вундеркиндов
- викторина вундеркиндов викторина
- Ошибка компилятора
Ответ: geeksquiz geeksforgeeks geeksforgeeks geeksquiz
Объяснение: поскольку параметры для функции подкачки не передаются по ссылке, поэтому фактические значения в них остаются неизменными при вызове функции подкачки.
Вывод
#include <iostream>
using namespace std;
int main()
{
float arr[5] = {12.5, 10.0, 13.5, 90.5, 0.5};
float *ptr1 = &arr[0];
float *ptr2 = ptr1 + 3;
cout<<*ptr2<<" ";
cout<< ptr2 - ptr1;
return 0;
}
- 90.5 3
- 90.5 12
- 10.0 12
- неопределенный
Ответ: 90,5 3
Пояснение: ptr1 указывает на первое значение arr (12,5). ptr2 указывает на четвертое значение arr (90,5). Итак, * ptr2 равно 90,5, и если ptr1 равно x, ptr2 равно x + 3. Вычитая эти значения, получаем 3.
Вывод
#include<iostream>
using namespace std;
int main() {
char st[] = "ABCD";
for(int i = 0; st[i] != ‘\0’; i++) {
cout << st[i] << *(st)+i << *(i+st) << i[st];
}
return 0;
}
- AAAABBBBCCCCDDDD
- ABCD
- A65AAB66BBC67CCD68DD
- Ошибка компиляции
Ответ: A65AAB66BBC67CCD68DD
Пояснение: для первой итерации: A ‹---------------- * (st [0]) + 0 = A + 0 (приведено к 65) ‹---------------- st [0] = A ‹---------------- 0-й индекс значение st = A… .. И так далее…
Вывод
#include <iostream> using namespace std; void Q(int z) { z += z; cout<<z << " "; }
void P(int *y) { int x = *y + 2; Q(x); *y = x - 1; cout<<x << " "; }
int main() { int x = 5; P(&x); cout<<x; return 0; }
- 7 6 14
- 14 7 5
- 14 7 6
- 14 6 5
Ответ: 14 7 6
Пояснение: y в P () указывает на фактическое значение x в main. локальный x в P () имеет значение (5 + 2 = 7). Копия локального x (7) передается в Q () и выводится 7 + 7 = 14. фактическое значение x обновляется через y до локального x: x-1 = 7–1 = 6. Локальный x (7) печатается в конце P (). фактическое значение x (6) выводится в main.
Вывод
#include<iostream>
using namespace std;
int main()
{
int ***r, **q, *p, i=8;
p = &i;
(*p)++;
q = &p;
(**q)++;
r = &q;
cout<<*p << " " <<**q << " "<<***r;
return 0;
}
- 8 8 8
- 10 10 10
- 9 10 11
- 9 10 10
Ответ: 10 10 10
Пояснение: p указывает на i. значение от i ++ до p (i = 9). q указывает на p напрямую и на i через p. от i ++ (i = 10) до q. r указывает на q напрямую, p - q, i - p - q. Печатаются i, i, i, то есть 10, 10, 10.
Вывод
int f(int x, int *py, int **ppz) { int y, z; **ppz += 1; z = **ppz; *py += 2; y = *py; x += 3; return x + y + z; }
int main() { int c, *b, **a; c = 4; b = &c; a = &b; cout << f(c, b, a); return 0; }
- 21
- 18
- 19
- 24
Ответ: 19
Пояснение: b указывает на c. a указывает на b напрямую, а на c - через b. копии c, b, a передаются в функцию (те же правила применяются к параметрам переменных). Значение x увеличивается на 1 до ** ppz (x = 4). z теперь сохраняет ** ppz = 4. значение x увеличивается на 2 с использованием * py (x = 6). = * py = 6. x увеличивается на 3 (x = 9). х + у + х = 4 + 6 + 9 = 19.