К основному контенту

Прата С. Решение 7 главы

Немного грустно, но я пока что прекращаю работу над плюсами. Решила осваивать джаву. Это последняя глава по Прате над которой я работала. Сейчас читаю Файна, учебник элементарный, но ознакамливает с синтаксисом джавы, ибо строгий слог Хорстманна сразу так сходу, как я рассчитывала, не пошел.




1.  Напишите программу, которая многократно запрашивает у пользователя пару чисел до тех пор, пока хотя бы одно из этой пары не будет равно 0. С каж­дой парой программа должна использовать функцию для вычисления среднего гармонического этих чисел. Функция должна возвращать ответ main () для ото­бражения результата. Среднее гармоническое чисел — это инверсия среднего значения их инверсий; она вычисляется следующим образом:
среднее гармоническое -2.0*х*у/ (х+у)
2.  Напишите программу, которая запрашивает у пользователя 10 результатов игры в гольф, сохраняя их в массиве. При этом необходимо обеспечить возможность прекращения ввода до ввода всех 10 результатов. Программа должна отобразить псе результаты в одной строке и сообщить их среднее значение. Реализуйте ввод, отображение и вычисление среднего в трех отдельных функциях, рабо­тающих с массивами.
364 Глава 7                                                                                                                ,
3.  Пусть имеется следующее объявление структуры:
struct box (
char maker[40); float height; float width; float length; float volume;
);
а. Напишите функцию, принимающую структуру box по значению и отображаю­щую все ее члены.
б. Напишите функцию, принимающую адрес структуры box и устанавливающую значение члена volume равным произведению остальных трех членов.
в.  Напишите простую программу, которая использует эти две функции.
4.  Многие лотереи в США организованы подобно той, что была смоделирована в листинге 7.4. Во всех их вариациях вы должны выбрать несколько чисел из одного набора, называемого полем номеров. (Например, вы можете выбрать 5 чисел из поля 1-47.) Вы также указываете один номер (называемый мсганомс- ром) из второго диапазона, такого как 1-27. Чтобы выиграть главный приз, вы должны правильно угадать все номера. Шанс выиграть вычисляется как всро ятность угадывания всех номеров в поле, умноженная на вероятность угадыва­ния меганомера. Например, вероятность выигрыша в описанном здесь приме­ре вычисляется как вероятность угадывания 5 номеров из 47, умноженная на вероятность угадывания одного номера из 27. Модифицируйте листинг 7.4 для вычисления вероятности выигрыша в такой лотерее.
5.  Определите рекурсивную функцию, принимающую целый аргумент и возвра­щающую его факториал. Вспомните, что факториал 3 записывается, как 3! и вычисляется как 3x2! и т.д., причем 0! равно 1. В общем случае, если п больше нуля, то n! = п * (п-1) !. Протестируйте функцию в программе, использующей цикл, где пользователь может вводить различные значения, для которых про­грамма вычисляет и отображает факториалы.
6.  Напишите программу, использующую описанные ниже функции.Fill array () принимает в качестве аргумента имя массива элементов типа double и размер этого массива. Она приглашает пользовате­ля ввести значения double для помещения их в массив. Ввод прекращается при наполнении массива либо когда пользова­тель вводит нечисловое значение и возвращает действитель­ное количество элементов.Show array () принимает в качестве аргументов имя массива значений double, а также его размер, и отображает содержимое массива.Reverse_array () принимает в качестве аргумента имя массива значений double, а также его размер, и изменяет порядок его элемен­тов на противоположный.
Программа должна использовать эти функции для наполнения массива, обра­щения порядка его элементов, кроме первого и последнего, с последующим отображением.
7.   Вернитесь к программе из листинга 7.7 и замените три функции обработки мас­сивов версиями, которые работают с диапазонами значений, заданными парой указателей. Функция fill array () вместо возврата действительного количест­ва прочитанных значений должна возвращать указатель на место, следующее за последним введенным элементом; прочие функции должны использовать его в качестве второго аргумента для идентификации конца диапазона данных.
8.   Вернитесь к программе из листинга 7.15, не использующей класс array. Напи­шите следующие две версии.
а. Используйте обычный массив из const char * для строковых представлений времен года и обычный массив из double для расходов.
б. Используйте обычный массив из const char * для строковых представле­ний времен года и структуру, единственный член которой является обычным массивом из double для расходов. (Это очень похоже на базовое проектное решение для класса array.)
9.   Следующее упражнение позволит попрактиковаться в написании функций, ра­ботающих с массивами и структурами. Ниже представлен каркас программы. Дополните его функциями, описанными в комментариях.
♦include <iostream> using namespace std;
const int SLEN - 30; struct student {
char fullname(SLEN); char hobby(SLEN]; int ooplevel;
);
// getinfoO принимает два аргумента: указатель на первый элемент // массива структур student и значение int, представляющее // количество элементов в массиве. Функция запрашивает и // сохраняет данные о студентах. Ввод прекращается либо после // наполнения массива, либо при вводе пустой строки в качестве // имени студента. Функция возвращает действительное количество // введенных элементов, int getinfо(student pa[), int n);
// displaylO принимает в качестве аргумента структуру student //и отображает ее содержимое, void displayl(student st);
// display2() принимает адрес структуры student в качестве аргумента // и отображает ее содержимое, void display2(const student * ps);
// display3() принимает указатель на первый элемента массива // структур student и количество элементов в этом массиве и // отображает содержимое всех структур в массиве, 
void display3(const student pa[], int n);
int main()
1
cout « "Enter class size: "; int class_size; ein >> class_size; while (cin.getO != '\n') continue;
student * ptr_stu = new student(class_size); int entered = getinfo(ptr_stu, class_size); for (int i = 0; i < entered; i + + )
displayl(ptr_stu(i) ) ; display2(6ptr_stu[i)) ;
)
display3(ptr_stu, entered); delete () ptr_stu; cout << *'Done\n"; return 0;
)
10.  Спроектируйте функцию calculate (), которая принимает два значения типа double и указатель на функцию, принимающую два аргумента double и воз­вращающую значение double. Функция calculated также должна иметь тип double и возвращать значение, вычисленное функцией, которая задана указа­телем, используя аргумент double функции calculate ( ). Например, предполо­жим, что имеется следующее определение функции add О :
double add(double х, double у)
< 
return х + у;
)
Приведенный ниже вызов функции должен заставить calculate () передать значения 2.5 и 10.4 функции add ( ) и вернуть ее результат (12.9): double q - calculate(2.5, 10.4, add);
Используйте в программе эти функции и еще хотя бы одну дополнительную, ко­торая подобна add(). В программе должен быть организован цикл, позволяю­щий пользователю вводить пары чисел. Для каждой пары calculate О должна вызвать add ( ) и хотя бы еще одну функцию такого рода. Если вы чувствуете себя уверенно, попробуйте создать массив указателей на функции, подобные add (), и организуйте цикл, применяя calculate () для вызова этих функций по их указателям. Подсказка: вот как можно объявить массив из трех таких ука­зателей:
double (*pf[3])(double, double);

Инициализировать такой массив можно с помощью обычного сшггаксиса ини­циализации массивов и имен функций в качестве адресов.

1



#include "stdafx.h"
#include<iostream>
using namespace std;

double harmonic_mean (int, int);

void main() 
{
int x, y;
do
{
cout << "Enter 2 numbers" << endl;
cin >> x >> y;
cout << "harmonic mean: " << harmonic_mean (x, y) << endl;
}
while (x!=0 && y!=0 );
}

double harmonic_mean (int x, int y)
{
return (2.0 * x * y / (x+y));
}






2


#include "stdafx.h"
#include<iostream>
using namespace std;
const int SIZE = 10;

int get (int[], int);
void display (double);
double mean (int[], int);

void main() 
{
double MEAN;
int golf[SIZE], limit;
limit = get(golf, SIZE);
MEAN = mean(golf, limit);
display(MEAN);
}
int get (int golf[], int limit)
{
int temp, i;
for (i = 0; i < limit; i++)
{
cout  << "\nEnter " << i+1 << " result ";
cin >> temp;
if (!cin) //если неправильный ввод
{
cin.clear(); //очистка буфера
while (cin.get() != '\n') //пока в буфере не попадется знак ввода
continue; //запуск цикла очистки сначала
cout << "Bad input. \n" << endl; 
break; //прерывание всего цикла for
}
else if (temp<0)
break; //прерывание всего цикла for
golf[i] = temp;
}
return i; // возврат уоличества введенных элементов в массив
};

double mean (int golf[], int limit)
{
int sum = golf[0];
for (int i = 1; i < limit; i++)
sum += golf[i];
return sum/limit;
};

void display (double mean)
{
cout << "Mean: " << mean << endl;
}




3




#include "stdafx.h"
#include<iostream>
using namespace std;

struct Box
{
char maker[40];
float height;
float wifth;
float length;
float volume;
};

void display_value(Box);
void display_adress(Box*);

void main() 
{
Box box1 = {"maker1", 1, 2, 3, 4}, box2 = {"maker2", 5, 6, 7, 8};
display_value(box1);
display_adress(&box2);
}

void display_value (Box box)
{
cout << box.maker << endl << box.height << endl << box.wifth << endl << box.length << endl << box.volume << endl;
};

void display_adress ( Box *box)
{
cout << box->maker << endl << box->height << endl << box->wifth << endl << box->length << endl << box->volume << endl;
}



4



#include "stdafx.h"
#include<iostream>
using namespace std;

long double probability(unsigned numbers, unsigned picks);
void main()
{
double total, total2, choices;
    cout << "Enter the total number of choices on the game card,\n"
            "the number of picks allowed \nand the total number of choices on the second game field \n";
while ((cin >> total >> choices >> total2) && choices <= total)
    {
        cout << "You have one chance in ";
        cout << probability(total, choices) * probability(total2, 1);      // compute the odds
        cout << " of winning.\n";
        cout << "Next three numbers (q to quit): ";
    }
    cout << "bye\n";
}

// the following function calculates the probability of picking picks
// numbers correctly from numbers choices
long double probability(unsigned numbers, unsigned picks)
{
    long double result = 1.0;  // here come some local variables
    long double n;
    unsigned p;

    for (n = numbers, p = picks; p > 0; n--, p--)
        result = result * n / p ; 
    return result;
}


5




#include "stdafx.h"
#include<iostream>
using namespace std;

long long factorial(long long, long long);

void main()
{
long long num, fact;
cout << "Enter num (Press any letter to exit)" << endl;
while (cin >> num)
{
fact = factorial(num, num);
cout << num << "! = " << fact <<endl;
}
cout << "Bye!" << endl;
}

long long factorial (long long n, long long fact)
{
if (n == 0)
return 1;

while (n > 1)
{
fact *= (n-1);
n--;
factorial (n, fact);
}
return fact;
}



6




#include "stdafx.h"
#include<iostream>
using namespace std;
const int MAX = 5;

int fill_array(double[], int);
void show_array(double[], int);
void reverse_array(double[], int);


void main()
{
double arr[MAX];
int n;
n = fill_array(arr, MAX);
show_array(arr, n);
reverse_array(arr, n);
show_array(arr, n);
}

int fill_array(double arr[], int MAX)
{
int temp, i;
for (i = 0; i < MAX; i++)
{
cout  << "\nEnter " << i+1 << " num ";
cin >> temp;
if (!cin) //если неправильный ввод
{
cin.clear(); //очистка буфера
while (cin.get() != '\n') //пока в буфере не попадется знак ввода
continue; //запуск цикла очистки сначала
cout << "Bad input. \n" << endl; 
break; //прерывание всего цикла for
}
else if (temp<0)
break; //прерывание всего цикла for
arr[i] = temp;
}
return i; // возврат количества введенных элементов в массив
}

void show_array(double arr[], int n)
{
for (int i = 0; i < n; i++)
cout << "arr[" << i+1 << "] = " << arr[i] << endl;
}

void reverse_array(double arr[], int n)
{
double temp;
for (int i = 0; i < (n/2); i++)
{
if (i == 0)
continue;
temp = arr[i];
arr[i] = arr[n-i-1];
arr[n-i-1] = temp;
}
}






7




#include "stdafx.h"
#include <iostream>
const int Max = 5;

double* fill_array(double *begin, double *end); //функция возвращает указатель на последний элемент массива
void show_array (double *begin, double *end);  
void revalue(double, double *begin, double *end);

int main()
{
    using namespace std;
    double properties[Max];

double *end = fill_array(properties, properties+Max); // название массива=указатель на первый элемент, название+число = элемент массива[число], находим последний эллемент массива и присваеваем адрес указателю end
    show_array(properties, end); // теперь можно смело пользоваться указателем на первый и последний элемент
if ((end - properties) > 0) // при отнимании результат - целочисленное значение = количеству єлементов в массиве
    {
        cout << "Enter revaluation factor: ";
        double factor;
        while (!(cin >> factor))    // bad input
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
           cout << "Bad input; Please enter a number: ";
        }
        revalue (factor, properties, end);
        show_array(properties, end);
    }
    cout << "Done.\n";
    return 0;
}

double* fill_array(double *begin, double *end)
{
    using namespace std;
double temp;
double *pt; // создаем временный указатель
int i = 1;
for (pt = begin; pt != end; pt++, i++) // присваиваем ему начало массива, цикл до последнего элемента, увеличение указателя на 1 = перемещение на следующий элемент массива
    {
        cout << "Enter value #" << i << ": ";
        cin >> temp;
        if (!cin)    // bad input
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
           cout << "Bad input; input process terminated.\n";
           break;
        }
        else if (temp < 0)   
            break;
*pt = temp; // разыменовываем указатель и присваеваем ему значение 
    }
    return pt; // возвращаем указатель, который остановился на последнем возможном элементе
}

void show_array(double *begin, double *end)
{
    using namespace std;
    double *pt; 
int i = 1;
for (pt = begin; pt != end; pt++, i++)
{
        cout << "Property #" << i << ": $";
        cout << *pt << endl;
    }
}

void revalue(double r, double *begin, double *end)
{
    double *pt;
for (pt = begin; pt != end; pt++)
       *pt *= r;
}




8


#include "stdafx.h"
#include <iostream>
using namespace std;
const int Seasons = 4;
const char Snames [Seasons][7] =
    {"Spring", "Summer", "Fall", "Winter"};

void fill (const char[][7], double[]);
void show (const char[][7], double[]);
int main()
{
    double expenses[4];
fill(Snames, expenses);
show (Snames, expenses);
    return 0;
}

void fill (const char Snames[][7], double* expenses)
{
    for (int i = 0; i < Seasons; i++)
    {
        cout << "Enter " << Snames[i] << " expenses: ";
cin >> expenses[i];
    }
}

void show(const char Snames[][7], double *expenses)
{
    double total = 0.0;
    cout << "\nEXPENSES\n";
    for (int i = 0; i < Seasons; i++)
    {
        cout << Snames[i] << ": $" << expenses[i] << '\n';
        total += expenses[i];
    }
    cout << "Total: $" << total << '\n';
}



////////////////////////////////////////////////////////////






#include "stdafx.h"
#include <iostream>
using namespace std;
const int Seasons = 4;
const char Snames [Seasons][7] =
    {"Spring", "Summer", "Fall", "Winter"};

struct Expenses
{
double expenses[4];
};

void fill (const char[][7], Expenses*); // при передаче двумерного массива в функцию следует использовать такую форму, при передаче структуры в функцию и для возможности ее изменения следует использовать указатель
void show (const char[][7], Expenses*);
int main()
{
Expenses exp;
fill(Snames, &exp); // передаем название двумерного массива и ссылку на объект структуры
show (Snames, &exp);
    return 0;
}

void fill (const char Snames[][7], Expenses *exp) 
{
    for (int i = 0; i < Seasons; i++)
    {
        cout << "Enter " << Snames[i] << " expenses: ";
cin >> exp->expenses[i]; // !!! работа с указателем на структуру
    }
}

void show(const char Snames[][7], Expenses *exp)
{
    double total = 0.0;
    cout << "\nEXPENSES\n";
    for (int i = 0; i < Seasons; i++)
    {
        cout << Snames[i] << ": $" << exp->expenses[i] << '\n';
        total += exp->expenses[i];
    }
    cout << "Total: $" << total << '\n';
}




9




#include "stdafx.h"
#include <iostream>
using namespace std;

const int SLEN = 30;

struct Student
{
char fullname[SLEN];
char hobby [SLEN];
int ooplevel;
};
int getinfo (Student*, int); // передача указателя на массив структур, возвращение количества элементов
void display1 (Student);
void display2 (const Student *); // передача ссылки на структуру как элемент массива только для отображения
void display3 (const Student[], int); // передача указателя на массив структур только для отображения

int main()
{
cout << "Enter class size: ";
int class_size;
cin >> class_size;
while (cin.get() !='\n')
continue;
Student * ptr_stu = new Student[class_size];
int entered = getinfo(ptr_stu, class_size);// передача указателя на массив структур
for (int i = 0; i < entered; i++)
{
display1(ptr_stu[i]);
display2 (&ptr_stu[i]);// передача ссылки на структуру как элемент массива
}
display3(ptr_stu, entered);// передача указателя на массив структур
delete[] ptr_stu;
cout << "Done \n";
}

int getinfo (Student pa[], int n)
{
int i;
cout << "to stop the entry under 'name' leave empty" << endl;
for (i = 0; i < n; i++)
{
cout << "Enter name" << endl;
cin >> pa->fullname;
if(pa->fullname[0] == 'q')
break; //прерывание всего цикла for

cout << "Enter hobby" << endl;
cin >> pa->hobby;

cout << "Enter oop level" << endl;
cin >> pa->ooplevel;
pa++; // увеличение копии указателя
}
return i; // возврат количества введенных элементов в массив
};
void display1 (Student st)
{
cout << "Name: " << st.fullname << endl;
cout << "Hobby: " << st.hobby << endl;
cout << "OOP Level: " << st.ooplevel << endl;
};
void display2 (const Student *ps)
{
cout << "Name: " << ps->fullname << endl;
cout << "Hobby: " << ps->hobby << endl;
cout << "OOP Level: " << ps->ooplevel << endl;
};
void display3 (const Student pa[], int n)
{
for (int i = 0; i < n; i++)
{
cout << "Name: " << pa->fullname << endl;
cout << "Hobby: " << pa->hobby << endl;
cout << "OOP Level: " << pa->ooplevel << endl;
pa++; // увеличение копии указателя
}
};




Комментарии

Отправить комментарий

Популярные сообщения из этого блога

Прата С. Решение задач 6 главы

На решение этих задач у меня ушло 2 дня. Становится все интереснее и интереснее! и черт возьми, я наконец-то поняла работу с файлами! прошу прощения за корявые условия. просто в нормальном формате электронной книги у меня нет, потому скрины задач просто пропущены через Файнридер.

Прата С. решение задач 5 главы

Эта глава по циклам меня удивила. я  с неким пренебрежением отнеслась к ней, т.к. думала что и так все знаю по этой теме. но Прата так глубоко и в подробностях объяснил тему, что я заново переосмыслила циклы и выражения. было очень много интересных подробностей, которые мне никто не мог толком объяснить. и кстати, парочка задач была над которыми я поломала голову. особенно понравился такой акцент на указателях. как говорится, приучают с малых лет. понять - поняла, но путаюсь в них до сих пор нечеловечески.

Прата С. Решение 3 и 4 главы

Повторюсь, взяла только интересные мне задания, т.е. с элементами того что поняла плохо/не встречала ранее. Сделала за сегодня. с удовольствием отмечаю что сдвиги  в положительную сторону  хотя-бы в стиле есть . в 4 главе ясно объяснено почему при вводе нескольких строк начинаются проблемы, и как этого избежать, подробно описана работа с входным потоком. Как работать со строками стиля Си и класса String, разница. для себя я сделала выводы что лучше всего, конечно-же класс string. намного меньше мороки. и метод ввода getline в обоих случаях. в задачах разница проиллюстрирована. и кстати, указатели больше не вызывают у меня ужаса и трепета. много нового узнала о видах структур. эта глава расставила все по местам в моей голове. правда, зачем в задачи на СР втиснута работа с массивом array - загадка. он ведь толком не объяснен, но понять его интуитивно можно, правда, зачем его использовать не зная тонкостей, как обычный массив с немного иным объявле...