编写C / C ++多种语言


27

这个挑战的概念非常简单。您要做的就是编写一个可以同时作为有效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 ++之间的区别之一,特别是如何处理char文字。在C中,它们被视为整数,因此sizeof('!')返回4,而在C ++中则为1。该((...+1)&1)部分只是简单的按位运算的一部分,如果sizeof('!')返回4,则返回1,如果返回1,则返回0。结果数乘以数组中的整数t,然后最终将乘积添加到要转换的特定字符中。在C ++中,乘积始终为零,因此字符串C++ rules!保持不变。在C中,乘积将始终是中的值t,因此字符串更改为C++ stinks


5
我确定这是某件事的虚假...
Beta Decay

@BetaDecay是吗?我尝试搜索类似内容,但找不到任何内容。
2014年

您能否解释一下您的程序如何以不同的方式工作(如果它不会破坏挑战)?
AL

@AL我编辑了我的帖子的解释。
2014年

所有来自stackoverflow.com/questions/2038200/…的文件都可以在这里使用-有点混淆。
杰里·耶利米

Answers:


18

蛋糕是骗人的吗?

由于对蛋糕是否是谎言一直存在很多争论,我编写了此程序来回答这个有争议的问题。

#include <stdio.h>

// checks if two things are equal
#define EQUALS(a,b) (sizeof(a)==sizeof(b)) 

struct Cake{int Pie;}; // the cake is a pie!
typedef struct Cake Lie;
main(){
    struct CakeBox{
        struct Cake{ // the cake contains lies!
            Lie Lies[2];
        };
    };
    typedef struct Cake Cake;

    printf("The cake is ");
    if(EQUALS(Cake, Lie)){
        printf("a LIE!\n");
    }else{
        printf("..not a lie?\n");
    }
    return 0;
}

结果将是什么?

C:

The cake is ..not a lie?

C ++:

The cake is a LIE!


1
这个。我喜欢这个。
FUZxxl

9

只是一些傻瓜

#include <stdio.h>

int test(bool)
  {
  return sizeof(bool) == sizeof(int);
  }

int main(void)
  {
  puts(test(0) ? "C" : "C++");
  return 0;
  }

http://codepad.org/dPFou20W
http://codepad.org/Ko6K2JBH


布尔不是C89的一部分
malat 2014年

8
@malat是的,此解决方案中正是使用了这一事实。对于c ++,该函数为int test(bool / * unnamed boolean arguments * /); 对于C语言,它使用默认的int声明,这意味着int test(int bool); 所以'bool'是整数变量的名称。
Qwertiy 2014年

5

我本可以用3行程序来完成此操作,但是很明显为什么它会为C和C ++产生不同的结果。所以相反,我开始用某种隐写法编写一个更大的程序,在C和C ++中得到不同的结果...

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct product
{
    int quantity;
    char name[20];
    char desc[80];
}; 

struct _customer
{
    char name[80];
    struct product *products;
} customer;

int main(int argc, char *argv[])
{

struct shipment
{
    char tracking_number[40];
    int quantity;
    struct product { int model; int serial; } sku;
};

struct _supplier
{
    char name[80];
    struct shipment *shipments;
} supplier;

/* now read the command line and allocate all the space we need */

if(argc<5)
{
    printf("Usage: %s <supplier name> <# of shipments> <customer name> <# of products> ",argv[0]);
    exit(1);
}

strcpy(supplier.name,argv[1]);
int shipments_size = atoi(argv[2])*sizeof(struct shipment);
printf("Allocating %d bytes for %s shipments\n", shipments_size,supplier.name);
supplier.shipments=(struct shipment *)malloc(shipments_size);

strcpy(customer.name,argv[3]);
int products_size = atoi(argv[4])*sizeof(struct product);
printf("Allocating %d bytes for %s products\n", products_size,customer.name);

/* ... TODO ... finish the rest of this program later */

free(customer.products);
free(supplier.shipments);

return 0;
}

您需要指定一个命令行。当我在我的gcc副本上运行它时,得到以下输出:

>g++ x.cpp

>a.exe "Bob Supplier" 1 "Jane Customer" 1
Allocating 52 bytes for Bob Supplier shipments
Allocating 104 bytes for Jane Customer products

>gcc x.c

>a.exe "Bob Supplier" 1 "Jane Customer" 1
Allocating 52 bytes for Bob Supplier shipments
Allocating 8 bytes for Jane Customer products

事情怎么会这么可怕呢?


尽管其他人也做同样的事情,但您掩盖得很好。
kirbyfan64sos 2015年

5
#include <stdio.h>

int c[1]; 
int main() { 
   struct c { int cpp[2]; }; 
   printf("%d\n", (int)sizeof(c)/4);
}

4

此版本适用于C ++ 11和更高版本以及到目前为止(在C11之前)的任何C。

#include <stdio.h>

int main()
{
    auto a = 'a';
    printf(sizeof(a) == sizeof(int) ? "C\n" : "C++\n");
    return 0;
}

参见此处:C ++:http : //ideone.com/9Gkg75 和C:http : //ideone.com/eECSmr

它利用了在C ++ 11中auto关键字具有新含义的事实。因此,虽然in C的int类型存储在AUTOMATIC的自动位置,但C ++ 11中的char类型却是char。

编辑:正如FUZxxl所说,隐式int在C11中已删除。


1
由于C11删除了隐式int规则,因此不适用于C11 。
2015年

@FUZxxl谢谢,我调整了帖子。
菲利克斯·拜托

1

自我描述程序

这将打印“此程序是用C编写的!” 如果使用C编译器编译;否则,将显示“此程序是用C ++编写的!”。它需要一个C99编译器。

#include <stdbool.h>
#include <stdio.h>
char str[] = "This program is written in C++ ";
#define S (sizeof(str)-sizeof(true)-sizeof(true)%4)
int main(){for(int i=S;i<=S+1;++i)str[i]=i==S?'!':'\0';puts(str);return 0;}

其他大多数文章都利用了C和C ++中char大小的差异;这一事实利用了在C99 true中定义为数字的事实。这会根据的大小插入感叹号和空终止符true

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.