📌  相关文章
📜  AKTU第一学年第二学期解题纸2015-16 | COMP。系统和C编程| C段

📅  最后修改于: 2021-05-20 07:36:49             🧑  作者: Mango

论文下载链接:论文|第二学期| 2015-16

时间: 3小时
总分数:100

注意:-

  • 共分为三个部分。 A节为20分, B节为50分, C节为30分。
  • 尝试所有问题。每个问题都带有标记。
  • 必要时假定合适的数据。

尝试两个部分:(15 * 2 = 30)

3.什么是预处理器指令?解释其中的任何三个。

  • 条件编译:条件编译指令有助于编译程序的特定部分,或者让我们根据某些条件跳过对程序某些特定部分的编译。在上一篇文章中,我们讨论了两个这样的指令’ ifdef ‘和’ endif ‘。在这篇文章中,我们将讨论#ifndef#if#else#elif
    1. #ifdef :此指令是最简单的条件指令。此块称为条件组。如果定义了宏名,则受控文本将包含在预处理器输出中。条件内的受控文本将包含预处理指令。仅在条件成功时才执行它们。您可以将它们嵌套在多个层中,但是必须将它们完全嵌套。换句话说,“#endif”始终匹配最接近的“ #ifdef”(或“ #ifndef”或“ #if”)。同样,您不能在一个文件中开始条件组,而在另一个文件中完成它。

      句法:

      #ifdef MACRO
          controlled text
      #endif /* macroname */
      
    2. #ifndef :我们知道,如果#ifdef指令中定义了宏名,则#ifdef指令后的语句块将正常执行,但是如果未定义,则编译器将简单地跳过该语句块。 #ifndef指令与#ifdef指令相反。对于#ifndef,仅当未定义宏或带有#ifndef的标识符时,才会执行#ifndef和#endif之间的语句块。
      句法 :
      ifndef macro_name
          statement1;
          statement2;
          statement3;
          .
          .
          .
          statementN;
      endif
      

      如果未使用#define指令定义名称为“ macroname”的宏,则仅执行语句块。

    3. #if,#else和#elif :这些指令可以一起使用,并使用某些条件控制程序部分的编译。如果带有#if指令的条件的结果为非零值,那么将立即执行#if指令后的行组,否则,如果带有#elif指令的条件的结果为非零值,则该行组#elif指令之后将立即执行,否则#else指令之后的行将被执行。
      句法:
      #if macro_condition
         statements
      #elif macro_condition
         statements
      #else
         statements
      #endif
      

      例子:

      #include 
        
      #define gfg 7
        
      #if gfg > 200
      #undef gfg
      #define gfg 200
      #elif gfg < 50
      #undef gfg
      #define gfg 50
      #else
      #undef gfg
      #define gfg 100
      #endif
        
      int main()
      {
          std::cout << gfg; // gfg = 50
      }
      

      输出:

      50
      

      注意#if,#elif和#else链式指令的整个结构如何以#endif结尾。

  • 行控制(#line) :每当我们编译程序时,程序中都有发生某些错误的机会。只要编译器在程序中发现错误,它就会为我们提供在其中找到错误的文件名,行列表以及错误所在的确切行号。这使我们很容易找到并纠正错误。
    但是,我们可以使用#line指令控制编译器在编译错误期间应提供哪些信息。
    句法:
    #line number "filename"
    

    number –将分配给下一个代码行的行号。从此以后,连续行的行号将一一增加。
    “文件名” –可选参数,允许重新定义将显示的文件名。

  • 错误指令(#error) :在编译过程中在程序中找到该指令时,该指令将中止编译过程,并产生一个可选的错误,可以将其指定为参数。
    句法:
    #error optional_error
    

    在这里, optional_error是用户指定的任何错误,当在程序中找到该伪指令时将显示该错误。
    例子:

    #ifndef GeeksforGeeks
    #error GeeksforGeeks not found !
    #endif
    

    输出:

    error: #error GeeksforGeeks not found !
    

4.(i)详细说明程序的加载和链接。

  • 加载程序操作系统的程序,它将可执行文件从磁盘加载到主内存(RAM)中以供执行。它将内存空间分配给主内存中的可执行模块,然后将控制权转移到程序的开始指令。

    例子:

    akash @aix(/ u / akash) #cat./ ak1.cpp
    #include 
                                   int main()
    {
        printf("Testing of Loader !");
        return 0;
    }
    

    通过xlC编译器进行编译:

    运行可执行文件时真正发生的情况:也可以使用strace命令。

    显示的第一个调用是’ execve() ‘,它实际上是加载程序。该加载器创建的过程涉及:

    • 读取文件并为该进程创建地址空间。
    • 创建指令,数据和程序堆栈的页表条目,并初始化寄存器集。
    • 然后,执行通常会导致页面错误的程序第一条指令的跳转指令,并将指令的第一页存储到内存中。
  • 链接这是最后一个阶段,在此阶段中完成了所有函数调用及其定义的链接。链接器知道所有这些功能的实现位置。 Linker还会做一些额外的工作,它会在程序的开始和结束时向我们的程序中添加一些额外的代码。例如,有一个代码需要设置环境,例如传递命令行参数。使用$ size filename.o$ size filename可以轻松地验证此任务。通过这些命令,我们知道输出文件如何从目标文件增加到可执行文件。这是因为链接器在我们的程序中添加了额外的代码。
    编译8
    请注意,默认情况下,GCC会进行动态链接,因此在上述程序中会动态链接printf()。有关静态和动态链接的更多详细信息,请参考本文档,本文档和本文档。

4.(ii)用C编写一个程序,该程序将从键盘读取一个正数并以相反的顺序打印它。
例子:

Input: 24578 
Output: 87542
#include 
  
/* Iterative function to reverse digits of num*/
int reversDigits(int num)
{
    int rev_num = 0;
    while (num > 0) {
        rev_num = rev_num * 10 + num % 10;
        num = num / 10;
    }
    return rev_num;
}
  
/* Driver program to test reversDigits */
int main()
{
    int num;
  
    scanf("%d", &num);
    printf("Reverse of no. is %d",
           reversDigits(num));
  
    return 0;
}

输出:

2654

5.假设一个文件包含学生的记录,而每个记录都包含一个学生的姓名和年龄。编写一个C程序来读取这些记录,并按名称按顺序显示它们。

// C program to read Student records 
// like id, name and age, 
// and display them in sorted order by Name 
  
#include  
#include  
#include  
  
// struct person with 3 fields 
struct Student { 
    char* name; 
    int id; 
    char age; 
}; 
  
// setting up rules for comparison 
// to sort the students based on names 
int comparator(const void* p, const void* q) 
{ 
    return strcmp(((struct Student*)p)->name, 
                ((struct Student*)q)->name); 
} 
  
// Driver program 
int main() 
{ 
    int i = 0, n = 5; 
  
    struct Student arr[n]; 
  
    // Get the students data 
    arr[0].id = 1; 
    arr[0].name = "bd"; 
    arr[0].age = 12; 
  
    arr[1].id = 2; 
    arr[1].name = "ba"; 
    arr[1].age = 10; 
  
    arr[2].id = 3; 
    arr[2].name = "bc"; 
    arr[2].age = 8; 
  
    arr[3].id = 4; 
    arr[3].name = "aaz"; 
    arr[3].age = 9; 
  
    arr[4].id = 5; 
    arr[4].name = "az"; 
    arr[4].age = 10; 
  
    // Print the Unsorted Structure 
    printf("Unsorted Student Records:\n"); 
    for (i = 0; i < n; i++) { 
        printf("Id = %d, Name = %s, Age = %d \n", 
            arr[i].id, arr[i].name, arr[i].age); 
    } 
    // Sort the structure 
    // based on the specified comparator 
    qsort(arr, n, sizeof(struct Student), comparator); 
  
    // Print the Sorted Structure 
    printf("\n\nStudent Records sorted by Name:\n"); 
    for (i = 0; i < n; i++) { 
        printf("Id = %d, Name = %s, Age = %d \n", 
            arr[i].id, arr[i].name, arr[i].age); 
    } 
  
    return 0; 
} 

输出:

Unsorted Student Records:
Id = 1, Name = bd, Age = 12 
Id = 2, Name = ba, Age = 10 
Id = 3, Name = bc, Age = 8 
Id = 4, Name = aaz, Age = 9 
Id = 5, Name = az, Age = 10 


Student Records sorted by Name:
Id = 4, Name = aaz, Age = 9 
Id = 5, Name = az, Age = 10 
Id = 2, Name = ba, Age = 10 
Id = 3, Name = bc, Age = 8 
Id = 1, Name = bd, Age = 12