Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 15.04.2017, 10:09   #1
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию Помогите пожалуйста разобраться с указателями?

Код:
#include <stdio.h>
#include <windows.h>
#include <conio.h>

int main(void)
{
    int ival = 1024;
    int *pint; // указатель на объект типа int
    pint = &ival; // pint получает значение адреса ival

    
    printf("pint %x, ival %x\n",pint,ival);
    return 0;
}
после запуска программы, получаю вывод на экран pint 94, ival 3357. Почему в переменной ival оказалось 3357, если я задавал изначально 1024, если даже это число вышло в 16сс, то должно быть 400
И второе почему pint равно 94, ведь оперативная память записывается через сегмент и смещение например 2345:3456 что обозначает это 94 и в каком сегменте памяти оно находится. Код пишу во FreeDos в BorlandC++3.1 (не эмулятор, чистый FreeDos 1.2 на винте, адреса памяти по идее должны выходить реальные)

______________________
Используйте тег [CODE] (кнопка с решеткой # в форме сообщения) при вставке кода на форум.

Последний раз редактировалось Alex11223; 15.04.2017 в 12:23.
седьмой вне форума Ответить с цитированием
Старый 15.04.2017, 10:32   #2
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Черт его знает. В 16 битном режиме была хитрая арифметика указателей, там, помнится, были короткие указатели (которые только смещение, в текущем сегменте) и полные длинные (которые - реальный линейный адрес 32 бита).
Как и что у вас тут работает не понятно, потому что, давно забыто

На линуксе запуск как ожидался:

g++ tst1.cpp
./a.out
pint a5663034, ival 400


вообще типы проверьте, х ожидает unsigned int, а вы ему int. Тут еще накладывается битовость, на досе инт может быть 16 бит.

Последний раз редактировалось alexzk; 15.04.2017 в 10:37.
alexzk вне форума Ответить с цитированием
Старый 15.04.2017, 12:34   #3
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Код:
printf("pint %x\n",pint);
printf("ival %x\n",ival);
после разделения строк значение ival вышло нормальное 400, а pint 94 оказалось смещением в адресе, это получилось посмотреть в дебуггере, а вот сегмент 5959, в программе вообще не вышел. Как его можно вывести прямо из программы? И как на этом форуме можно поставить человеку, который помог разобраться плюс или спасибо?
седьмой вне форума Ответить с цитированием
Старый 15.04.2017, 12:36   #4
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
На линуксе запуск как ожидался:
линукс это все хорошо, но нужен чистый дос. А на unsigned ругается , говорит что не может сконвертировать указатель unsigned в int... а ну да указатель надо тоже в этот тип перевести наверно.

Последний раз редактировалось седьмой; 15.04.2017 в 12:40.
седьмой вне форума Ответить с цитированием
Старый 15.04.2017, 12:51   #5
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от седьмой Посмотреть сообщение
линукс это все хорошо, но нужен чистый дос. А на unsigned ругается , говорит что не может сконвертировать указатель unsigned в int... а ну да указатель надо тоже в этот тип перевести наверно.
Да, нужно..
...насчет сегмента, если я верно помню, там в настройке проекта С++ есть "segmentation model", вот оно как раз и задает все с указателями - сколько вам памяти будет доступно и в какой модели(сегментированая или флэт). Но я уже лет 15 этого чуда не видел, могу помнить не верно.
alexzk вне форума Ответить с цитированием
Старый 15.04.2017, 12:58   #6
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от седьмой Посмотреть сообщение
Код:
printf("pint %x\n",pint);
printf("ival %x\n",ival);
после разделения строк значение ival вышло нормальное 400, а pint 94 оказалось смещением в адресе, это получилось посмотреть в дебуггере, а вот сегмент 5959, в программе вообще не вышел. Как его можно вывести прямо из программы? И как на этом форуме можно поставить человеку, который помог разобраться плюс или спасибо?
А я понял почему так, потому что исходный вариант ( в 1 строку) ожидает блок памяти 4 байта, 2 unsigned int, которые в режиме дос = 16 бит.
Но, указатель, скорее всего у вас не 16 бит, как ожидалось. При разделении, все по прежнему работает не совсем верно Потому что, печатает только 16 бит от указателя, остальные в пролете. Скорее всего, указатель у вас там 2+2 = сегмент+смещение, вот их первый принт и печатал (и соотв, игнорировал ival)

Последний раз редактировалось alexzk; 15.04.2017 в 13:02.
alexzk вне форума Ответить с цитированием
Старый 17.04.2017, 07:07   #7
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
лет 15 этого чуда не видел
я тоже этого чуда не видел давно, пока не пришлось переделывать под себя драйвер платы для согласования интерфейсов, заказчик предложил делать под досом из за достаточно малых временных интервалов, одно дело переделать драйвер на с++ под досом для платы на микроконтроллере и другое полноценный аппаратный драйвер по виндой, так в руках оказался проект под досом. Сейчас надо его не то что писать, а кое что удалить, кое что изменить, кое что проверить.
седьмой вне форума Ответить с цитированием
Старый 17.04.2017, 09:13   #8
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Спасибо всем за помощь. Вы оказались правы, взял не тот шаблон данных при выводе printf, нужно было брать формат указателя %p, а не числа, сейчас выходит все верно "3358:037C". Теперь остался совсем простой вопрос просто чисто формально, разделить отдельно сегмент и смещение нужно уже самому? Команды такой наверно нет на с++, можно наверно чисто через split или нечто подобное?
седьмой вне форума Ответить с цитированием
Старый 17.04.2017, 09:18   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Цитата:
Сообщение от седьмой Посмотреть сообщение
разделить отдельно сегмент и смещение нужно уже самому
Поищите есть в вашем компиляторе макросы FP_SEG и FP_OFF.
waleri вне форума Ответить с цитированием
Старый 17.04.2017, 10:40   #10
седьмой
Форумчанин
 
Регистрация: 17.07.2012
Сообщений: 140
По умолчанию

Цитата:
Сообщение от waleri Посмотреть сообщение
Поищите есть в вашем компиляторе макросы FP_SEG и FP_OFF.
Спасибо, попробую, а пока можно еще вопрос? Почему при запуске из разных оболочек изменяется сегмент памяти при запуске программы? И будет ли он один и тот же если его запускать всегда из одной программы, если количество программ на компьютере всегда одинаковое и комп под досом.
Изображения
Тип файла: jpg img3.JPG (8.6 Кб, 118 просмотров)
седьмой вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
помогите разобраться с указателями С++ sasha_14-88 Общие вопросы C/C++ 1 07.12.2014 10:39
Помогите разобраться с указателями igole Общие вопросы C/C++ 1 28.04.2013 16:47
Не могу разобраться с указателями FRATER1234 Общие вопросы C/C++ 7 13.10.2011 11:23
Товарищи, помогите разобраться с указателями scibern Общие вопросы C/C++ 7 11.01.2009 12:28
Помогите пожалуйста с динамической памятью и указателями Riddick2013 Помощь студентам 1 19.12.2007 14:41