Набор задач 1
Изучите следующую программу, а затем ответьте на вопросы ниже. Мы бы хотели, чтобы вы отвечали на вопросы, просматривая только исходный код, т.е. не копируйте его в файл, не компилируйте и отвечайте на вопросы, основываясь на его запуске. Это лишит вас всего удовольствия!
int main() { int counter, first, last, next; first = 1; last = 2; for (counter = first; counter <= last; counter++) { cout << "\n " << counter; next = counter * counter; cout << " " << next; } counter = first; while (counter <= last) { cout << "\n " << counter; next = counter * counter; cout << " " << next; counter++; } counter = first; do { cout << "\n " << counter; next = counter * counter; cout << " " << next; counter++; } while (counter < last); }
Вопрос 1: Каков результат этой программы?
А) | 1 2 2 4 1 2 2 4 1 2 2 4 |
Б) | 1 1 2 4 1 1 2 4 1 1 2 4 |
С) | 1 1 2 4 1 1 2 4 1 1 |
Д) | 1 1 2 4 1 1 1 1 2 4 |
Е) | Ничего не выводит - есть ошибки в синтаксисе. |
Вопрос 2. Что произойдет, если мы удалим инициализацию «счетчика» перед циклом do- while?
А) | Бесконечный цикл — цикл do- while выводит серию единиц. |
Б) | Вывод программы не изменится |
С) | Цикл do- while выводит 2 и 4. |
Д) | Цикл do- while ничего не выводит |
Е) | Цикл do- while выводит 3 и 9. |
Вопрос 3. Учитывая исходную программу вверху этой страницы, предположим, что мы удалили строку, которая инициализирует переменную счетчика перед циклом while. Что произойдет, если мы также удалим строку counter++ внутри цикла while, как показано ниже?
А) | Цикл while ничего не выводит. |
Б) | Цикл while выводит 1 и 1; цикл do- while ничего не выводит. |
С) | Вывод цикла while такой же, как и при включении обеих строк. |
Д) | Система будет выводить случайные числа, пока мы не выключим компьютер. |
Е) | Цикл while — это бесконечный цикл. |
Вопрос 4. Учитывая исходную программу вверху этой страницы, что произойдет, если цикл while будет выглядеть так?
counter = first; while (counter <= last) { cout << "\n" << counter; if (first % 2 == 0) next = counter * counter; cout << " " << next; counter++; }
А) | Вывод цикла while такой же, как и в исходной программе. |
Б) | Цикл while ничего не выводит |
С) | Выходные данные цикла while — 1 1 и 1 4. |
Д) | Выходные данные цикла while — 1 2 и 2 4. |
Е) | Выходные данные цикла while — 1 4 и 2 4. |
Ф) | Выходные данные цикла while — 2 4 и 2 4. |
Вопрос 5: Что произойдет, если первая переменная больше последней?
А) | Цикл while выведет что-то, но больше ничего. |
Б) | Цикл do while выведет что-то, но больше ничего. |
С) | Выхода не будет вообще. |
Д) | Программа выдаст ошибку или вылетит |
Е) | Цикл for выведет что-то, но больше ничего. |
Вопрос 6. Что выведет программа, если мы инициализируем первую переменную такой же, как и последнюю переменную?
А) | Цикл do while выведет что-то, но больше ничего. |
Б) | Цикл while выведет что-то, но больше ничего. |
С) | Каждый цикл выводит одну строку. |
Д) | Цикл do while выведет 2 строки, а другой — одну строку. |
Е) | Он ничего не выведет |
Ф) | Цикл for выведет что-то, но больше ничего. |
Набор задач 2
Как и в предыдущем наборе задач, вашему вниманию предлагается программа. Пожалуйста, ответьте на следующие вопросы, просматривая только исходный код.
#include <iostream> using namespace std; int main() { int Boys = 3, Girls = 5; void F1(int males, int females); void F2(int &m, int &f); F1(Boys, Girls); cout << "\nAfter calling F1, within main()"; cout << "\n\tBoys = " << Boys; // #2 cout << "\n\tGirls = " << Girls; F2(Boys, Girls); cout << "\nAfter calling F2, within main()"; cout << "\n\tBoys = " << Boys; // #4 cout << "\n\tGirls = " << Girls; } void F1(int b, int g) { b += 3, g += 4; cout << "\nF1"; cout << "\n\tBoys = " << b; // #1 cout << "\n\tGirls = " << g; } void F2(int &b, int &g) { b = b + 8, g = g + 5; cout << "\nF2"; cout << "\n\tBoys = " << b; // #3 cout << "\n\tGirls = " << g; }
Вопрос 1. Каковы выходные данные переменной Boys в отмеченных строках?
А) | №1: 6 №2: 3 №3: 11 № 4: 11 |
Б) | №1: 6 №2: 3 №3: 11 № 4: 3 |
С) | №1: 6 № 2: 6 №3: 11 № 4: 11 |
Д) | Он ничего не выводит, потому что не компилируется и не запускается. |
Вопрос 2: Выберите все, что относится к следующим строкам программы:
void F1(int males, int females); void F2(int &m, int &f);
А) | Правила C++ гласят, что мы можем удалить эти две строки, если методы определены перед использованием. |
Б) | Правила C++ гласят, что имена аргументов в объявлении и определении должны быть одинаковыми. |
С) | Эта программа выйдет из строя, если мы удалим эти две строки. |
Д) | Чаще всего объявления указываются в глобальной области видимости. |
Е) | Это так называемые предварительные объявления. |
Вопрос 3: Если мы переместим следующую строку из main() и поместим ее в глобальную область видимости, что произойдет?
int Boys = 3, Girls = 5;
А) | Результат будет таким же. |
Б) | Мальчики = 3, а девочки = 5 во всех выходных данных. |
С) | Мальчики = 3, а девочки = 5 только в выводе функции main(). |
Вопрос 4: Что, если мы изменим начало программы так:
// We have moved moved these to global scope const int Boys = 3; const int Girls = 5; void main() { //int Boys = 3, Girls = 5;
А) | Программа скомпилируется, но вылетит при попытке запустить ее. |
Б) | Никаких изменений в выводе не будет |
С) | Результатом будет: Мальчики = 3 Девочки = 5 на протяжении всей программы. |
Д) | Результатом будет Boys = 3 Girls = 5 только в выводе main(). |
Е) | Программа, вероятно, не скомпилируется (в зависимости от компилятора). |
Вопрос 5: Данные передаются по значению в F2.
А) | Истинный. |
Б) | ЛОЖЬ. |
Набор задач 3
Как и в предыдущем наборе задач, вашему вниманию предлагается программа. Пожалуйста, ответьте на следующие вопросы, просматривая только исходный код. Этот более интересен, чем два предыдущих — внимательно проследите за кодом.
#include <iostream> using namespace std; const int MAX_SIZE = 20; typedef int ARR2D[MAX_SIZE][MAX_SIZE]; void Print(ARR2D in_array, int rows, int cols); void Fill(ARR2D in_array, int rows, int cols); int main() { ARR2D matrix; int row, col; do { cout << "Please enter the size of the matrix to generate (rows and cols) :" << endl; cin >> row >> col; } while (row <= 0 || row > MAX_SIZE || col <= 0 || col > MAX_SIZE); Fill(matrix, row, col); Print(matrix, row, col); return(0); } void Print(ARR2D in_array, int rows, int cols) { for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) cout << '\t' << in_array[i][j]; cout << endl; } } void Fill(ARR2D in_array, int rows, int cols) { for(int i = 0; i < rows; i++) for (int j = 0; j < cols; j++) in_array[i][j] = 0; const int limit = rows * cols; int cNum = 1; int cRow = 0; int cCol = 0; int cDir = 0; // 0-north, 1-east, 2-south, 3-west while(true) { // Place the number. in_array[cRow][cCol] = cNum; cNum++; if (cNum > limit) break; int fRow = cRow; int fCol = cCol; while (true) { fRow = cRow; fCol = cCol; switch(cDir) { case 0: fRow--; break; case 1: fCol++; break; case 2: fRow++; break; case 3: fCol--; break; } if ( fRow >= 0 && fRow < rows && fCol >= 0 && fCol < cols && in_array[fRow][fCol] == 0) break; cDir = (cDir + 1) % 4; } cRow = fRow; cCol = fCol; } }
Вопрос 1. Что выводит эта программа, если ввести 3 для строк и 4 для столбцов?
А) | 1 2 3 4 5 6 7 8 9 10 11 12 |
Б) | 1 2 3 4 5 6 7 8 9 10 11 12 |
С) | 12 11 10 9 8 7 6 5 4 3 2 1 |
Д) | 1 3 2 4 8 6 7 5 9 11 10 12 |
Е) | 1 2 3 4 10 11 12 5 9 8 7 6 |
Г) | 9 8 7 6 10 11 12 5 1 2 3 4 |
ЧАС) | Ничего не выводит - логика неисправна. |
Я) | Ничего не выводит - есть синтаксические ошибки. |
Дж) | Он ничего не выводит - это не положено. |
К) | Он выводит первые 12 чисел, которые приходят на ум, пока вы ожидаете запуска программы. |
Вопрос 2. Что, если мы добавим следующую строку в нашу функцию main()?
MAX_SIZE = 10;
А) | Это не разрешено в C++. |
Б) | Это разрешено; программа будет работать с параметром MAX_SIZE, равным 20 |
С) | Это разрешено; программа будет работать со значением MAX_SIZE, равным 10. |
Вопрос 3: Рассмотрим следующие четыре строки из приведенной выше программы:
const int MAX_SIZE = 20; typedef int ARR2D [MAX_SIZE][MAX_SIZE]; void Print (ARR2D A, int rows, int cols); void Fill (ARR2D A, int rows, int cols);
1) Можно ли использовать константу в typedef?
2) Можно ли использовать typedef в объявлении до того, как переменная этого типа была объявлена?
А) | 1) Да 2) Да |
Б) | 1) Нет 2) Нет |
С) | 1) Нет 2) Да |
Д) | 1) Да 2) Нет |
Вопрос 4: Можем ли мы использовать следующее:
#define MAX_SIZE 20вместо:
const int MAX_SIZE = 20;
А) | Да, это будет работать, и можно использовать #define для констант в C++. |
Б) | Да, это будет работать, но мы обычно не используем #define для констант в C++. |
С) | #define недоступен в C++. |
Д) | Вы не можете сделать ни одну из этих вещей в C |
Вопрос 5: typedef используется для создания псевдонима для имени типа.
А) | Истинный. |
Б) | ЛОЖЬ. |
Вопрос 6. Что произойдет, если мы не инициализируем массив значением 0 в функции Fill()?
А) | Он будет работать, но на выходе будут все 12. |
Б) | Он будет работать нормально и генерировать тот же результат, как если бы массив был инициализирован значением 0. |
С) | Программа не запускается или вылетает |
Д) | Он будет работать, но на выходе будут все 0. |
Е) | Он будет работать, но может не генерировать никаких результатов |
Вопрос 7: Отметьте все подходящие варианты. Почему в этой программе мы используем const для MAX_SIZE? Не проще ли просто ввести «20» вместо MAX_SIZE там, где это необходимо?
А) | MAX_SIZE — это встроенное значение C++, которое может использовать каждый. Просто установите его и используйте. |
Б) | Глобальных констант следует избегать так же, как и глобальных переменных. |
С) | Использование константы упрощает понимание нашей программы. |
Д) | Магические числа в программе обычно считаются хорошей практикой. |
Е) | Если мы хотим изменить MAX_SIZE, нам нужно изменить его только в одном месте. |
Вопрос 8. Оператор переключения в функции Fill() должен иметь регистр по умолчанию, поскольку его включение считается хорошим стилем.
А) | Истинный. |
Б) | ЛОЖЬ. |
Вопрос 9: Обратите внимание, что в функции Fill() мы объявляем переменные между операторами. Например, cNum и cRow объявляются и инициализируются после выполнения цикла for. Будет ли это работать на C++ или все переменные придется объявлять в начале функции?
А) | Это нормально. |
Б) | Все переменные должны быть объявлены в верхней части функции. |
С) | Оба пути неверны: C++ не допускает использования переменных в любом месте программы. |
Д) | Все переменные должны быть объявлены в глобальной области видимости. |
Набор задач 4
Вот набор файлов, определяющих и тестирующих простой класс. Как обычно, отвечайте на последующие вопросы, ссылаясь только на исходный код.
Вот заголовочный файл (cow.h):
#ifndef COW_H #define COW_H using namespace std; typedef enum Color {black, brown, beige, blackandwhite, nocolor}; class Cow { public: Cow(); ~Cow(); // accessors double weight() { return weight_; }; string name() { return name_; }; Color color() { return color_; }; // mutators void set_name(string inName) { name_ = inName; }; void set_color(Color inColor) { color_ = inColor; }; void set_weight(double inWeight) {weight_ = inWeight; }; void Moo(); void Properties(); private: Color color_; double weight_; string name_; }; #endif
Вот связанный файл .cc (cow.cc):
#include <iostream> #include "cow.h" using namespace std; Cow::Cow() {} Cow::~Cow() {} void Cow::Moo() { cout << name() << " says MOO." << endl; } void Cow::Properties() { cout << name() << " weighs " << weight() << ", is " << color() << " and says MOO." << endl; }
А вот клиентская программа для этого класса (cowmain.cc):
#include <iostream> #include "cow.h" using namespace std; int main() { Cow cow1; cow1.set_name("betsy"); cow1.set_weight(400.0); cow1.set_color(black); cow1.Moo(); cow1.Properties(); }
Вопрос 1: Что выводит эта программа?
А) | Бетси говорит МУ. Бетси весит 400, равна 0 и говорит МУ. |
Б) | Бетси говорит МУ. Бетси весит 400 фунтов, она черная и говорит «МУ». |
С) | Бетси говорит МУ. Бетси весит 400 фунтов |
Вопрос 2. Никогда не следует размещать код методов доступа и мутаторов в заголовочном файле. (Обратите внимание, что аксессор — это метод, который возвращает значение, а мутатор — это метод, который изменяет значение.)
А) | Истинный. |
Б) | ЛОЖЬ. |
Вопрос 3. Нужен ли нам «Cow::» перед каждым определением функции в файле «cow.cc»?
А) | Нет, поскольку файл коровы включен. |
Б) | Да |
Вопрос 4: Какую роль выполняют:
#ifndef COW_H #define COW_H ... #endif
играть в заголовочном файле?
Выберите все, что подходит:
А) | Они бесполезны, поскольку имя файла — корова.h, а не COW_H. |
Б) | Если бы мы этого не сделали, мы бы получили ошибку времени выполнения. |
С) | Если бы мы этого не сделали, мы могли бы включить файл более одного раза. |
Д) | Они ничего не делают, потому что одно или несколько ключевых слов написаны с ошибкой. |
Е) | Они ничего не делают, поскольку класс Cow имеет только один заголовочный файл. |
Вопрос 5. Что произойдет, если мы добавим следующую строку в файлowmain.cc?
cow1.weight_ = 24;
А) | Программа запустится, и эта строка изменит весовую переменную. |
Б) | Программа скомпилировалась и запустилась, но на этой строке произошел сбой. |
С) | С++ этого не позволяет. |
Д) | Программа скомпилируется и запустится, но переменная веса не изменится в этой строке. |
Вопрос 6: При выполнении следующей строки вызывается конструктор класса Cow:
Cow cow1;
Каковы некоторые важные характеристики конструкторов?
Выберите все, что подходит
А) | Обычно они не возвращают никаких значений |
Б) | Если мы не предоставим конструктор в нашем классе, класс не скомпилируется. |
С) | Конструктор класса Cow нетипичен, поскольку он не инициализирует частные переменные. |
Д) | Они всегда имеют то же имя, что и класс. |
Е) | В классе может быть несколько конструкторов, если аргументы различаются. |
Ф) | Конструктор вызывается при создании экземпляра класса. |
Вопрос 7. Каковы некоторые важные характеристики деструктора?
А) | Деструктор вызывается, когда объект выходит за пределы области видимости. |
Б) | Деструктор имеет то же имя, что и класс, но ему предшествует «~». |
С) | Что-то не так с деструктором в файле корова.cc: он ничего не делает. |
Д) | Если мы не создадим деструктор для нашего класса, класс не скомпилируется. |
Вопрос 8. Учитывая то, как клиентская программа использует класс, учтите следующее:
Разделение членов на публичные и частные в классе Cow нецелесообразно. То есть то, что является частным, должно быть публичным, а то, что является публичным, должно быть частным.
А) | Истинный. |
Б) | ЛОЖЬ. |
Вопрос 9: Что, если мы добавим еще один конструктор в дополнение к тому, который у нас есть в коровьем.cc. Новый конструктор выглядит так
Cow::Cow(string inName, double inWeight, Color inColor) { set_name(inName); set_weight(inWeight); set_color(inColor); }
И мы добавляем следующие строки в main():
Cow cow2("milly", 350.2, brown); cow2.Moo(); cow2.Properties();
Можем ли мы это сделать?
Выберите все, что подходит
А) | Строка в main(), где мы инициализируем корову2, выйдет из строя. |
Б) | У нас может быть только один конструктор. |
С) | Это обычное явление в C++ |
Д) | Да, но это не типичное использование C++. |
Е) | Это будет работать нормально, но ничего не выведет, потому что приваты не инициализированы. |
Ф) | Мы не можем вызвать setName(), setColor() и setWeight() из метода того же класса. |
Бонусные вопросы
Вопрос 1) Каков результат следующего?
#include <iostream> using namespace std; void HelpMe(int *p, int *num, int *q); void WhereAmI(int *p, int *q, int a); void HelpMe(int *p, int *num, int *q) { int a; a = 2; q = &a; *p = *q + *num; num = p; } void WhereAmI(int *p, int *q, int a) { a = 6; *p = a + *p; *q = a + 3; HelpMe(q, &a, p); } int main() { int *p; int q; int *num; int a; a = 3; q = 5; p = &a; num = &q; HelpMe(&a, p, num); WhereAmI(&q, p, *num); cout << "*p = " << *p << " q = " << q << " *num = " << *num << endl; }
Вопрос 2) Рассмотрим следующее утверждение, предполагая, что класс Apple существует и инициализирован. Класс Apple имеет переменную экземпляра color_:
Apple* granny_smith = new Apple;
Выберите все утверждения ниже, которые верны:
А) | Apple* granny_smith = NULL; if (granny_smith == NULL)... Это НЕ нормально: NULL не является значением, которое можно проверить таким способом. |
Б) | Apple* granny_smith, Фудзи; Это объявляет два указателя на объекты Apple. |
С) | Переменная granny_smith содержит значения переменных экземпляра, связанные с объектом Apple. |
Д) | Apple* granny_smith = NULL; Это нормально, |
Е) | Переменная granny_smith содержит адрес объекта Apple. |
Ф) | строка gs_color = *(granny_smith.get_color()); Этот оператор возвращает цвет объекта granny_smith, предполагая, что он был инициализирован. |
Г) | Память для нового объекта Apple выделяется в куче. |
ЧАС) | Память для нового объекта Apple выделяется в стеке времени выполнения. |
Я) | интервал* а = &b; Это помещает адрес b в адрес a. |
Вопрос 3) Каков результат выполнения следующей программы?
#include <iostream> using namespace std; const int kNumVeggies = 4; void Grill(int squash, int *mushroom); int Saute(int onions[], int celery); void Grill(int squash, int *mushroom) { *mushroom = squash/4; cout << *mushroom + squash << endl; } int Saute(int onions[], int celery) { celery *= 2; onions[celery]++; Grill(onions[0], &onions[3]); cout << celery << " " << onions[3] << endl; return celery; } int main() { int broccoli, peppers[kNumVeggies], *zucchini; for (broccoli = 0; broccoli < kNumVeggies; broccoli++) peppers[broccoli] = kNumVeggies - broccoli; zucchini = &peppers[Saute(peppers,1)]; Grill(*zucchini, zucchini); zucchini--; cout << peppers[3] + *zucchini + *(zucchini + 1) << endl; }
Ответы на викторину
Вам следует попытаться ответить на все приведенные выше вопросы, не заглядывая в ответы. Лучше попросить кого-нибудь о помощи, чем сразу же обращаться за помощью к листу ответов.
Посмотреть ответы на вышеперечисленные задачи можно здесь .