Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Хлам 
V
    Опции темы
Hagrael
Дата 12.8.2011, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Здравствуйте. В учебнике по WinAPI от Петзолда (кстати, замечательный учебник!) код тела оконной процедуры приведен в подобном виде:
Код

HDC hdc;
PAINTSTRUCT ps;
RECT rect;

switch (iMsg) {

    case WM_CREATE:
        ... // переменные не используются
        return 0;

    case WM_PAINT:
        ... // переменные используются
        return 0;

}


Но ведь данный код при каждом вызове оконной процедуры (а их ведь в приличных программах совсем немало!) будет создавать переменные, причем не простые переменные, а структуры! Это же жуткая задержка! Почему бы не делать так:
Код

switch (iMsg) {

    case WM_CREATE: {
        ... // переменные? какие переменные?
        return 0;
    }

    case WM_PAINT: {
        HDC hdc;
        PAINTSTRUCT ps;
        RECT rect;
        ... // переменные есть и используются
        return 0;
    }

}

И почему компилятор ругается на такую запись:
Код

switch (var) {

    case 1:
        int a = 10;
        break;

    case 2:
        int b = 10; // про эту переменную он ничего не говорит!
        break;

}

т. е. на запись без фигурных скобок? Говорит:
error: jump to case label
error:   crosses initialization of 'int a'

Заранее благодарен.
PM MAIL   Вверх
vedr
Дата 12.8.2011, 15:38 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Оконная процедура вызывается когда ОС кидает приложению сообщения. Ну например, приходит десяток сообщений в секунду, это совсем немного, а структуры - элементарные (несколько POD - типов). На саму перерисовку окна тратится несравнимо больше времени. 

скорее всего он видит единичку в 10 и хочет перейти на case 1
сделайте так:
Код

switch (var) {

    case 1:
   {
        int a = 10;
        break;
   }

    case 2:
    {
        int b = 10; // про эту переменную он ничего не говорит!
        break;
    }

}

PM MAIL   Вверх
asmdzen
Дата 12.8.2011, 16:01 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата



**


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

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



Цитата(Hagrael @  12.8.2011,  15:09 Найти цитируемый пост)
структуры! Это же жуткая задержка!


sub esp, любое число байт -> жуткая задержка  smile 

в stwitch'е насколько мне известно нельзя объявлять переменные.
PM MAIL   Вверх
Cheloveck
Дата 12.8.2011, 16:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Правильно делать так
Код

switch (iMsg) {
    case WM_CREATE:
        return OnWMCreated(/*...*/);
    case WM_PAINT:
        return OnWMPaint(/*...*/);
}


Цитата(Hagrael @  12.8.2011,  15:09 Найти цитируемый пост)
почему компилятор ругается на такую запись

Объявление переменных должно быть в блоке кода. Создай его в кейсе и будет тебе счастье
Код

switch (var) {
    case 1:
        {
            int a = 10;
        }
        break;
    case 2:
        {
            int b = 10; // про эту переменную он ничего не говорит! // потому, что она в последнем кейсе свитча, видимо
        }
        break;
}



--------------------
user posted image
PM Jabber   Вверх
spyswamp
Дата 12.8.2011, 16:39 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Cheloveck, да, в каждом кейсе нужен свой скоп, чтобы можно было объявлять переменные. smile Странно только, что автор не понял это из сообщения компилятора.


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
Hagrael
Дата 12.8.2011, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Не пойму, почему авторы языка запретили создавать в case-ах без блоков переменные?

Цитата(Cheloveck @  12.8.2011,  16:09 Найти цитируемый пост)
Правильно делать так

В принципе, логично, в большой программе все в одной функции обрабатывать как-то неправильно smile
PM MAIL   Вверх
spyswamp
Дата 12.8.2011, 21:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Hagrael, ну, начнем с того, что это оператор... http://www.cyberguru.ru/programming/cpp/cp...way-page61.html


--------------------
- why you call it beta?
- cuz it's betta then nothin'
PM MAIL   Вверх
Hagrael
Дата 13.8.2011, 07:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Но если можно создать переменную, а после ее инициализировать, то почему же нельзя создать и инициализировать переменную одновременно?
PM MAIL   Вверх
Cheloveck
Дата 13.8.2011, 13:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Hagrael, потому что время жизни этой переменной будет не определено.


--------------------
user posted image
PM Jabber   Вверх
Hagrael
  Дата 13.8.2011, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Cheloveck, я не улавливаю связь между тем, инициализировать переменную сразу или нет, и временем ее жизни 
PM MAIL   Вверх
volatile
Дата 13.8.2011, 14:47 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

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



Hagrael, рассмотрим такой вариант
Код

int main ()
{
   goto label;
   int a = 2;
label:
   std::cout << a;
}

Здесь идет обращение к "а", без ее создания, так как создание (и иниц-ия) находится в коде который не выполняется.
Чтоб избежать такого поведения, компилятор не будет компилировать такой код, где переменные могут быть использованы без создания.

Так вот, switch - это по сути тот же самый goto, только оформлен по другому.

Стоит-ли продолжать дальше ... ?


PM MAIL   Вверх
Hagrael
Дата 13.8.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Понятно. Значит, компилятор самостоятельно не в состоянии разделить процесс создания переменной и присвоения ей значения. Но отсюда вытекает новый вопрос: не уже ли инициализация в корне отличается от последовательного создания переменной и ее заполнения?
PM MAIL   Вверх
Cheloveck
Дата 13.8.2011, 15:10 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Hagrael, C++ поддерживает инициализацию при объявлении и поощряет это. Но объявление переменной в switch невозможно без создания блока кода. Два или более кейсов switch будут выполняться подряд, если не будет явного указания на выход из оператора. По этой причине, компилятор не может догадаться о времени жизни переменной. Ты можешь создать в двух кейсах две переменные с одним именем. Компилятор не сможет их разрешить, если break указан не будет.

Добавлено через 1 минуту и 46 секунд
Код

switch(number)
{
case 0:
    int x = 100;
case 1:
    int x = 200; // ошибка компиляции. переменная x уже объявлена.
}


Добавлено через 4 минуты и 47 секунд
http://codepad.org/eGMeXzmn


--------------------
user posted image
PM Jabber   Вверх
Hagrael
Дата 13.8.2011, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В общем, понятно.
PM MAIL   Вверх
xvr
Дата 15.8.2011, 13:51 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Hagrael @  13.8.2011,  14:57 Найти цитируемый пост)
не уже ли инициализация в корне отличается от последовательного создания переменной и ее заполнения? 

В общем случае - да. Особенно это заметно для экземпляров объектов и ссылок.
Код

int a;
int &b=a; // Инициализация - 'привязка' b к переменной a
b=a; // Присваивание в то, к чему 'привязана' b, текущего значения переменной a


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




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


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

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