Форум программистов, компьютерный форум CyberForum.ru

Обьявление локальных переменных - C++

Восстановить пароль Регистрация
 
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 17:07     Обьявление локальных переменных #1
Добрый день. В какой последовательности объявляются локальные переменные в функции? Если вызвать return раньше обьявления, будет ли последующая переменная обьявлена? и почему нельзя объявлять переменные в конструкциях if или switch?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Leomana
58 / 58 / 5
Регистрация: 29.06.2012
Сообщений: 188
16.08.2012, 17:20     Обьявление локальных переменных #2
в любой последовательности.
если вызвать return , то последующий код не будет выполнятся => и переменные не объявятся.
переменные можно объявлять в if и switch, но они будут локальны в пределах этой конструкции.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 17:30  [ТС]     Обьявление локальных переменных #3
Цитата Сообщение от Leomana Посмотреть сообщение
в любой последовательности.
если вызвать return , то последующий код не будет выполнятся => и переменные не объявятся.
переменные можно объявлять в if и switch, но они будут локальны в пределах этой конструкции.
Дествительно переменные обьявляются, но почему-то в switch не объявляется(лся) класс, компилятор писал что объявление пропущено из за конструкции switch
Leomana
58 / 58 / 5
Регистрация: 29.06.2012
Сообщений: 188
16.08.2012, 17:53     Обьявление локальных переменных #4
Цитата Сообщение от h3mbr0 Посмотреть сообщение
Дествительно переменные обьявляются, но почему-то в switch не объявляется(лся) класс, компилятор писал что объявление пропущено из за конструкции switch
ну не знаю.. тут надо смотреть конкретный код
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 18:07  [ТС]     Обьявление локальных переменных #5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <conio>
#include <iostream>
#
using namespace std;
 
class Foo
{
public:
    Foo()
    {
        cout << "Hello\n";
    }
};
 
int main()
{
    char c;
    while(c = getch())
    {
        switch(c)
        {
        case '1': Foo Bar; break;
        }
    }   
}
error C2360: пропуск инициализации "Bar" из-за метки "case"
Leomana
58 / 58 / 5
Регистрация: 29.06.2012
Сообщений: 188
16.08.2012, 18:19     Обьявление локальных переменных #6
в моем MVS2010 ошибки нет
а что у Вас за компилятор?
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 22:59  [ТС]     Обьявление локальных переменных #7
MVS 2012

Добавлено через 5 минут
Прошу прощения, такой код срабатывает, а вот следующий - нет:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <conio.h>
#include <iostream>
#
using namespace std;
 
class Foo
{
public:
    Foo()
    {
        cout << "Hello\n";
    }
};
 
int main()
{
    char c;
    while(c = getch())
    {
        switch(c)
        {
        case '1': Foo Bar; break;
        case '2': Foo FooBar;
        }
    }   
}
error C2360: пропуск инициализации "Bar" из-за метки "case"
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
16.08.2012, 23:02     Обьявление локальных переменных #8
Можно этот код с Foo в отдельный блок заключить.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 23:09  [ТС]     Обьявление локальных переменных #9
Цитата Сообщение от Somebody Посмотреть сообщение
Можно этот код с Foo в отдельный блок заключить.
Так работает, но ведь получится что он уничтожется после выхода из блока... а что бы он не уничтожался можно сделать?
4iFF
 Аватар для 4iFF
19 / 19 / 1
Регистрация: 06.07.2012
Сообщений: 88
16.08.2012, 23:24     Обьявление локальных переменных #10
h3mbr0, зачем в 3 строке шарп (#)?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
16.08.2012, 23:34     Обьявление локальных переменных #11
Цитата Сообщение от h3mbr0 Посмотреть сообщение
Так работает, но ведь получится что он уничтожется после выхода из блока... а что бы он не уничтожался можно сделать?
Объявить вне switch. Засунув сам switch в блок. (Естессно, при этом для каждой итерации while будут новые переменные.)

А почему нельзя объявлять переменные в блоках if и switch — потому что у них синтаксис такой. В блоке if точно в скобках пишется не "обычное" выражение. Внутри switch сейчас попробую найти.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
16.08.2012, 23:52  [ТС]     Обьявление локальных переменных #12
Цитата Сообщение от 4iFF Посмотреть сообщение
h3mbr0, зачем в 3 строке шарп (#)?
Привычка.. в начале инклуды, дефайны и неймспейсы разделяю шарпом для наглядности
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Объявить вне switch. Засунув сам switch в блок. (Естессно, при этом для каждой итерации while будут новые переменные.)

А почему нельзя объявлять переменные в блоках if и switch — потому что у них синтаксис такой. В блоке if точно в скобках пишется не "обычное" выражение. Внутри switch сейчас попробую найти.
Можно по подробнее? не совсем понял о чем идет речь
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
17.08.2012, 00:04     Обьявление локальных переменных #13
Окей. Я посмотрел в стандарт. Это всё неправда про то, что нельзя объявлять.

После слова if или switch в скобках указывается условие (те же правила для условий switch, while и второго элемента for, но не для do-while). Условие — это или выражение (приводимое к bool), или объявление переменной. Если это выражение, то для выбора используется его значение. Если это объявление, то для выбора используется значение этой переменной. Переменная, объявляемая в этих скобках, является локальной для всего if или switch-оператора (то есть её нельзя переопределять). Если неясно, выражение это или объявление, оно считается объявлением.

То есть
вот это
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
 
int main()
{
  if (int x = 42) {
    std::cout << x;
  }
  else {
    std::cout << "NO";
  }
}
должно печатать 42.

Внутри switch можно объявлять переменные (равно как и в его условии, но только одну). Там обычные выражения со всеми вытекающими. Другое дело, что их инициализация зависит от того, на какой case мы прыгнем. То есть в
таком случае
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
int main()
{
  int c = 2;
  switch (c) {
  case 1:
    int x = 5;
    std::cout << x;
  case 2:
    int y = 6;
    std::cout << x + y;
    break;
  case 3:
    std::cout << 3;
  }
}
код для инициализации переменной x не будет выполнен и будет выведено чёрти что. Тот же gcc ругается на это как на ошибку, потому что это всё же серьёзный говнохитрокод, но ему можно заткнуть рот и получить свой undefined behavior, который должен быть по стандарту.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
17.08.2012, 00:07  [ТС]     Обьявление локальных переменных #14
Спасибо, стало понятнее, но все таки раз если окончить блок до его дальнейшего выполнения, скажем
C++
1
2
3
4
5
{
int a;
return 0;
int b
}
b в этом случае объявлена не будет как я понимаю, так почему тогда нельзя в switch объявлять ту переменную, которую я выберу? то есть остальные просто проигнорировать? в этом собственно и заключался мой вопрос)
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
17.08.2012, 00:19     Обьявление локальных переменных #15
Нет, формально она будет объявлена.
Такой код
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
 
int foo()
{
  return 42;
  int x = 2, y = 21;
  std::cout << x * y << " = ";
}
 
int main()
{
  std::cout << foo();
}
спокойно компилируется, хотя по понятным причинам выводит только 42, а не 42 = 42.

А почему нельзя объявлять то, что вы выберете... Вот смотрите, когда происходит выбор ветки switch? Во время исполнения программы. А когда происходит объявление переменной? При компиляции.

Объявить переменную при исполнении программы вы не можете (для этого потребуется тащить внутри программы целый компилятор Си++ и остальной фарш). Максимум можете её инициализировать динамически, во время выполнения программы.

Постарайтесь выразить нужные вам действия с помощью этой метафоры: при входе в switch у вас есть некая переменная, после выхода из switch она имеет значение, зависящее от условия, которое было передано в switch.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
17.08.2012, 00:28  [ТС]     Обьявление локальных переменных #16
Все, теперь понял, спасибо
Еще один маленький вопрос, нехочу создавать для нее отдельную тему.
Есть ли в c++ аналог
C++
1
case1..10:
То есть когда case срабатывает при значении от 1 до 10? именно не сравнением а такой конструкцией или оператором? пытался искать, но все что нашел на это форуме: предлагаеться сделать конструкцию
C++
1
2
3
case 1:
case 2:
case 3: //code
и т.д. что не очень приятно при 1..100
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
17.08.2012, 00:43     Обьявление локальных переменных #17
К сожалению, нету. Если это числа, то придётся воспользоваться if, строя вот такой паровоз из интервалов:
C++
1
2
3
4
5
6
7
8
9
10
if ((1 <= x) && (x <= 100)) {
  // case 1..100:
}
else if ((200 <= x) && (x <= 300)) {
  // case 200..300:
}
// else if <другие интервалы>
else {
  // default-ветка
}
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
17.08.2012, 01:06  [ТС]     Обьявление локальных переменных #18
//написал не подумав, вопрос исчерпан, спасибо за помощь
Максим1
2 / 2 / 0
Регистрация: 08.05.2012
Сообщений: 18
17.08.2012, 01:23     Обьявление локальных переменных #19
Возвращаясь к главной теме: чтобы решить проблему с инициализацией во время компиляции в switch'e, нужно все выражения после case'a заключать в фигурные скобки {}. Вот этот код работает

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <conio.h>
#include <iostream>
 
using namespace std;
 
class Foo
{
public:
    Foo()
    {
        cout << "Hello\n";
    }
};
 
int main()
{
    char c;
    while(c = getch())
    {
        switch(c)
        {
        case '1': {Foo Bar; break;}
        case '2': {Foo FooBar;}
        }
    }  
    return 0;
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.08.2012, 01:32     Обьявление локальных переменных
Еще ссылки по теме:

C++ Создание области определния для очистки временных локальных переменных
C++ Выделение и освобождение памяти для локальных переменных функций
Требуется обьявление C++

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

Или воспользуйтесь поиском по форуму:
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
17.08.2012, 01:32  [ТС]     Обьявление локальных переменных #20
Цитата Сообщение от Максим1 Посмотреть сообщение
Возвращаясь к главной теме: чтобы решить проблему с инициализацией во время компиляции в switch'e, нужно все выражения после case'a заключать в фигурные скобки {}. Вот этот код работает

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <conio.h>
#include <iostream>
 
using namespace std;
 
class Foo
{
public:
    Foo()
    {
        cout << "Hello\n";
    }
};
 
int main()
{
    char c;
    while(c = getch())
    {
        switch(c)
        {
        case '1': {Foo Bar; break;}
        case '2': {Foo FooBar;}
        }
    }  
    return 0;
}
Тут уже предлагали такой способ, но мне нужно было что бы после выхода из switch класс оставался, а таким способом он уничтожается сразу после switch
Yandex
Объявления
17.08.2012, 01:32     Обьявление локальных переменных
Ответ Создать тему
Опции темы

Текущее время: 03:36. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru