Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ox, эти указатели!!! Как это понять!!! 
:(
    Опции темы
My_Pioner
Дата 12.12.2004, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 12.12.2004

Репутация: нет
Всего: нет



Здесь я хочу привести кусочек кода, а от вас, уважаемые хотелось бы услышать соображения касательно результатов выполнения этого кода. Можно к примеру рассмотреть такой чуть более сложный код: Самое интересное в этом коде то какие результаты он выдает в обоих режимах работы компилятора Visual C++.NET.
Код

void Cproject001Dlg::OnBnClickedButton1()
{  
int my_int_1 = 11;
int my_int_2 = 30;
int my_int_3 = 430;
int *my_int_p_array[3];
my_int_p_array[0]= &my_int_1;
my_int_p_array[1]= &my_int_2;
my_int_p_array[2]= &my_int_3;
m_edit_1 = (int)my_int_p_array[0];  //   Edit Control Здесь все правильно - значение адреса
m_edit_2 = (int)my_int_p_array[1];  //   Edit Control А вот здесь уже выдает значение содержащееся по адрессу определенным указателем, тоесть 30. А это противоречит правилам синтаксиса языка С++.  иными словами два выражение, такие как  m_edit_1 = (int)my_int_p_array[0] и m_edit_1 = *my_int_p_array[0] выдают одинаковые результаты, хотя в первом случае я пытаюся получить адресс переменной(значение указателя), а во втором значение переменной определенной по данному указателю  
m_edit_3 = (int)my_int_p_array[2];  //   Edit Control
UpdateData(0);
}

или такой чуть попроще:
Код

void Cproject001Dlg::OnBnClickedButton1()
{  
int my_int_1 = 11;
int my_int_2 = 30;
int my_int_3 = 430;
m_edit_1 = (int)&my_int_1;  //   Edit Control
m_edit_2 = (int)&my_int_2;  //   Edit Control
m_edit_3 = (int)&imy_int_3;  //   Edit Control
UpdateData(0);
}


Visual C++ выдает весьма интересные результаты, которые я никак не в состоянии объяснить, причем результаты слегка могут различаться для режимов отладки и реализации. Хотелось бы поинтересоваться вашими соображениями по этому поводу. Если этот факт работы компилятора кого нибудь заинтересует, я могу привести еще боллее интересные примеры. Ход рассуждений сводится в конечном итоге к тому, что в оптимизационном режиме работы компилятора для определенных операций результат предыдущих операций зависит от операций последующих. Вот пример:
Код

void Cproject001Dlg::OnBnClickedOk()
{
   int my_int_1 = 11;
   int my_int_2 = 30;
   int my_int = (int)&my_int_1-(int)&my_int_2; //Здесь должно содержать расстояние в байтах между переменными
   m_edit_1 = my_int; // Резулат 4
   m_edit_2 = *(int*)((int)&my_int_2+my_int);//Результат:11 <-- * --> Если эту строку коментировать, то my_int будет уже -4 для данного случая и m_edit_3 не как ни получишь значение переменной my_int_2 а если  в следующем выражении менять значение my_int на какое нибудь другое, то my_int вообдще будет содержать черти что!!! Клево Да
  m_edit_3 = *(int*)((int)&my_int_1-my_int); //Результат:30
 UpdateData(0);
}


Это сообщение отредактировал(а) My_Pioner - 13.12.2004, 15:39
PM MAIL   Вверх
NiJazz
Дата 12.12.2004, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


Профиль
Группа: Экс. модератор
Сообщений: 2286
Регистрация: 10.8.2003
Где: Москва

Репутация: 2
Всего: 23



Код

void Cproject001Dlg::OnBnClickedButton1()
{  
   int my_int_1 = 11;
   int my_int_2 = 30;
   int my_int_3 = 430;
   int my_int_p_array[3];
   my_int_p_array[0]= my_int_1;
   my_int_p_array[1]= my_int_2;
   my_int_p_array[2]= my_int_3;
   m_edit_1 = (int)my_int_p_array[0];  //   Edit Control
   m_edit_2 = (int)my_int_p_array[1];  //   Edit Control
   m_edit_3 = (int)my_int_p_array[2];  //   Edit Control
   UpdateData(0);
}

Что-то с указателями там совсем наглючено. Так вот должно работать.
Добавлено @ 20:34
объявить массив можно двумя способами:
1. int array[3];
2. int* array;
Во втором способе нужно выделять память, чтобы с массивом можно было работать.
Код

array = (int)malloc(3*sizeof(int)); // выделяем 3*sizeof(int) байтов - для трёх элементов
free(array); // освобождаем память

PM MAIL   Вверх
My_Pioner
Дата 13.12.2004, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 5
Регистрация: 12.12.2004

Репутация: нет
Всего: нет



Вообщем то. в коде нет проблем относительно синтаксиса, здесь есть проблемки относительно того как этот синтаксис воспринимает компилятор Visual C++.NET да еще в режиме Release. Так (int)&int my_int_1 выдает правильный результат, то-есть значение адреса и только в том случае если m_edit_1 = (int)&int my_int_1 является первым выражением из группы выражений выводящих значения в текствое поле; если же поменять например местами m_edit_1 = (int)&int my_int_1 и m_edit_2 = (int)&int my_int_2 то в m_edit_1 помещается значение по адресу, тоесть 11, а совсем не адресс числа, хотя в данном случае приведена операция получения адреса. Чудеса да и только!!!

Это сообщение отредактировал(а) My_Pioner - 13.12.2004, 14:18
PM MAIL   Вверх
Mad
Дата 13.12.2004, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 2
Всего: 19



А лучше так smile
Код

void Cproject001Dlg::OnBnClickedButton1()
{  
  m_edit_1 =11;  //   Edit Control
  m_edit_2 = 30;  //   Edit Control
  m_edit_3 = 430;  //   Edit Control
  UpdateData(0);
}



--------------------
user posted image
PM MAIL   Вверх
threef
Дата 31.10.2005, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 375
Регистрация: 27.10.2005
Где: Запорожье

Репутация: 1
Всего: 10



В первом блоке кода:
создаешь массив указателей(стековый)
Записываешь адреса переменных(int) в этот массив
в разных editbox(ах) получаешь разные адреса переменных. В связи с разными режимами компиляции имеешь разный обьем кода и ,соответственно, разные адреса. Ничегошеньки непонятного.

Во втором блоке кода просто заносишь адреса переменных в editbox(ы). Аналогично предыдущему.


Третий блок кода более интересен. Компилятор складывает переменные в обратном порядке в стек.Поэтому адрес последней переменной меньше адреса первой ( Отладочный режим ). Можно было не изголятся,приводя адреса к int, они и так вычитаются по синтаксису языка( складывать нельзя) . Прибавив положительное число(sizeof int) ко второму адресу получаешь адрес первой переменной( он больше), отняв то же от первого получаешь адрес второй переменной.
Код

int my_int_1 = 11;
int my_int_2 = 30;
int my_int_3 = 430;

cout<< (int)&my_int_1;  //   адрес
  cout<<'\n';
  cout<< (int)&my_int_2;  //   адрес
  cout<<'\n';
  cout<< (int)&my_int_3;  //  адрес
  cout<<'\n';
//  if  _DEBUG_
cout<< *(int*)&my_int_1;  //   значение 1
  cout<<'\n';
  cout<< *(int*)(&my_int_2+sizeof int);  // значение 1
  cout<<'\n';
  cout<< *(int*)(&my_int_2-sizeof int);  // значение 3
  cout<<'\n';
//  if  _RELEASE_
cout<< *(int*)&my_int_1;  //   значение 1
  cout<<'\n';
  cout<< *(int*)(&my_int_2+sizeof int);  // значение 3
  cout<<'\n';
  cout<< *(int*)(&my_int_2-sizeof int);  // значение 1
  cout<<'\n';



Это сообщение отредактировал(а) threef - 31.10.2005, 16:27
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0474 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.