Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.97/64: Рейтинг темы: голосов - 64, средняя оценка - 4.97
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335

Указатели, адрес переменной

01.03.2020, 09:21. Показов 13584. Ответов 42
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
int main(коллеги!)
Снова прошу меня поправить!
Есть такой пример:
C++
1
2
3
4
5
6
7
8
9
 int *ptr;           // переменная - ptr, указывает на - int значение (*ptr - это указатель на значение - int)
 
 int total = 3200;   // обычная "интовая" переменная - total, получает значение 3200
 
 ptr = &total;       // переменная - ptr получает адрес переменной - total  (в переменную - ptr, помещается адрес переменной - total)
 
 int val = *ptr;     // а здесь наоборот, из адреса хранящегося в - ptr, получаем значение и присваиваем его переменной - val
                     // то есть теперь переменные total и val содержат одинаковые значения = 3200
                     /// переменная - ptr, нужна была для записи и хранения адреса переменной - total
Я его подробно закоментировал как сам понимаю, то есть дополнил комент из книги...
Но первая строчка - int *ptr; не вполне понятна
как я это понимаю, что переменная - ptr интовая! только и всего!
Правильно?

Можно записать все вот так:
C++
1
2
3
4
5
 int total = 3200;   
 
 int *ptr = &total;    // ну то есть, объявляем интовый указатель - *ptr  ?????????????
 
 int val = *ptr;
Добавлено через 2 минуты
Ну если совсем примитивно то так:

int *ptr - указатель с типом - int
int ptr - переменная с типом - int
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
01.03.2020, 09:21
Ответы с готовыми решениями:

Массивы и Указатели: распечатать таблицу,содержащую имя переменной,ее значение и адрес
Условие:Написать программу,которая создает несколько переменных целого и вещественного типа,для каждой переменной создает указатель,а затем...

Убедиться, что адрес первого элемента массива и адрес, хранящийся в указатели на этот массив равны.
Убедиться, что адрес первого элемента массива и адрес, хранящийся в указатели на этот массив - равны.

Есть три переменные. Используя указатели на указатели, поменять значение максимальной и минимальной переменной
Мой код. #include <iostream> #include <stdlib.h> #include<iomanip> using namespace std; void min_max(int*pa, int*pb,...

42
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
01.03.2020, 09:24
Цитата Сообщение от R_U_S_V Посмотреть сообщение
как я это понимаю, что переменная - ptr интовая! только и всего!
ptr - это указатель на другую переменную типа int
Цитата Сообщение от R_U_S_V Посмотреть сообщение
(*ptr - это указатель на значение - int)
Только не на значение, а на саму переменную. Значение - это содержимое переменной, а переменная - это, грубо говоря, область памяти, хранящая значение. Вот на эту область памяти и будет указывать указатель, то есть будет хранить адрес этой области памяти.
1
фрилансер
 Аватар для Алексей1153
6466 / 5684 / 1131
Регистрация: 11.10.2019
Сообщений: 15,129
01.03.2020, 09:33
Цитата Сообщение от R_U_S_V Посмотреть сообщение
Но первая строчка - int *ptr; не вполне понятна
C++
1
int *ptr;
это объявление переменной-указателя без инициализации. Содержимое - мусор

вот так - присваиваем нулевое значение (такое значение общепринято считается отсутствием адреса. То есть 0 - значит, указатель не заполнен)
C++
1
int* ptr=nullptr;
вот так - инициализируем адресом переменной total
C++
1
2
int total = 3200;
int* ptr = &total;
1
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335
01.03.2020, 10:18  [ТС]
Цитата Сообщение от likehood Посмотреть сообщение
ptr - это указатель на другую переменную типа int
А на какую? На ту которую мы пока не объявили?

Добавлено через 1 минуту
Цитата Сообщение от Алексей1153 Посмотреть сообщение
это объявление переменной-указателя без инициализации. Содержимое - мусор
Так я вроде о том же , что это указатель типа int, но без инициализации
а инициализируется вот здесть - int *ptr = &total; когда получает адрес переменной total

И еще, я правильно понимаю, что обычная переменная не может содержать адрес другой переменной?
То есть если мы хотим получить адрес либо записать его, мы это делаем только через указатель, то есть так :
*ptr
&ptr
0
1272 / 1029 / 470
Регистрация: 25.12.2016
Сообщений: 3,333
01.03.2020, 10:19
Цитата Сообщение от R_U_S_V Посмотреть сообщение
А на какую? На ту которую мы пока не объявили?
Пока не на какую. Как выше написал Алексей1153, содержимое - мусор.
1
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335
01.03.2020, 10:31  [ТС]
Цитата Сообщение от likehood Посмотреть сообщение
Пока не на какую. Как выше написал Алексей1153, содержимое - мусор.
Понятно! Без инициализации...
То есть это указатель на интовую переменную, который пока не инициализирован!

Добавлено через 6 минут
Вот итог из того, что смог понять:
C++
1
2
3
4
5
6
7
8
9
 int total = 3200;   // обычная "интовая" переменная - total, получает значение 3200
 
 
 int *ptr = &total;  // указатель - *ptr получает адрес переменной - total  (в переменную - ptr, помещается адрес переменной - total)
                     // то есть мы инициализируем указатель - *ptr, присваивая ему адрес переменной - total
 
 int val = *ptr;     // а здесь наоборот, из адреса хранящегося в указателе - *ptr, получаем значение и присваиваем его переменной - val
                     // то есть теперь переменные total и val содержат одинаковые значения = 3200
                     /// переменная - *ptr (указатель), нужна была для записи и хранения адреса переменной - total
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
01.03.2020, 10:42
Цитата Сообщение от R_U_S_V Посмотреть сообщение
То есть это указатель на интовую переменную, который пока не инициализирован!
R_U_S_V, строго говоря, инициализация, это процесс установки значения в момент создания. Он может быть выражен явно. И лучше всего это использовать. Но для ряда областей (глобальная, например) инициализация может быть проведена по умолчанию. Это зависит также и от типа о котором заходит речь. Для указателя не инициализированного пользователем действует правило - nullptr в глобальной области и для статических локальных переменных. Иначе память захватывается но содержимое - случайный набор нулей и единиц (мусор). Это значит что указатель указывает на что-то, но ни кто не знает на что именно. Это означает что попытка записи может не закончится плачевно. На системах умеющих защищаться, это безопаснее. Но программа будет вести себя придурковато, хотя обнаружить это будет не просто. Всё как и с людьми.
1
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335
01.03.2020, 10:49  [ТС]
ну то есть можно было бы сделать так
int *ptr=nullptr;
а затем уже переопределить
int *ptr = &total;
Верно??

И еще, все же - int *ptr; пока не инициализированный указатель на интовую переменную
или
пока не инициализированный интовый указатель на переменную

мне это важно, чтоб уж совсем разобраться с этим моментом!
0
Заблокирован
01.03.2020, 10:53
Цитата Сообщение от R_U_S_V Посмотреть сообщение
int *ptr=nullptr;
ну имеет смысл чтоб потом предварительно проверять, а так особого смысла нет
C++
1
if(ptr!=nullptr)....
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
01.03.2020, 10:56
Цитата Сообщение от R_U_S_V Посмотреть сообщение
ну то есть можно было бы сделать так
C++
1
2
3
int *ptr=nullptr;
//а затем уже переопределить
int *ptr = &total;
Верно??
Лучше,
C++
1
2
3
int *ptr=nullptr;
//а затем уже переопределить
ptr = &total;
а ещё лучше:
C++
1
int *ptr = &total;
Цитата Сообщение от R_U_S_V Посмотреть сообщение
И еще, все же - int *ptr; пока не инициализированный указатель на интовую переменную
Можно так сказать. Говорят указатель на инт или указатель инт (что новичков, радует лёгким сбиванием с толку).
Тот факт, что он да/не инициализирован не имеет отношение к названию типа (указатель это тип), не старайтесь себя запутать. Некоторое время процесс и так будет идти в автоматическом режиме.
ps инициализация нулём - старая техника, но иногда уместна. Можно проверить. Кроме того, освобождение (delete) на указателе с мусором, это пожар на свалке. А вот, ноль горит ровно и безопасно. Хоть и не греет.
1
 Аватар для Annemesski
2674 / 1336 / 480
Регистрация: 08.11.2016
Сообщений: 3,692
01.03.2020, 10:59
Цитата Сообщение от R_U_S_V Посмотреть сообщение
То есть это указатель на интовую переменную, который пока не инициализирован!
Переменная тоже не инициализируется сама.
есть два понятия: объявление и определение
C++
1
2
3
4
int a; // объявили переменную типа int
cout << a << endl; // выведет мусор
a = 0; // здесь определили переменную, теперь в ней записано нулевое значение
int b = 5; // а здесь и объявление и определение объединены в одно выражение
int* - это другой тип данных, называется указатель на переменную типа int и он всегда определен, в нем записан адрес области памяти которая (память) хранит переменную типа int, а по адресу мусор или определенное значение если оно было определено
C++
1
2
3
4
5
6
7
8
9
10
11
12
int a = 0;
int *ptr_a; // объявили указатель - он определен - это конкретная область памяти по которой лежит мусор
cout << ptr_a << endl; // выведет адрес
cout << *ptr_a << endl; // выведет мусор, применена операция "*" - разыменование указателя, то есть обращение к области памяти на которую он указывает
*ptr_a = 5; // записали по адресу указателя значение 5 для переменной типа int
cout << ptr_a << endl; // выведет тот же адрес что и в строке №3
cout << *ptr_a << end; // выведет значение 5
ptr_a = &a; // здесь применен оператор "&" - взятия ссылки на переменную а, ссылка - это адрес переменной
cout << ptr_a << endl; // выведет адрес переменной "a" - отличный от адреса что выводился в строках 3 и 6
cout << *ptr_a << endl; // выведет 0 - значение переменной "a";
*ptr_a = 7; // после этого
cout << a << endl; // выведет 7, теперь мы имеем две точки доступа к переменной "а", собственно саму "а" и указатель ptr_a которые связаны с одной и той же областью памяти.
1
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335
01.03.2020, 11:07  [ТС]
Понятно, лучше сразу инициализировать при объявлении, ну то есть все как и с обычными переменными.
Переменной же тоже можно дать начальное значение = 0 допустим а потом, ниже его перезаписать уже в коде...

Добавлено через 3 минуты
Цитата Сообщение от Annemesski Посмотреть сообщение
Переменная тоже не инициализируется сама.
есть два понятия: объявление и определение
Я объявление и инициализацию различаю
int a; // объявляем
a=1; // инициализируем

int a=1; // и объявляем и сразу инициализируем
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
01.03.2020, 11:07
Цитата Сообщение от Annemesski Посмотреть сообщение
Переменная тоже не инициализируется сама.
Конечно. Это делает вычислительная система. По умолчанию она может инициализировать. И это зависит от соглашений в языке программирования. Вот ещё познавательный фрагмент:
Цитата Сообщение от Annemesski Посмотреть сообщение
int* - это другой тип данных, называется указатель на переменную типа int и он всегда определен, в нем записан адрес области памяти которая (память) хранит переменную типа int, а по адресу мусор или определенное значение если оно было определено
В самом указателе тоже может быть мусор. Он конечно не мерцает и строго определён, но его ни кто не знает. Принято считать, что такое значение не является результатом инициализации и является неопределённым.
1
10 / 9 / 1
Регистрация: 25.12.2019
Сообщений: 335
01.03.2020, 11:20  [ТС]
Цитата Сообщение от IGPIGP Посмотреть сообщение
В самом указателе тоже может быть мусор. Он конечно не мерцает и строго определён, но его ни кто не знает.
Я так понимаю, что мусор затирается нужным значением в момент его присваивание ниже по коду и это нормально, ну то есть хрен с ним что вверху переменная без четкого значения, ниже же мы его поменяем, и это никак не скажется на безопасности работы программы, или я не прав?
и есть ситуации когда это не так?
Ну в целом то я понял, что лучше сразу инициализировать!
0
 Аватар для Annemesski
2674 / 1336 / 480
Регистрация: 08.11.2016
Сообщений: 3,692
01.03.2020, 11:23
Цитата Сообщение от IGPIGP Посмотреть сообщение
И это зависит от соглашений в языке программирования.
Я писал именно в контексте ветки форума, то бишь про С++, в каком-нибудь паскале переменные инициализируются, по умолчанию, нулем, в каждом ЯП свои соглашения на этот счет.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Это делает вычислительная система.
Нет, это делает программа либо во время исполнения для динамической памяти, либо во время загрузки кода программы в ОП для статической памяти, вычислительная система только лишь предоставляет ресурсы для выполнения программного кода - память и процессорное время.
Цитата Сообщение от IGPIGP Посмотреть сообщение
Принято считать, что такое значение не является результатом инициализации и является неопределённым.
технически немного не так, поскольку указатель это по сути не данные, а метаданные (как бы данные о данных) то он считается неопределенным пока не определены значения в области памяти по этому указателю, по настоящему неопределенным указателем указателем может быть тот самый nullptr.
1
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
01.03.2020, 11:24
Цитата Сообщение от R_U_S_V Посмотреть сообщение
Я объявление и инициализацию различаю
int a; // объявляем
a=1; // инициализируем
На самом деле есть объявление, инициализация и определение.
C++
1
2
3
4
int a; //объявляем. в какой-то ситуации тут может быть и неявная инициализация(а может и не быть)
a = 1; //определяем
 
int b = 2; //объявление и явная инициализация
Для классов эта разница будет более существенна(нужно понимать, где вызывается конструктор, и какой именно, а где операция присваивания).

Цитата Сообщение от Annemesski Посмотреть сообщение
cout << *ptr_a << endl; // выведет мусор
Если в ptr_a изначально попал 0, тут будет не мусор, а вылет(попытка обратиться к несуществующему адресу).
2
 Аватар для Annemesski
2674 / 1336 / 480
Регистрация: 08.11.2016
Сообщений: 3,692
01.03.2020, 11:31
Цитата Сообщение от R_U_S_V Посмотреть сообщение
Ну в целом то я понял, что лучше сразу инициализировать!
Это исключительно вопрос стиля, хорошим стилем считается определение переменной сразу, как только это становится возможным, при этом нередки случаи когда в момент объявления переменной еще неизвестно какое значение ей нужно присвоить.

Добавлено через 3 минуты
Цитата Сообщение от elenayagubova Посмотреть сообщение
Если в ptr_a изначально попал 0, тут будет не мусор, а вылет
Как это? Выведет 0, чему тут вылетать?
1
337 / 237 / 103
Регистрация: 26.03.2019
Сообщений: 407
01.03.2020, 11:36
Цитата Сообщение от Annemesski Посмотреть сообщение
Как это? Выведет 0, чему тут вылетать?
Вывод самого указателя выведет 0, а вот обращение по адресу не пройдет.
https://rextester.com/TRYR40211
0
 Аватар для Annemesski
2674 / 1336 / 480
Регистрация: 08.11.2016
Сообщений: 3,692
01.03.2020, 11:50
Цитата Сообщение от elenayagubova Посмотреть сообщение
Вывод самого указателя выведет 0, а вот обращение по адресу не пройдет.
Видимо зависит от компилятора
C++
1
2
int *ptr = nullptr;
cout << ptr << endl << *ptr << endl;
Вот так да, точно вылетит,
Цитата Сообщение от elenayagubova Посмотреть сообщение
https://rextester.com/TRYR40211
тут происходит именно это, видимо g++ 5.4.0 по умолчанию присваивает указателям nullptr и выделяет память только в момент определения. Там же, по вашей ссылке, для clang этот код работает без вылетов.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
01.03.2020, 11:53
Цитата Сообщение от Annemesski Посмотреть сообщение
Нет, это делает программа либо во время исполнения для динамической памяти, либо во время загрузки кода программы в ОП для статической памяти, вычислительная система только лишь предоставляет ресурсы для выполнения программного кода - память и процессорное время.
Нет. Без компьютера оно не бывает. Вы писаои что переменная сама не инициализируется. Это глубоко:
Цитата Сообщение от Annemesski Посмотреть сообщение
Переменная тоже не инициализируется сама.
И это с той мерой условности с которой принято говорить - ерунда.
Цитата Сообщение от Annemesski Посмотреть сообщение
Я писал именно в контексте ветки форума, то бишь про С++, в каком-нибудь паскале переменные инициализируются, по умолчанию
Почитайте про инициаплизаию по умолчанию в С++.
Цитата Сообщение от Annemesski Посмотреть сообщение
технически немного не так, поскольку указатель это по сути не данные, а метаданные (как бы данные о данных) то он считается неопределенным пока не определены значения в области памяти по этому указателю
Это вы откуда берёте? Я спрашиваю потому, что кучно оно у вас как-то ложится всё.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
01.03.2020, 11:53
Помогаю со студенческими работами здесь

Создать две переменных, ввести их с клавиатуры. Вывести строки: имя переменной - адрес переменной - значение п
Создать две переменных, ввести их с клавиатуры. Вывести строки: имя переменной - адрес переменной - значение переменной.

Указатели в с++ указывают только на адрес?
Например указатель int *p; Он может инициализироваться только адресом?(и ничем другим) например *p=&amp;s

Указатели и ссылки. Как сохранить адрес?
Небольшая путаница с указателями и ссылками. Допустим,есть некий указатель p1, который указывает на экземпляр класса a1 в динамической...

Указатели в переменной!!!
Указатели в переменной используються только для просмотра адреса? int *a;

взять адрес переменной
если &amp; стоит перед переменной, то это читается как - &quot; взять адрес этой переменной&quot; а если он стоит после ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Программный контроль заполнения реквизита табличной части документа
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: реализовать контроль заполнения реквизита табличной части. . .
wmic не является внутренней или внешней командой
Maks 02.04.2026
Решение: DISM / Online / Add-Capability / CapabilityName:WMIC~~~~ Отсюда: https:/ / winitpro. ru/ index. php/ 2025/ 02/ 14/ komanda-wmic-ne-naydena/
Программная установка даты и запрет ее изменения
Maks 02.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: при создании документов установить период списания автоматически. . .
Вывод данных в справочнике через динамический список
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru