С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
1 / 1 / 1
Регистрация: 19.07.2009
Сообщений: 54

Как работает приведение типов

14.08.2016, 20:26. Показов 913. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
#include <stdio.h>
 
int main(void)
{
    printf("%d", (int*)3 + 4);
    return 0;
}
То что выведется 19 проверить можно.
Но умные люди разъясните, как это происходит и почему ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.08.2016, 20:26
Ответы с готовыми решениями:

Приведение типов: как работает reinterpret_cast<>() ?
Хочу разобраться до конца с приведением типов а именно интересует reinterpret_cast&lt;&gt;(), хотя бы в общих чертах логика этой функции, на...

Неправильное приведение типов или как?
Короче вот код void CMyDialog::OnBnClickedButtonEdit() { double number ; CString t; number= (t_f+t_o+t_m+t_d+t_b+t_i+t_s)/7; ...

Строгая типизация. Только ручное приведение типов. Как не смешать яблоки с грушами?
Приветствую Вас, уважаемые форумчане! Вопрос, предполагаю, элементарный для опытных программистов. Подскажите пожалуйста каким...

6
1615 / 1181 / 552
Регистрация: 08.01.2012
Сообщений: 4,559
14.08.2016, 20:34
3+4*sizeof(int)
0
Хитрая блондиночка $)
 Аватар для Hikari
1472 / 988 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
14.08.2016, 20:45
Цитата Сообщение от Omnio Посмотреть сообщение
(int*)3
Это операция с расчетом смещения указателей.
Как я понимаю: (int*)3 - это расчет кол-ва ячеек памяти по 4 байта (3+1)*4=16, где +1 - потому что начало расчета с нуля
И плюс еще 4 - дает 20. 20 это байт смещения от указателя (int *)0. А учитывая отсчет не с единицы а с нуля получается 19, ибо 20, это если считать начало указателя с единицы.
Наверное не очень понятно описала?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.08.2016, 20:47
Цитата Сообщение от Omnio Посмотреть сообщение
как это происходит и почему ?
вот здесь:
C++
1
(int*)3
вы сообщаете компилятору, что цыферка 3 - это адрес памяти,
где сидит объект типа int.

далее:
C++
1
(int*)3 + 4
к полученному адресу прибавляется 4.
получается адрес, который смещен относительно исходного на 4ре штуки объектов типа int

размер одного объекта int в данном случае был 4.

от адреса 3 смещаемся на 4ре объекта каждый из которых весит 4.
то есть на 16 байт.

16 + 3 = 19.

таким образом, 19 - это адрес,
который получился в результате выражения:
C++
1
(int*)3 + 4
далее:
C++
1
printf("%d", (int*)3 + 4);
здесь функции printf сообщается,
что переданный адрес 19 нужно вывести как обычную циферку.

её мы в итоге и видим в результате.
0
 Аватар для meJevin
161 / 153 / 92
Регистрация: 18.11.2015
Сообщений: 677
14.08.2016, 21:11
Блин, пока я писал свое супер-деревенское объяснение, хогги опередил с более правильным. Но ладно, не пропадать же виртуальным буковкам-циферкам, вот:



Кликните здесь для просмотра всего текста
Начнем с того, что запись (int*)3 - просто даст нам указатель на int со значением 3

Заметь, что не int со значением 3, а указатель на int, т.е. нам программа даст адрес.

Мы получим 00000000 00000003 в консоли, если напишем std::cout << (int*)3 << std::endl;. Это верно, представление тройки в шестнадцатеричной системе счисления (а она стоит по умолчанию при выводе адресов) так и запишется.

Далее, мы прибавляем к нашему адресу 4, т.е. наша запись приобретает вид (int*)3 + 4. И тут-то самое вкусное.

Если мы попытаемся вывести в консоль std::cout << (int*)3 + 4 << std::endl;, то получим 00000000 000000013. Но почему? Мы же всего лишь 4 прибавили к 3, мы должны были получить 7, не так ли? Нет, не так.

Давай вспомним, что мы работаем с адресами и указателями, а с ними простая арифметика работает не так, как может подумать неопытный программист. Дело в том, что когда мы говорим программе прибавить, например 4, к указателю, то программа не просто увеличит адрес, который держит наш указатель на 4, а "перепрыгнет" через 4 переменных типа, на который указывает указатель. Т.е. программа возьмет размер (в байтах) типа переменной, на которую указывает указатель, и прибавит к адресу указателя столько раз, сколько мы сказали ей "прыгнуть".


С полученными знаниями, мы можем сами посчитать, какой будет адрес, если мы пишем (int*)3 + 4. Итак, значение (в шестнадцатеричной системе счисления) (int*)3 мы уже знаем, будет 00000000 00000003. Далее, мы говорим к текущему адресу прибавить 4. Используя вышеописанный способ вычисления адреса после перемещения указателя на N раз, мы можем вычислить будущий адрес. Так как программа "перепрыгивает" N раз через размер типа, на которую указывает указатель, который в нашем случае int, мы должны перепрыгнуть через 4 int переменных. Таким образом, мы перепрыгнем через 16 (т.к. размер int 4 байта) байт и окажемся на 00000000 000000013. И ответ верный, ведь прибавив 16 к имеющимся 3 мы получим 19, что записывается, как 00000000 000000013 в шестнадцатеричной системе счисления.


Вот и все
0
-30 / 27 / 1
Регистрация: 14.03.2015
Сообщений: 807
14.08.2016, 22:49
meJevin, даже не думаю тебе льстить, но скажи какую книгу по С++ ты считаешь правильной
0
 Аватар для meJevin
161 / 153 / 92
Регистрация: 18.11.2015
Сообщений: 677
14.08.2016, 23:23
gogaloh, не могу ответить на этот вопрос. Я еще не достаточно владею С++, чтобы книги правильными или неправильными назначать
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.08.2016, 23:23
Помогаю со студенческими работами здесь

Приведение типов
Как компилятор заставить адекватней приводить типы? (VS2012) Например: int a=-1; unsigned int b=5; if(a&gt;b){...}//Условие...

Приведение типов в C++
Знающие люди, подскажите пожалуйста. В классе существует поле: const int static ID; Необходимо записать его в бинарный файл посредством...

Приведение типов
Привет всем! Компилятор выдает варнинг если сравниваются signed и unsigned значения.Допустим, код пересмотреть нельзя и изменить типы...

Приведение типов.
Столкнулся с задачей считывания данных из символьного массива с дальнейшим отбором из всего этого чисел и перезаписи их в массив типа...

Приведение типов
в GUI ни int str = static_convert&lt;int&gt;(Edit1-&gt;Text) ни int str = (int)Edit1-&gt;Text не приводит : E2034 Cannot convert...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru