Концепция этой задачи довольно проста. Все, что вам нужно сделать, это написать программу, которая будет компилировать как действительный C, так и действительный C ++! Ну, есть некоторые уловы. Программа должна вести себя по-разному при компиляции на каждом языке. Программа должна иметь разные выходные данные для каждого языка, чтобы считаться «веду себя по-разному».
правила
- Программа должна быть как на C, так и на C ++
- Программа должна иметь разные выходные данные в зависимости от языка, на котором она была скомпилирована.
#ifdef __cplusplus
или другие "легкие" уловки препроцессора не приветствуются! (Однако другие операции препроцессора вполне хороши.)- Постарайтесь не показывать совершенно очевидным, что программа делает что-то другое.
Это конкурс популярности , поэтому победит тот, кто найдет самое интересное и удивительное решение. Повеселись!
Пример:
Я создал свою собственную программу, чтобы посмотреть, возможно ли это сделать с помощью #ifdef
трюков:
#include <stdio.h>
#include <string.h>
char *m="C++ rules!";
int t[11]={0,0,0,0,1,-1,-3,9,-8,82,0};
char tr(char c,int i)
{
return c+((sizeof('!')+1)&1)*t[i];
}
int main()
{
int i = 0;
for(;i<strlen(m);i++)
{
printf("%c",tr(m[i],i));
}
printf("\n");
return 0;
}
Эта программа выводится C++ rules!
при компиляции в C ++ и C++ stinks
при компиляции в C.
Объяснение:
Что вызывает разницу между языками, так это
tr()
функция. Он использует одно из различий между C и C ++, а именно то, как обрабатываются символьные литералы. В C они рассматриваются как целые числа, поэтомуsizeof('!')
возвращает 4, а не 1 в C ++. Эта((...+1)&1)
часть является лишь частью простой побитовой операции, которая вернет 1, еслиsizeof('!')
вернет 4, и 0, если вернет 1. Это результирующее число умножается на целые числа в массиве,t
а затем этот продукт, наконец, добавляется к конкретному преобразуемому символу. В C ++ продукт всегда будет нулевым, поэтому строкаC++ rules!
остается неизменной. В C продукт всегда будет значением вt
, поэтому строка меняется наC++ stinks
.