C++ primer 第七章 编程练习题

题目




#include<iostream>
using namespace std;

double avrg(double a,double b) {
    double output;
    output = 2.0 * a * b / (a + b);
    return output;
}

int main()
{
    cout << "Please enter two numbers:"<<endl;
    double num1, num2;
    cout << "num1:";
    cin >> num1;
    cout << "num2:";
    cin >> num2;
/*double x,y;
cout<<"请输入两个由空格相间隔的数字:\n";
while(cin>>x>>y){}
*/
    if (num1 != 0 && num2!=0) 
        cout << "The output is " << avrg(num1, num2)<<endl;
    system("pause");
    return 0;
}

输出结果


#include<iostream>
using namespace std;

void input(double* arr, int* x);//函数声明
void output(double *arr, int x);
double calculate(double arr[], int x);

int main()
{
    double score[10];
    //double golf_score;
    int times = 0;
    cout << "Please enter golf score(less than 10,enter 0 if end): ";

    input(score, &times);
    output(score, times);
    cout << "The average of score is: " << calculate(score, times) << endl;

    system("pause");
    return 0;
}

void input(double* arr, int* x)//必须选用指针常量,因为需要返回修改后的值;否则无法改变主函数中的值
{
    double golf_score;
    while (cin >> golf_score && golf_score!=0)
    {
        arr[*x] = golf_score;
        (* x)++;
    }
}
void output(double *arr, int x)
{
    for (int i = 0;i < x;i++)
        cout << arr[i] << endl;
}
double calculate(double arr[], int x)
{
    double sum = 0.0;
    double averg;
    for (int i = 0;i < x;i++)
        sum += arr[i];
    averg = sum / x;
    return averg;
}

输出结果


#include <iostream>
using namespace std;

struct box
{
    char maker[40];
    float height;
    float width;
    float length;
    float volume;
};
void PrintBox(struct box mbox)
{
    cout << "Box maker: " << mbox.maker << endl;
    cout << "Box height: " << mbox.height << endl;
    cout << "Box width: " << mbox.width << endl;
    cout << "Box length: " << mbox.length << endl;
    cout << "Box volume: " << mbox.volume << endl;
}
void CalBoxVolume(struct box* pbox)
{
    pbox->volume = pbox->height * pbox->width * pbox->length;
}
int main()
{
    struct box mbox = { "HAHA", 1.1, 2.0, 3.0, 2.2 };
    PrintBox(mbox);
    CalBoxVolume(&mbox);
    PrintBox(mbox);
}

输出结果


程序7.4


#include <iostream>
using namespace std;
long long factorial(unsigned int number)
{
    if (number == 0 || number == 1)
    {
        return 1;
    }
    else
    {
        return number * factorial(number - 1);
    }
}
int main()
{
    long long result = 0;
    unsigned int input = 0;
 
    cout << "Please enter the number: ";
    cin >> input;
 
    while (1)
    {
        result = factorial(input);
        cout << "The result of " << input << "! is " << result << "." << endl;
 
        cout << "Please enter the next number: ";
        cin >> input;
    }
}

注:
1.对于一些变量的长度应该准确标识,有助于自己和读者区分
2.嵌套某种程度上也是一种循环

输出结果


例:对于指针和数组,函数头或者函数原型声明中
*int sum = (int arr,int n)和int sum(int arr[],int n)含义是相同的,都意味着arr是一个int指针,数组表示法(int arr[])表示,arr不仅指向int,还指向int数组的第一个int
当指针指向数组的第一个元素时,使用数组表示法,当指针指向一个独立的值时,使用指针表示法。
但在其他位置,两种写法含义并不相同
如果想要保持原来的数组不在函数中被改变值,可以选用const保护数组
例: void show_array(const double ar[],int n);

#include <iostream>
using namespace std;
const int Max = 10;

int fill_array(double ar[], int limit);
void show_array(const double ar[], int n);
void Reverse_array(double ar[], int n);

int main()
{
    double properties[Max];

    int size = fill_array(properties, Max);
    show_array(properties, size);
    cout << "After reverse: " << endl;
    Reverse_array(properties, size);
    show_array(properties, size);
    cout << "After reverse(delete the first and the last): " << endl;
    Reverse_array(properties+1, size-2);//可以直接用+1来表示第二项开始
    show_array(properties + 1, size - 2);
    cin.get();
    return 0;
}
    
int fill_array(double ar[],int limit)
    {
        double temp;
        int i;
        for (i = 0;i < limit;i++)
        {
            cout << "Enter value #" << (i + 1) << ":";
            cin >> temp;
            if (!cin)//判断是否为数字输入
            {
                cin.clear();
                while (cin.get() != '\n')
                    continue;
                cout << "Bad input;input process terminated.\n";
                break;
            }
            else if (temp < 0)//判断是否为负值
                break;
            ar[i] = temp;
        }
        return i;

    }

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

void Reverse_array(double ar[], int n)
    {
        double temp;
        int j = n;
        for (int i = 0;i < int(n/2);i++)
        {
            temp = ar[i];
            ar[i] = ar[j-1];
            ar[j-1] = temp;
            j--;
        }
    }

输出结果


调用函数时,可以直接用+1来表示从数组第二项开始
Reverse_array(properties+1, size-2);

#include<iostream>
using namespace std;
const int Max = 5;

double* fill_array(double* begin, double* end);
void show_array(double *begin, double* lspt);
void revalue(double* begin, double* lspt, double r);

int main()
{
    double properties[Max];
    double *last_point;
    last_point = fill_array(properties,properties+Max);
    show_array(properties,last_point);
    if (last_point>properties)//最后一个指针在第一个指针后面
    {
        cout << "Enter revaluation factor: ";
        double factor;
        while (!(cin >> factor))
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
            cout << "Bad input;Please enter a number:";
        }
        revalue(properties,last_point,factor);
        show_array(properties, last_point);
    }
    cout << "Done.\n";
    cin.get();
    cin.get();
    return 0;
}

double *fill_array(double* begin, double* end)
{
    double temp;
    double* i;
    int j = 0;
    for (i = begin;i!=end;i++)
    {
        cout << "Enter value #" << (j+1) << ":";
        cin >> temp;
        if (!cin)
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
            cout << "Bad input;input process terminated.\n";
            break;
        }
        else if (temp < 0)
            break;
        *i = temp;
        j++;
    }
    return i;
}

void show_array( double*begin,double *lspt)
{
    double* i;
    i = begin;
    for (i;i < lspt;i++)
    {
        int j = 0;
        cout << "Property #" << (j + 1) << ":$";
        cout << *i << endl;
        j++;
    }
}

void revalue(double* begin, double* lspt,double r)
{
    double* temp;
    for (temp=begin;temp <lspt;temp++)
        (*temp)*= r;
}

结果输出


int fill_array(double *ar_begin, double *ar_end)
{
    double temp = 0.0;
    int i = 0;
    double *ar_tmp = nullptr;
    for (ar_tmp = ar_begin; ar_tmp < ar_end; ar_tmp++)
    {
        cout << "Enter value #" << (i + 1) << ": ";
        cin >> temp;
        if (!cin)
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
            cout << "Bad input; input preocess terminated.\n";
            break;
        }
        else if (temp < 0)
        {
            break;
        }
 
        *ar_tmp = temp;
        i++;
    }
 
    return i;

fill_array函数网友做的版本,不符合以begin和开头为函数参数的要求,但是里面用到一个nullptr

NULL的问题

在nullptr被提出之前,空指针通常被赋值为NULL,其是由编译器定义的宏,一般为0或者(void*)0。即空指针是值为0的指针。
因此在将空指针传入重载函数时,有时会产生二义性的问题,见下例

    void func(int);

    void func(char *);

    func(NULL);  // ambiguous,由于NULL定义为整数0并可指代空指针,
                 // 编译器将不确定此处是调用func(int) 还是 func(char *);

对于这种二义性问题,曾经只能通过显式转换来解决。

func((char*)NULL);  // 调用到func(char *);

nullptr

nullptr的提出为了解决上述历史遗留问题,需要将空指针类型与整数类型区分开,因此提出了一个新的右值常量nullptr。

nullptr是C++11中新增的一个关键字,用以指定为一个不能被取址的右值常量,以取代NULL。
nullptr的类型为decltype(nullptr),并在<cstddef>中typedef为nullptr_t(因此nullptr_t类型变量的值都为nullptr)。

nullptr_t类型的变量,被规定为只能被转换为指针类型(包括函数指针、成员指针等),而不能被转换为整数、布尔等其他类型。

char *p = nullptr;  // ch的值为空指针
int n = nullptr;    // error,nullptr不能被转换为int类型

PS. 有一点特殊的是,因为空指针仍然能被赋值为NULL(0),所以为了向后兼容,使用nullptr与常量0或者值为0的指针类型进行比较是允许并相等的,但是不被允许与值为0的其他类型相比较。

nullptr == 0 // ok
    
char *p = NULL;
p == nullptr // ok
    
int i = 0;
i == nullptr // error   

a.

#include<iostream>
#include<string>

using namespace std;
const int season = 4;
const char*seasons[] = {"Spring","Summer","Fall","Winter"};

void fill(double arr[]);
void show(double arr[]);

int main() {
    double expenses[season];
    fill(expenses);
    show(expenses);
    return 0;
}

void fill(double arr[])
{

    for (int i = 0;i < season;i++)
    {
        cout << "Enter " << seasons[i] << " expenses:";
        cin >> arr[i];
    }
}

void show(double arr[])
{
    double total = 0.0;
    cout << "\nEXPENSES\n";
    for (int i = 0;i < season;i++)
    {
        cout << seasons[i] << ":$" << arr[i] << endl;
        total += arr[i];
    }
    cout << "Total Expenses: $" << total << endl;
}

b.

#include<iostream>
#include<string>

using namespace std;
const int season = 4;
const char*seasons[] = {"Spring","Summer","Fall","Winter"};

struct expense
{
    double money[season];
};

void fill(struct expense *group);//指向结构体的指针变量
void show(struct expense *group);

int main() {
    
    struct expense *group1 = new struct expense;
    fill(group1);
    show(group1);
    return 0;
}

void fill(struct expense* group)
{
    for (int i = 0;i < season;i++)
    {
        cout << "Enter " << seasons[i] << " expenses:";
        cin >> group->money[i];
    }
}

void show(struct expense*group)//expense类型的指向结构体指针变量
{
    double total = 0.0;
    cout << "\nEXPENSES\n";
    for (int i = 0;i < season;i++)
    {
        cout << seasons[i] << ":$" << group->money[i] << endl;
        total += group->money[i];
    }
    cout << "Total Expenses: $" << total << endl;
}

输出结果


#include<iostream>

using namespace std;
const int SLEN = 30;

struct student 
{
    char fullname[SLEN];
    char hobby[SLEN];
    int ooplevel;
};

int getinfo(student pa[], int n);
void display1(student st);
void display2(const student* ps);
void display3(const student pa[], int n);

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";
    return 0;
}

int getinfo(student pa[], int n)
{
    int times = 0;
    for (int i = 0;i < n;i++)
    {
        cout << "Please enter the #" << i + 1 << " student information(including fullname,hobby and opplevel): " << endl;
        cout << "fullname:";
        cin.getline(pa[i].fullname, SLEN);//cin.pa[i].fullname;
        cout << "hobby:";
        cin.getline(pa[i].hobby, SLEN);
        cout << "ooplevel:";
        cin >> pa[i].ooplevel;

        times++;
    }
    return times;
}
void display1(student st)
{
    cout << "fullname:"<<st.fullname << endl;
    cout << "hobby:"<<st.hobby << endl;
    cout << "opplevel:"<<st.ooplevel << endl;
}
void display2(const student* ps)
{
    cout << "fullname:" << ps->fullname<<endl;
    cout << "hobby:" << ps->hobby << endl;
    cout << "ooplevel:" << ps->ooplevel << endl;
}
void display3(const student pa[], int n)
{
    for (int i = 0;i < n;i++)
    {
        cout << "Student #"<<i+1<<"fullname: " << pa[i].fullname<<endl;
        cout << "Student #" << i + 1 << "hobby: " << pa[i].hobby<<endl;
        cout << "Student #" << i + 1 << "ooplevel: " << pa[i].ooplevel<<endl;
    }
}

(有点小问题,不会改...)

#include<iostream>

using namespace std;

void input(double* p1, double* p2);
double add(double x, double y);
double mul(double x, double y);
double calculate(double x, double y, double (*function)(double ,double));

int main()
{
    double num1, num2;
    input(&num1, &num2);
    char symbol;
    cout << "Please choose a symbol: ";
    cin >> symbol;
    if (symbol == '+')
        cout<<num1<<" "<<symbol<<" "<<num2 << " = " << calculate(num1, num2, add);
    else if (symbol == '*')
        cout<< num1 << " " << symbol << " " << num2 << " = "<<calculate(num1, num2, mul);
    else
        cout << "wrong input" << endl;
    return 0;
}

void input(double* p1, double* p2)
{
    cout << "Please enter two numbers: ";
    cin >> *p1 >> *p2;
}
double add(double x, double y)
{
    return x + y;
}
double mul(double x, double y)
{
    return x * y;
}
double calculate(double x, double y, double (*function)(double, double))
{
    return function(x, y);
}

输出结果


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容