國立暨南國際大學 104 學年度第二學期 期末考試卷

科目名稱:程式設計 開課系所:資訊工程 學系 考試日期 2016.6.23
系所別:
年級:
學號:
姓名:
考試時間 08:30-10:30
1


2
3  
4
5  
6  
7
8  
9  
10
11
12
13  
14
15  
16  
17
18  
19  
20
  1. (5%) Explain the following terminologies:
    1. static variable of a function
    2. static function of a class
    3. signature of a function
    4. default copy constructor
    5. operator overloading

  2. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // Fundamental Data Types (P.45)
    // The sizeof Operator (P.154)
    #include <iostream>
    using std::cout;
    using std::endl;

    int main()
    {
       char a = 1;
       unsigned char b = 2;
       short c = 3;
       double d = 4.0;
      
    unsigned short e = 5;
       float f = 6.0f;

       cout << sizeof(a)*sizeof(a) + sizeof(b)*sizeof(b) +
           sizeof(c)*sizeof(c) + sizeof(d)*sizeof(d) +
           sizeof(e)*sizeof(e) + sizeof(f)*sizeof(f) << endl;
       return 0;
    }


  3. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // Map (P.548)
    #include <iostream>
    #include <map>
    using std::map;
    using std::cout;
    using std::endl;

    int main()
    {
        const int digit[] = {1, 4, 2, 8, 5, 7};
        map<int,int> a;
        for (int i=0; i<=4; i++)
            a.insert(std::make_pair(digit[i], digit[i+1]));

        if (a.find(4) != a.end())
        {
            int number = a[4];
            cout << "The number is " << number << endl;
        }
        else
        {
            cout << "No number for the key" << endl;;
        }
        return 0;
    }


  4. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // for Loop (P.140)
    // hex2dec
    #include <iostream>
    #include <cstring>
    using std::cout;
    using std::endl;

    int hex2dec(const char* s)
    {
        unsigned int sum = 0;
        unsigned int n;
        for (int i=0; i<strlen(s); i++)
        {
            n = static_cast<unsigned int>(*(s+i))-48;
            if (n>9)
                n -= 7;
            if (n>=42)
                n -= 32;
            sum += sum * 16 + n;
        }
        return sum;
    }

    int main()
    {
        cout << hex2dec("9") << endl
             << hex2dec("F") << endl
             << hex2dec("20") << endl
             << hex2dec("FF") << endl
             << hex2dec("a") << endl
             << hex2dec("fe") << endl;
        return 0;
    }


  5. (5%) Suppose you compile and run the following code on a 64-bit computer (e.g. STU.ipv6.club.tw).  What will be its output?

    // Pointers to char (P.150)
    // sizeof (P.154)

    #include <iostream>
    using std::cout;
    using std::endl;

    int main()
    {
        const char name[][9] = { "Alice", "Bob", "Charlie", "Dennis", "Emily" };
        const char* pstr[] = { "Alice", "Bob", "Charlie", "Dennis", "Emily" };

        cout << sizeof(name) << '\t'
                << sizeof(pstr[3]) << '\t'
                << sizeof(pstr[3][2]) << endl;
        cout << sizeof(pstr) << '\t'
                << pstr[3] << '\t'
                << *(pstr[3] + 2) << endl;
        return 0;
    }


  6. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // Type Conversion (P.64)
    // switch (P.105)

    #include <iostream>
    using std::cout;

    int main()
    {
        int even = 0, odd = 0;
        char str[] = "TAITUNG"; // 'A' == 65
        for (int i=0; i<sizeof(str) / sizeof(str[0]) / 2; i++)
            switch ( str[i] % 2 )
            {
                case 0:
                    even++;
                case 1:
                    odd++;
            }
        cout << "odd = " << odd << '\n'
             << "even = " << even << '\n';
        return 0;
    }




  7. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // Initialize an Array (P.172)
    // Increment Operator (P.59)

    #include <iostream>
    using std::cout;

    int main()
    {
        int data[7] = { 5 * 7 };
        int i;
        for (i=0; i<7; ++i)
            data[i] += i++;
        for (i=0; i<7; i++)
            cout << data[i];
        return 0;
    }

  8. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).

    // continue (P.116) vs. break (P.115)
    #include <iostream>

    int main()
    {
        const int K = 5;
        int count = 0;
        int i, j;
        for (i=1; i<K; i++)
        {
            if (i==3) continue;
            ++count;
        }

        for (j=1; j<K; j++)
        {
            if (3 == j) break;
            ++count;
        }
        std::cout << count << '\t' << i << '\t' << j << std::endl;
        return 0;
    }

  9. (5%) Determine whether the following code has syntax errors or
        not.  If it is correct, predict its output.  If it is
        incorrect, point out the
        mistake(s).

    // Short-Circuit
    #include <iostream>
    using std::cout;
    using std::endl;

    int main()
    {
    int i, j, n = 0, m = 0;
    for (i=0; i<10; i++)
    for (j=0; j<10; j++)
    if (i<++j && n++ > 0)
    m++;
    cout << n << m << endl;
    return 0;
    }

  10. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Math Library
    // Type Conversion (P.63)

    #include <iostream>
    #include <cmath>
    using std::cout;
    using std::endl;

    int main()
    {
    cout << (21/6)+1 << '\t'
    << ceil(21/6)+1 << '\t'
    << (-21/6)+1 << '\t'
    << ceil(-21/6)+1 << '\t'
    << (-21.0/6)+1 << '\t'
    << ceil(-21.0/6)+1 << '\n';
    return 0;
    }

  11. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Pass by Reference
    #include <iostream>

    using std::cout;

    void swap1(int a, int b)
    {
      int temp;
      temp = a; a = b; b = temp;
    }

    void swap2(int* a, int* b)
    {
      int temp;
      temp = *a; *a = *b; *b = temp;
    }

    void swap3(int& a, int b)
    {
      int temp;
      temp = a; a = b; b = temp;
    }

    void print(int a, int b)
    {
        cout << a << '\t' << b << '\n';
    }

    int main()
    {
        int x = 6;
        int y = 23;
        swap1( x,  y); print(x, y);
        swap2(&x, &y); print(x, y);
        swap3(x, y); print(x, y);
        return 0;
    }

  12. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Transposition Cipher - Scytale
    // The input key specifies the diameter of the scytale

    #include <iostream>
    #include <cstring>
    #include <cmath>
    using std::cin;
    using std::cout;
    using std::endl;

    #define MAX_WIDTH 9
    #define MAX_MESSAGE_LENGTH 200

    void decrypt(char* ciphertext, char* plaintext, int key);

    int main()
    {
    char matrix[MAX_WIDTH * MAX_WIDTH + 1];
    char plaintext[ MAX_MESSAGE_LENGTH];

    char ciphertext[ MAX_MESSAGE_LENGTH ] =
    "Al stmiit enteIre rnisf tc oieatunrnhnfn idleAn itikfg.rsahA";
    char *p = plaintext;
    unsigned key = 5;

    decrypt(ciphertext, plaintext, key);
    std::cout << plaintext << '\n';
    return 0;
    }

    void decrypt(char* ciphertext, char* plaintext, int height)
    {
    char* pc = plaintext;
    int i, j, offset = 0;
    int length = strlen(ciphertext);
    int width = ceil(1.0 * length / height);

    for (j=0; j<width; j++)
    for (i=0; i<height; i++)
    {
    plaintext[i * width + j] = ciphertext[i + height * j] ;
    }
    plaintext[ width * height ] = '\0';
    }
  13. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Destructor
    #include <iostream>
    using std::cout;
    using std::endl;

    class CData
    {
    public:
    int* pdata;

    CData(int n=0)
    {
    pdata = new(int);
    *pdata = n;
    }

    ~CData()
    {
    cout << *pdata << endl;
    delete pdata;
    }
    };


    int main()
    {
    CData a(3);
    CData b(5);
    CData c(7);
    return 0;
    }
  14. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Dynamically allocated objects
    #include <iostream>
    using std::cout;
    using std::endl;

    class CData
    {
    public:
    int* pdata;

    CData(int n=0)
    {
    pdata = new(int);
    *pdata = n;
    }

    ~CData()
    {
    cout << *pdata << endl;
    delete pdata;
    }
    };


    int main()
    {
    CData a(3);
    CData* b = new CData(5);
    CData c(7);
    c = *b;
    return 0;
    }
  15. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Pass an object to a function
    // Copy Constructor

    #include <iostream>
    using std::cout;
    using std::endl;

    class CData
    {
    public:
    int data;

    CData(int n=0)
    {
    data = n;
    }

    ~CData()
    {
    cout << data << endl;
    }
    };

    int add(CData n)
    {
    int sum = 0;
    sum += n.data;
    return sum;
    }

    int main()
    {
    CData a(3);
    CData b(5);
    add(a);
    add(b);
    return 0;
    }
  16. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Swap two rational numbers
    #include <iostream>
    using std::cout;
    using std::endl;
    using std::ostream;

    class CRational
    {
    friend ostream& operator<<(ostream& os, CRational a) // P.300
    { os << a.numerator << "/" << a.denominator;
    return os;
    }

    private:
    int numerator;
    int denominator;

    public:
    CRational(int p, int q) : numerator(p), denominator(q) {}

    void swap(CRational& b)
    {
    CRational a = *this;
    CRational temp = a;
    a = b;
    b = temp;
    }
    };

    int main()
    { CRational a(3, 2);
    CRational b(1, 7);
    cout << a << "\t" << b << endl;
    a.swap(b);
    cout << a << "\t" << b << endl;
    }
  17. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Racing Horse
    #include <iostream>
    #include <cstring>
    using std::cout;
    using std::endl;

    int main()
    {
    char horse_string[40] = "~/-\\^";
    char input_string[40] = "Alice";
    int i, horse_string_length;

    for (i=0, horse_string_length=0; i<strlen(input_string); i++, horse_string_length++)
    {
    if (input_string[i] == '\\')
    {
    horse_string[horse_string_length++] = '\\';
    }
    horse_string[horse_string_length++] = input_string[i++];
    }
    horse_string[horse_string_length] = '\0';

    cout << horse_string << endl;
    return 0;
    }
  18. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Operator Overloading (P.331)
    #include <iostream>

    class CRational
    {
    int numerator;
    int denominator;
    public:
    CRational(int n, int d): numerator(n), denominator(d) {}

    bool operator<(CRational b)
    {
    if (numerator / denominator < b.numerator / b.denominator)
    return true;
    else
    return false;
    }
    };

    int main()
    {
    CRational a(2,3), b(3,4);
    std::cout << (a<b?"a<b":"a>=b") << std::endl;
    return 0;
    }
  19. (5%) Determine whether the following code has syntax errors or not.  If it is correct, predict its output.  If it is incorrect, point out the mistake(s).
    // Prime Generator
    /*
    * This class Generates prime numbers up to a user specififed
    * maximum. The algorithm used is the Sieve of Eratosthenes.
    * Given an array of integers starting at 2:
    * Find the first uncrossed integer, and cross out all its
    * multiples. Repeat until there are no more multiples
    * in the array.
    */

    #include <iostream>
    #include <cmath>
    #include <vector>

    using std::cout;
    using std::endl;
    using std::vector;

    class PrimeGenerator
    {
    private:
    vector<bool> crossedOut;
    vector<int> result;

    public:
    vector<int> generatePrimes(int maxValue)
    {
    if (maxValue > 2)
    {
    uncrossIntegersUpTo(maxValue);
    crossOutMultiples();
    putUncrossedIntegersIntoResult();
    }
    return result;
    }

    int show()
    {
    for (int i=0; i<result.size(); i++)
    cout << result.at(i)
    << (i==result.size()-1?'\n':' ');
    return result.size();
    }

    private:
    void uncrossIntegersUpTo(int maxValue)
    {
    for (int i=0; i<maxValue+1; i++)
    crossedOut.push_back(false);
    }

    void crossOutMultiples()
    {
    int limit = determineIterationLimit();
    for (int i=2; i<=limit; i++)
    if (notCrossed(i))
    crossOutMultiplesOf(i);
    }

    int determineIterationLimit()
    {
    // Every multiple in the array has a prime factor that
    // is less than or equal to the root of the array size,
    // so we don't have to cross out multiples of numbers
    // larger than that root.

    double iterationLimit = sqrt(crossedOut.size() );
    return static_cast<int>( iterationLimit );
    }

    void crossOutMultiplesOf(int i)
    {
    for (int multiple = 2*i; multiple < crossedOut.size(); multiple += i)
    crossedOut.at(multiple) = true;
    }

    bool notCrossed(int i)
    {
    return crossedOut.at(i) == false;
    }

    void putUncrossedIntegersIntoResult()
    {
    result.resize( numberOfUncrossedIntegers() );
    for (int j=0, i=2; i<crossedOut.size(); i++)
    if ( notCrossed(i) )
    result.at(j++) = i;
    }

    int numberOfUncrossedIntegers()
    {
    int count = 0;
    for (int i=2; i<crossedOut.size(); i++)
    if ( notCrossed(i) )
    count++;

    return count;

    }
    };

    int main()
    {
    PrimeGenerator p, q;
    p.generatePrimes(10);
    p.show();
    q.generatePrimes(15);
    q.show();
    p.generatePrimes(20);
    p.show();

    return 0;
    }
  20. (5%) If we replace the OnDraw() function in P.669 as below, what result will be shown on the screen after you run the program? Please specify the coordinates of endpoints of each segment, or the coordinates of centers and boundaries.
    // CView::OnDraw()  (P.669)
    void CSketcherView::OnDraw(CDC* pDC)
    {
    CSketcherDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
    return;

    const int k = 10;
    for (int i=5; i>=1; i--)
    pDC->Rectangle(i*k, i*k, (10-i)*k, (10-i)*k );
    }