Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
#1

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

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

Почему код работает, не должен же, потому что выражение стоящее после #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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.03.2014, 14:25
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему нельзя подставлять переменные в выражения #if #else? (C++):

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

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

Почему break нельзя использовать в if? - C++
почему break нельзя использовать в if вот код if(f.eof()==1) { break; } про break MVS говорит что ОПЕРАТОР break...

Почему нельзя так объявить двумерный массив? - C++
Ошибка возникает если для массива tempArray при объявлении(и одновременной инициализации) использовать переменную(size) которую принимает...

Почему нельзя объявить указатель на шаблонную структуру? - C++
template &lt;class T&gt; typedef struct per { T znach; int kol_vo_povt; }* p; int main() { per&lt;int&gt; k; }

Почему нельзя компилировать отдельный заголовочный файл? - C++
Вообще можно весь код поместить в один .cpp файл. Но, как я понимаю, люди советуют все функции помещать в отдельные заголовочные файлы. А...

27
gelior
26 / 26 / 4
Регистрация: 10.04.2013
Сообщений: 91
26.03.2014, 14:28 #2
а, собственно, зачем # перед if и else?
0
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
26.03.2014, 14:31  [ТС] #3
а, собственно, зачем # перед if и else?
смотрю как работает, читаю книгу, там написано то что я написал выше, мне интересно, посему
просто кто то пишет какую то программу, по ходу задает вопросы, а кто то читает книги и примеры "абстрактные"
конечно если я буду писать какую нить программу, я не буду где попало ставить #
0
Евгений89
99 / 99 / 9
Регистрация: 17.04.2011
Сообщений: 554
Завершенные тесты: 2
26.03.2014, 14:40 #4
Директивы #if, #elif, #else и #endif (C/C++)http://msdn.microsoft.com/ru-ru/library/ew2hz0yd.aspx
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:41 #5
Цитата Сообщение от gelior Посмотреть сообщение
а, собственно, зачем # перед if и else?
Затем, что это макрос условной компиляции.
0
SatanaXIII
Супер-модератор
Эксперт С++
5619 / 2654 / 247
Регистрация: 01.11.2011
Сообщений: 6,554
Завершенные тесты: 1
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
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:46 #7
Цитата Сообщение от SatanaXIII Посмотреть сообщение
Единственное, что нужно отметить - обязательно должен быть "#endif", потому как без него препроцессор не сможет понять, в каком месте заканчивается директива "#if"
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
0
SatanaXIII
Супер-модератор
Эксперт С++
5619 / 2654 / 247
Регистрация: 01.11.2011
Сообщений: 6,554
Завершенные тесты: 1
26.03.2014, 14:50 #8
Цитата Сообщение от taras atavin Посмотреть сообщение
Нет. Второе важное обстоятельство заключается в том, что этот иф обрабатывается статически на этапе компиляции, а условие в нём определяет не поведение программы, а сам её код, то есть от него зависит, что будет в исполняемой версии программы, а чего там вообще не будет.
Нет. Третье, что необходимо отметить, что компиляция вообще не будет возможна при ошибках на этапе препроцессорной обработки, а без нее не имеет смысла говорить о поведении программы, так как код ее не будет сформирован правильно.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 14:54 #9
Нет. Этот фактор не отличает от грубых синтаксических ошибок в обычных операторах, если написать, например,
C++
1
if )a>d)
вместо
C++
1
if (a>d)
, или помянуть не существующую переменную, или сравнить величины не сравнимых (для которых нет версии
C++
1
operator >
), то программы тоже не будет. Это общее, а конкретно условная компиляция от условного оператора отличается только двумя факторами.
0
ValeryS
Модератор
6709 / 5118 / 482
Регистрация: 14.02.2011
Сообщений: 17,213
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
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.03.2014, 15:06 #11
Цитата Сообщение от ValeryS Посмотреть сообщение
предположу что a сделалась константой
а она известна на этапе компиляции
Константой она не стала, но на этапе компиляции стала известна за счёт инициализации не кодом самой программы, а загрузчиком, входящим в состав операционной системы, то есть не операция присваивания, а само стартовое значение стало частью исполняемого файла. Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
0
ValeryS
Модератор
6709 / 5118 / 482
Регистрация: 14.02.2011
Сообщений: 17,213
26.03.2014, 15:10 #12
Цитата Сообщение от taras atavin Посмотреть сообщение
Константой она не стала,
разумеется нет, поскольку нет const
но для препроцессора наверное да, значение то известно, да и не используется больше нигде
(ключевое слово наверное, т.е я ни в чем не уверен)
Цитата Сообщение от taras atavin Посмотреть сообщение
Вот только где гарантия, что подобные тонкости учитывают все компиляторы?
об чем и речь
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
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
SatanaXIII
Супер-модератор
Эксперт С++
5619 / 2654 / 247
Регистрация: 01.11.2011
Сообщений: 6,554
Завершенные тесты: 1
26.03.2014, 15:14 #14
Цитата Сообщение от ValeryS Посмотреть сообщение
так об чем ТС и спрашивает
У меня не работает.
Цитата Сообщение от ValeryS Посмотреть сообщение
об чем и речь
0
ValeryS
Модератор
6709 / 5118 / 482
Регистрация: 14.02.2011
Сообщений: 17,213
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
26.03.2014, 15:16
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.03.2014, 15:16
Привет! Вот еще темы с ответами:

Почему нельзя написать просто - using namespace boost; - C++
Доброго времени суток. В общем, есть программа, в которой я использую тип cpp_int. Вроде его объявление содержится в заголовочном файле...

Почему нельзя выделить статически кусок в ~100 MB? - C++
Есть код #include &lt;iostream&gt; using namespace std; enum { length = 256, count = 50 }; struct Town { char name =...

Почему таким способом нельзя создать массив? - C++
Хочу создать массив вот таким способом, но выскакивает ошибка error C2057: требуется константное выражение. Ведь у меня и так константа!?...

Почему нельзя объявить динамический массив глобально - C++
вот код #include &lt;iostream&gt; #include &lt;string&gt; int w = 0; string *s = new string ; using namespace std; int main { ...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru