第三届全国高校绿色计算机大赛(初赛题目)

任务描述

任务背景

我们在编写程序时,代码在通常情况下都是平台无关的。但是,在某些情况下,某一些代码是和平台相关的,比如 SSE intrinsics 函数(是一组函数,主要是把 x86 汇编封装成了函数,一个函数对应一个 x86 汇编)的底层实现是 x86 汇编,所以该类函数只能够在 x86 平台运行。

针对上述情况,当我们在代码中需要用到这些函数的时候,就要用 x86 相关的宏来标示和控制该代码段,保证该代码段不会在非 x86 平台上运行。

x86 宏的使用

__x86_64__ 是一种预定义的 x86 宏,通过下面的一些规则来标示对应的代码是否在 x86 平台上运行:

  1. #if defined(__x86_64__)       // 标示对应的代码在 x86 平台上运行
  2. #if !defined(__x86_64__)      // ! 是逻辑非运算符,标示对应的代码不能在 x86 平台上运行
  3. #ifdef __x86_64__            // ifdef 等价于 if defined 的缩写,标示对应的代码在 x86 平台上运行
  4. #ifndef __x86_64__           // ifndef 等价于 if !defined,标示对应的代码不能在 x86 平台上运行
  5. #elif defined(__x86_64__)     // elif 是 else if 的缩写,标示对应的代码在 x86 平台上运行
  6. #elif !defined(__x86_64__)    // 标示对应的代码不能在 x86 平台上运行
  7. #else
  8. #endif

注意:__x86_64__ 首尾的下划线是由两个短下划线组成的。

本关任务

任务要求

本赛题提供了多个使用 C 语言编写的代码片段文件,其中部分代码片段中包含了只能在 x86 平台运行的代码,这些代码会通过相应的宏来标示。

本赛题要求编写代码,读取控制台输入的代码片段文件,识别出该代码文件中通过宏__x86_64__ 标示的只能在 x86 平台上运行的代码段(不包括通过其他 x86 宏标示的只能在 x86 平台上运行的代码),并打印输出该代码段的起始行与结束行的行号;若无通过宏__x86_64__ 标示的 x86 相关代码则输出NULL。

注意:本题中,输出结果中起始行和结束行为实际在 x86 平台运行的代码的起始行和结束行,不包括 if defined和else等宏定义所在的代码行,具体参考下面的示例。此外,题目测试集所提供的代码片段文件中代码的书写格式与下面给出的参考示例文件相同。

评测示例

(1) test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #if defined(__x86_64__)
  7.     printf("The platform is x86_64.\n");
  8.  
  9. #endif
  10. 10.     return 0;

11. }

输出为:起始行为7,结束行为8。

(2) test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #if !defined(__x86_64__)
  7.     printf("The platform is not x86_64.\n");
  8.     printf("This is a test case.\n");
  9. #endif
  10. 10.     return 0;

11. }

输出:NULL

(3) test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #ifdef __x86_64__
  7.     printf("The platform is x86_64.\n");
  8. #endif
  9.     return 0;

10. }

输出为:起始行为7,结束行为7。

(4) test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #ifndef __x86_64__
  7.     printf("The platform is not x86_64.\n");
  8. #endif
  9.     return 0;

10. }

输出:NULL

(5) test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #if !defined(__x86_64__)
  7.     printf("The platform is not x86_64.\n");
  8. #else
  9.      printf("The platform is x86_64.\n");

10. #endif

  1. 11.     return 0;

12. }

输出为:起始行为9,结束行为9。

注意: 宏#if defined(__x86_64__)与#ifdef __x86_64__是等价的,#if !defined(__x86_64__)与#ifndef __x86_64__也是等价的。

(6) 要注意多个宏的定义, test.c 文件内容如下:

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. int main()
  5. {
  6. #if defined(__x86_64__)
  7.     printf("The platform is x86_64.\n");
  8.     printf("This is a test case.\n");
  9. #endif
  10. 10.  

11. #ifndef __x86_64__

  1. 12.     printf("The platform is not x86_64.\n");
  2. 13.  

14. #endif

  1. 15.  

16. #if !defined(__x86_64__)

  1. 17.     printf("The platform is not x86_64.\n");
  2. 18.     printf("This is a test case.\n");

19. #endif

  1. 20.  

21. #ifdef __x86_64__

  1. 22.     printf("The platform is x86_64.\n");
  2. 23.     printf("This is a test case.\n");

24. #endif

  1. 25.     return 0;

26. }

输出为:

  1. 起始行为7,结束行为8。
  2. 起始行为22,结束行为23。

本题不需考虑宏定义的嵌套语句,即类似下面的代码示例:

  1. int main()
  2. {
  3. #if defined(__x86_64__)
  4.     #ifdef __x86_64__
  5.         printf("The platform is x86_64.\n");
  6.         printf("This is a test case.\n");
  7.     #endif
  8. #endif
  9.     return 0

10. }

测试说明

在右侧编辑器中完成代码编写,识别每个代码片段中只能在 x86 平台上运行的代码段,参照示例打印输出相关代码的起始行和结束行。完成代码后点击评测,平台将运行你的代码进行测试,如果与预期输出一致,则算通过相应的测试用例。


开始你的任务吧,祝你成功!

 

 

 

 

 

//########## Begin ##########

#include <bits/stdc++.h>    //万能头文件

using namespace std;

string files;   //输入文件的路径

int sum=0,flag,l;

void fun()

{

    cin>>files;

    ifstream ifile;

    ifile.open(files.data());   //正确打开文件

    string s;

    while(getline(ifile,s))   //每次读入一行,然后在循环里对行进行处理

    {

        sum++;      //用来记录行数

        string s1=s.substr(0,strlen("#if defined(__x86_64__)"));

        string s2=s.substr(0, strlen("#if !defined(__x86_64__)"));

        string s3=s.substr(0, strlen("#ifdef __x86_64__"));

        string s4=s.substr(0, strlen("#ifndef __x86_64__"));

        string s5=s.substr(0, strlen("#elif defined(__x86_64__)"));

        string s6=s.substr(0, strlen("#elif !defined(__x86_64__)"));

        string s7=s.substr(0, strlen("#else"));

        string s8=s.substr(0, strlen("#endif"));

        if(s1=="#if defined(__x86_64__)" || s3=="#ifdef __x86_64__" || s5=="#elif defined(__x86_64__)")

        {

            //如果定义了

            cout<<"起始行为"<<sum+1<<",";

            flag=2;

            l++;    //l不为0表示整个程序里有__x86_64__的代码

        }

        if(s8=="#endif" && flag==2)     //只在有定义时输出,所以需要flag=2;

        {

            cout<<"结束行为"<<sum-1<<"。";

            cout<<endl;

            flag=0;

            l++;

        }

        if(s8=="#endif")  //防止:#if !defined(__x86_64__)出现,却没有else的情况(因为此时flag=1)

            flag=0;

        if(s2=="#if !defined(__x86_64__)" || s4=="#ifndef __x86_64__" || s6=="#elif !defined(__x86_64__)")

            flag=1;       //这里令出flag=1,保证了else是和!=配套的,而不是if——else结构

        if(s7=="#else" && flag==1)  //条件是和上文呼应,配套的

        {

            cout<<"起始行为"<<sum+1<<",";

            flag=2;

            l++;

        }

    }

    if(l==0) cout<<"NULL";    //没有x86平台的代码

    ifile.close();

}

int main()

{

    fun();

    return 0;

}

//########## End ##########

 

 

 

 

posted @ 2020-09-01 21:00  py佐料  阅读(354)  评论(0)    收藏  举报