Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
2 / 2 / 1
Регистрация: 28.08.2013
Сообщений: 414
1

Почему нельзя подставлять переменные в выражения #if #else?

26.03.2014, 14:25. Показов 2648. Ответов 27
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
 
int main(void){
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
 
    char ch = getchar();
    return 0;
}
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.03.2014, 14:25
Ответы с готовыми решениями:

Почему в switch нельзя определять переменные?
int main() { setlocale(LC_ALL, &quot;Russian&quot;); int n; std::cout &lt;&lt; &quot;Введите число: &quot;;...

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

Почему нельзя использовать в операторе case переменные, которые определены как #define
Я не понимаю, почему Visual Studio ругается на строку с case в коде. Вроде все правильно. Если там...

Почему локальные переменные методов нельзя изменять в анонимных классах?
Почему Java защищает от изменения локальные переменные методов, когда пытаешься их изменить в...

27
27 / 27 / 10
Регистрация: 10.04.2013
Сообщений: 91
26.03.2014, 14:28 2
а, собственно, зачем # перед if и else?
0
2 / 2 / 1
Регистрация: 28.08.2013
Сообщений: 414
26.03.2014, 14:31  [ТС] 3
а, собственно, зачем # перед if и else?
смотрю как работает, читаю книгу, там написано то что я написал выше, мне интересно, посему
просто кто то пишет какую то программу, по ходу задает вопросы, а кто то читает книги и примеры "абстрактные"
конечно если я буду писать какую нить программу, я не буду где попало ставить #
0
101 / 101 / 39
Регистрация: 17.04.2011
Сообщений: 554
26.03.2014, 14:40 4
Директивы #if, #elif, #else и #endif (C/C++)http://msdn.microsoft.com/ru-r... hz0yd.aspx
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 14:41 5
Цитата Сообщение от gelior Посмотреть сообщение
а, собственно, зачем # перед if и else?
Затем, что это макрос условной компиляции.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
26.03.2014, 14:42 6
Zla9_Kolu4ka, зачитайтесь вот из этого источника: Препроцессорные директивы в C/C++ (#include, #define и прочее) .
А именно:
4.2. Директивы #if, #else, #elif, #endif

Синтаксис директивы "#if" очень простой и по большому счёту совпадает с операциями условного исполнения в языке. Как-то особенно на этом останавливаться не буду, просто покажу все варианты использования. Единственное, что нужно отметить - обязательно должен быть "#endif", потому как без него препроцессор не сможет понять, в каком месте заканчивается директива "#if"
C
1
2
3
#if <условие>
...
#endif
C
1
2
3
4
5
#if <условие>
...
#else
...
#endif
C
1
2
3
4
5
6
7
8
9
#if <условие>
...
#elif <условие>
...
#elif <условие>
...
#else
...
#endif
Что касается условия, то хочется ещё раз отметить, что препроцессирование делается отдельно от компиляции, а потому в условии директивы "#if" НЕ могут использоваться никакие переменные из программы. В условии могут использоваться только целочисленные константные значения (которые могут быть значениями других макросов). Над этими константами можно выполнять операции сравнения "==", "!=", "<", "<=", ">", ">=". В условии могут использоваться логические операции "&&", "||", "!", круглые скобки, а так же некая конструкция "defined <macro_name>", значение которой истинно, если макрос <macro_name> определён, в противном случае значение ложно. Препроцессорные "#if'ы", так же, как и языковые, могут быть вложены друг в друга. В строках с директивами можно использовать комментарии
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 14:46 7
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Единственное, что нужно отметить - обязательно должен быть "#endif", потому как без него препроцессор не сможет понять, в каком месте заканчивается директива "#if"
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
26.03.2014, 14:50 8
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
Нет. Третье, что необходимо отметить, что компиляция вообще не будет возможна при ошибках на этапе препроцессорной обработки, а без нее не имеет смысла говорить о поведении программы, так как код ее не будет сформирован правильно.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 14:54 9
Нет. Этот фактор не отличает от грубых синтаксических ошибок в обычных операторах, если написать, например,
C++
1
if )a>d)
вместо
C++
1
if (a>d)
, или помянуть не существующую переменную, или сравнить величины не сравнимых (для которых нет версии
C++
1
operator >
), то программы тоже не будет. Это общее, а конкретно условная компиляция от условного оператора отличается только двумя факторами.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
26.03.2014, 15:06 10
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
int a = 9;
предположу что a сделалась константой
а она известна на этапе компиляции

Добавлено через 2 минуты
попробуй вот так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
 
int main(void){
 
a+=100;
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
 
    char ch = getchar();
    return 0;
}
что будет?

Добавлено через 1 минуту
Цитата Сообщение от SatanaXIII Посмотреть сообщение
потому в условии директивы "#if" НЕ могут использоваться никакие переменные из программы.
так об чем ТС и спрашивает
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
Почему код работает, не должен же, потому что выражение стоящее после #if вычисляется на этапе компиляции, переменные подставлять нельзя??
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 15:06 11
Цитата Сообщение от ValeryS Посмотреть сообщение
предположу что a сделалась константой
а она известна на этапе компиляции
Константой она не стала, но на этапе компиляции стала известна за счёт инициализации не кодом самой программы, а загрузчиком, входящим в состав операционной системы, то есть не операция присваивания, а само стартовое значение стало частью исполняемого файла. Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
26.03.2014, 15:10 12
Цитата Сообщение от taras atavin Посмотреть сообщение
Константой она не стала,
разумеется нет, поскольку нет const
но для препроцессора наверное да, значение то известно, да и не используется больше нигде
(ключевое слово наверное, т.е я ни в чем не уверен)
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
об чем и речь
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 15:11 13
Кроме того, сама возможность изменить переменную означает, что делать так всё равно нельзя:
C++
1
2
3
4
5
6
7
int a=20;
a+=200;
#if a<100
std::cout<<"less"<<std::endl;
#enlse
std::cout<<"more"<<std::endl;
#endif
, хотя перед строкой #if a<100 a уже стала равна 220, но на этапе компиляции она равна 20, в результате будет скомпилировано
C++
1
2
3
int a=20;
a+=200;
std::cout<<"less"<<std::endl;
, а должно быть
C++
1
2
3
int a=20;
a+=200;
std::cout<<"more"<<std::endl;
.
0
Почетный модератор
Эксперт С++
5850 / 2861 / 392
Регистрация: 01.11.2011
Сообщений: 6,907
26.03.2014, 15:14 14
Цитата Сообщение от ValeryS Посмотреть сообщение
так об чем ТС и спрашивает
У меня не работает.
Цитата Сообщение от ValeryS Посмотреть сообщение
об чем и речь
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
26.03.2014, 15:16 15
для чистоты эксперимента надо бы так написать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <iostream>
using namespace std;
 
int a = 9;
#define b a 
int main(void){
#if a>99
    printf("Kompiliruet, esli a bol'she 9\n");          
#else
    printf("Kompiliruet, esli a men'she 9\n");
#endif
   printf ("%d",b);
    char ch = getchar();
    return 0;
}
что препроцессор из a считывает? может там вообще 0
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 15:18 16
Цитата Сообщение от ValeryS Посмотреть сообщение
что препроцессор из a считывает? может там вообще 0
Там 9.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
26.03.2014, 15:25 17
Цитата Сообщение от taras atavin Посмотреть сообщение
Там 9.
я лично не уверен
препроцессор работает до компилятора, инициализации то еще не было
тем более что SatanaXIII, не работает, в каждой палатке свои порядки
вот если бы было
C++
1
const int a = 9;
то вопрос другой, по сути это
C++
1
#define a 9
в тонкости реализации не лезу
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.03.2014, 15:28 18
Цитата Сообщение от ValeryS Посмотреть сообщение
препроцессор работает до компилятора, инициализации то еще не было
Препроцессор тоже умеет читать исходник, так что она вполне была. Вот только юзать эту фичу нельзя, она предназначена не для программирования, а для выявления глюкописцев.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
26.03.2014, 15:40 19
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только юзать эту фичу нельзя, она предназначена не для программирования, а для выявления глюкописцев.
вот здесь полностью согласен
0
18840 / 9839 / 2408
Регистрация: 30.01.2014
Сообщений: 17,280
26.03.2014, 18:38 20
О чем вообще разговор-то? Препроцессинг это отдельный этап. Он никак не связан с компиляцией. В том плане что препроцессору вообще побоку что там написано с точки зрения языка. Он обрабатывает текст. Любой. Вообще. А директивы - это средство контроля этой обработки. Заменить там, А на Б. Вставить кусок С или кусок Б в зависимости от определенного условия (которое тем же препроцессором и задается).
Поэтому ни о каком родстве вот этих примеров не может быть и речи
C++
1
2
3
const int a = 9;
 
#define a 9
Первый случай, это языковая константа, которая подчиняется всем правилам языка, таким как: область видимости, время жизни, также учитывается ее тип и место определения. А второе это просто правило для автозамены вида "встретил а - подставь 9".
0
26.03.2014, 18:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.03.2014, 18:38
Помогаю со студенческими работами здесь

Можно ли в запросе фильтра подставлять переменные
В два грида выводятся отфильтрованые данные нельзя-ли в место запроса &quot;dv1.RowFilter =...

Почему нельзя командой copy скопировать системные файлы на дискету? Почему?
Пожалуйсат, подскажите, весь интернет перерыла, вот почему нельзя? что нельзя знаю, а по какой...

Почему в локальном классе доступны финальные переменные или переменные инициализированные при объявлении
Добрый вечер. Объясните пожалуйста, почему в локальном классе могут использоваться только финальные...

На рабочем столе нельзя перетаскивать ярлыки, нельзя копировать файлы и нельзя их вставлять
После загрузки компьютера вылезла ошибка, что кокойто файл windows неможет прочесть было предложено...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru