• 北航2021程序语言原理试题及总结


    试题

    1 C语言程序阅读

    #include<bits/stdc++.h>
    using namespace std;
    int f(int* i) {
      static int x = 0;
      x++;
      printf("%d -1, *i= %d\n", x, *i++);
      printf("%d -2, *i= %d\n", x, *i++);
      return *i;
    }
    int main() {
      int x[3] = { 1,2,3 };
      x[0] = f(x) + f(x) + x[x[0]];
      printf("x[0]=%d\n", x[0]);
    }
    
    
    

    输出是

    1 -1, *i= 1
    1 -2, *i= 2
    2 -1, *i= 1
    2 -2, *i= 2
    x[0]=8

    (这输出也太奇怪了吧局部变量x增加了,x[0]没有变,所以求值策略是什么?感觉要看汇编代码)

    (后来知道这个++优先级更高。。。太蠢了)

    2 Scheme设计

    实现trim,去掉列表的最后一个元素。相当于 vector<int>v;v.pop_back()

    
    (define (my-trim lst )
      (cond ((null? lst)    ; if the list is empty
             'error)          ; error
            ((equal? (cdr lst) '()) 
              '())
            (else            ; if the list is non-empty
             (cons (car lst)     ; cons the first element in the list
                   (my-trim (cdr lst) ))))) ; with the result of advancing the recursion
    

    3 指称语义

    *I1=*I2
    var *I1=&I2
    let var *I1=&I2 in C
    

    (照着I=E和*I=E的语义瞎写的。有没有人来告诉我ppt最后两行是错的,当时就应该问老师的QAQ)

    4 哲学家用餐问题

    一个用synchonized实现的哲学家问题,问会出现什么问题,怎么改进,我正好找到了源码博客[1],和里面的教学思路一致(国内的java并发实现真的找不到标准代码)。

    public class Philosopher implements Runnable {
    
      // The forks on either side of this Philosopher
      private Object leftFork;
      private Object rightFork;
      //引用调用,指向同一个对象,所以可以锁住
      public Philosopher(Object leftFork, Object rightFork) {
        this.leftFork = leftFork;
        this.rightFork = rightFork;
      }
    
      private void doAction(String action) throws InterruptedException {
        System.out.println(
            Thread.currentThread().getName() + " " + action);
        Thread.sleep(((int) (Math.random() * 100)));
      }
    
      @Override
      public void run() {
        try {
          while (true) {
    
            // thinking
            doAction(System.nanoTime() + ": Thinking");
            synchronized (leftFork) {
              doAction(
                  System.nanoTime()
                      + ": Picked up left fork");
              synchronized (rightFork) {
                // eating
                doAction(
                    System.nanoTime()
                        + ": Picked up right fork - eating");
    
                doAction(
                    System.nanoTime()
                        + ": Put down right fork");
              }
    
              // Back to thinking
              doAction(
                  System.nanoTime()
                      + ": Put down left fork. Back to thinking");
            }
          }
        } catch (InterruptedException e) {
          Thread.currentThread().interrupt();
          return;
        }
      }
    
      public static void main(String[] args) throws Exception {
    
        final Philosopher[] philosophers = new Philosopher[5];
        Object[] forks = new Object[philosophers.length];
    
        for (int i = 0; i < forks.length; i++) {
          forks[i] = new Object();
        }
    
        for (int i = 0; i < philosophers.length; i++) {
          Object leftFork = forks[i];
          Object rightFork = forks[(i + 1) % forks.length];
    
          if (i == philosophers.length - 1) {
    
            // The last philosopher picks up the right fork first
            philosophers[i] = new Philosopher(rightFork, leftFork);
          } else {
            philosophers[i] = new Philosopher(leftFork, rightFork);
          }
    
          Thread t = new Thread(philosophers[i], "Philosopher " + (i + 1));
          t.start();
        }
      }
    }
    
    class DiningPhilosophers {
    
    }
    
    

    应该就是这里改的

    5 JAVA多态 终极版

    类似作业里的题 大概长这样,但是里面还试图对内部类进行多态(定义了内部类,private内部类变量,内部类extend父类的内部类,子类通过set内部类实例到父类里)。个人理解内部类无法多态。类似这种

    public class Foo {
    
      public void method1() {
    
    ​    System.out.println("foo 1");
    
      }
    
      public void method2() {
    
    ​    System.out.println("foo 2");
    
      }
    
      public String toString() {
    
    ​    return "foo";
    
      }
    
    }
    
    
    
    public class Baz extends Foo {
    
      public void method1() {
    
    ​    System.out.println("baz 1");
    
      }
    
      public String toString() {
    
    ​    return "baz";
    
      }
    
    }
    
    
    
    public class Mumble extends Baz {
    
      public void method2() {
    
    ​    System.out.println("mumble 2");
    
      }
    
    }
    
    
    
    public static void main(String[] args){
    
      Foo[] pity = {new Baz(), new Bar(), new Mumble(), new Foo()};
    
      for (int i = 0; i < pity.length;i++) {
    
    ​    System.out.println(pity[i]);
    
    ​    pity[i].method1();
    
    ​    pity[i].method2();
    
    ​    System.out.println();
    
      } 
    
    }
    
    
    
    method foo bar Mumble baz
    method1 foo 1 baz 1
    method2 foo 2 bar 2 numble 2
    toString foo baz

    感想

    近年考试比较简单,同学也是这么觉得。课程大作业可以没有代码实现,总之还是算能水过的核心课之一。

    但是要真的掌握,内容太多了,每一章都能作为一节课。

    作用域、闭包、堆栈帧、参数传递、prolog、语法、lambda演算都没考(基本也不是重点,但基础不好的我看了好久)。

    我今天复习的时候真的折磨。java并发的内容是真的多、又不懂java,又不懂并发。


    1. The Dining Philosophers Problem in Java | Baeldung ↩︎

    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    项目目标文档
    河北省民间组织管理系统项目分析
    《探索需求》读书笔记一
    “花儿日记”项目总结
    2015年秋季个人阅读计划
    场景调研
    “数组最大值求和”结对情况
    课堂改进意见
    《梦断代码》阅读笔记三
    linux io 学习笔记(03)---共享内存,信号灯,消息队列
  • 原文地址:https://www.cnblogs.com/SuuT/p/15738340.html
Copyright © 2020-2023  润新知