当前位置:  开发笔记 > 编程语言 > 正文

编写一个程序,如果编译为(ANSI)C程序将打印"C",如果编译为C++程序则编写"C++"

如何解决《编写一个程序,如果编译为(ANSI)C程序将打印"C",如果编译为C++程序则编写"C++"》经验,为你挑选了4个好方法。

取自http://www.ocf.berkeley.edu/~wwu/riddles/cs.shtml

它看起来非常适合我的编译器.不知道在哪找?



1> avakar..:

我们不得不在学校做类似的任务.我们不允许使用预处理器(#include当然除外).下面的代码使用了这样的事实,即在C中,类型名称和结构名称形成单独的命名空间,而在C++中则不是.

#include 
typedef int X;
int main()
{
    struct X { int ch[2]; };
    if (sizeof(X) != sizeof(struct X))
        printf("C\n");
    else
        printf("C++\n");
}


在C++中,它们并不构成单独的命名空间,它们由编译器保持独立,**但**编译器将在*both*namespaces中查找符号(首先在非用户定义的类型中,然后在用户定义的类型).有几种方法可以测试它,最简单的方法是`typedef struct X {} Y; void X();`编译,但是如果你添加`void Y();`你将得到编译器错误:非用户定义的命名空间中的符号`Y`已被`typedef`使用.

2> jamesdlin..:

我知道7种方法:

1.滥用C++自动typedefs

(注意,struct需要在内部作用域中声明,以便它优先于C++中的外部名称.)

char x;
{
    struct x { char dummy[2]; };
    printf("%s\n", sizeof (x) == 1 ? "C" : "C++");
}

类似的版本,不依赖之间的模糊性sizeof (type)sizeof (variable)仅使用类型:

typedef char t;
{
    struct t { char dummy[2]; };
    printf("%s\n", sizeof (t) == 1 ? "C" : "C++");
}

2.滥用C++ struct/ class等价,自动typedef生成和自动生成的默认构造函数

/* Global*/
int isC = 0;
void Foo() { isC = 1; }

/* In some function */
struct Foo { int dummy; };
Foo();
printf("%s\n", isC ? "C" : "C++");

3.滥用structC语言中的嵌套声明

另请参阅内部和外部结构的符号冲突,C++与C

typedef struct inner { int dummy; } t;
{
    struct outer { struct inner { t dummy[2]; } dummy; };
    printf("%s\n",
           sizeof (struct inner) == sizeof (t)
           ? "C++"
           : "C");
}

4.滥用//评论

这不适用于C99或支持//扩展的C89编译器.

printf("%s\n",
       0 //* */
       +1
       ? "C++"
       : "C");

或者:

printf("s\n",
       1 //* */ 2
       ? "C++"
       : "C");

5. sizeofchar文字的差异

请注意,这不能保证是可移植的,因为某些假设平台可能使用超过8位的字节,在这种情况下sizeof(char)可能与之相同sizeof(int).(另请参阅Can sizeof(int)在托管实现上是否为1?)

printf("%s\n", sizeof 'a' == 1 ? "C++" : "C");

6.在执行左值⇒价值转换时滥用差异

这基于ISO C++ 03标准中的5.16,5.17,5.18示例,它在gcc中工作但在MSVC中不起作用(可能是由于编译器错误?).

void* array[2];
printf("%s\n",
       (sizeof (((void) 0), array) / sizeof (void*) == 1)
       ? "C"
       : "C++");

7.滥用C和C++语法解析三元运算符的方式的差异

这个并不严格合法,但有些编译器不严格.

int isCPP = 1;
printf("%s\n", (1 ? isCPP : isCPP = 0) ? "C++" : "C");

(您也可以检查__cplusplus预处理器宏(或其他各种宏),但我认为这不符合问题的精神.)

我在以下所有方面都有实现:http: //www.taenarum.com/csua/fun-with-c/c-or-cpp.c


不,根据定义,`char`是1个字节,一个字节必须是*至少*8位,但它可以更多.这就是为什么`CHAR_BIT`存在的原因.
它需要char为1个字节.字节中的位数是实现定义的.

3> bmargulies..:

很简单.

#include 
int main(int argc, char ** argv) {
#ifdef __cplusplus
printf("C++\n");
#else
printf("C\n");
#endif
return 0;
}

或者是否要求在没有官方标准的情况下这样做?


当然,一个非常讨厌的C实现可以定义__cplusplus.
@Neil,在C99标准中,第6.10.8.5节明确禁止定义__cplusplus的实现.但在C89中没有任何类似的东西.
`__cplusplus`仅在编译器完全符合时才定义为199711L*.例如,gcc仍将`__cplusplus`定义为1.
只是让输出同意这个问题.
那是对的.C++ 1998标准说:"在编译C++翻译单元时,名称`__cplusplus`被定义为值`199711L`".(第16.8节:`[cpp.predefined]`)

4> Matthew Slat..:
puts(sizeof('a') == sizeof(int) ? "C" : "C++");


Oak,在C中,字符文字的类型为`int`,在C++中它们的类型为`char`.
实际上这并不能保证工作.如果`CHAR_BIT`至少为16,则`sizeof(int)`可以为1.
推荐阅读
LEEstarmmmmm
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有