Набор задач 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;
}
Ответы на викторину
Вам следует попытаться ответить на все приведенные выше вопросы, не заглядывая в ответы. Лучше попросить кого-нибудь о помощи, чем сразу же обращаться за помощью к листу ответов.
Посмотреть ответы на вышеперечисленные задачи можно здесь .