首页 > 编程语言 >c++primer第七章函数学习笔记

c++primer第七章函数学习笔记

时间:2024-09-18 19:49:06浏览次数:15  
标签:include const cout int double c++ 第七章 primer 函数

函数的基本知识

定义函数

无返回值

void functionName(parameterList)

{

    statement(s);

    return; // optional

}

有返回值

    typeName funtionName(parameterList)

    {

        statements;

        return value;

    }

#include <iostream>
using namespace std;
void simple();
int main()
{

    //     // c++ 的编程模块
    cout << "main() will call the simple () function: \n";
    simple(); // function
    return 0;
}
void simple()
{
    cout << "I'm but a simple function";
}

函数原型和函数调用

#include <iostream>
using namespace std;
void cheers(int);
double cube(double x);
int main()
{
    cheers(5);
    cout << "Give me a number: ";
    double side;
    cin >> side;
    double volume = cube(side);
    cout
        << "A " << side << "-foot cube has a volume of ";
    cout << volume << " cubic feet. \n";
    cheers(cube(2)); // 存在自动类型转换
    return 0;
}
void cheers(int n)
{
    using namespace std;
    for (int i = 0; i < n; i++)
        cout << "Cheers!";
    cout << endl;
}

double cube(double x)
{
    return x * x * x;
}

函数原型是一句语句,以分号结束。例如

函数原型的功能:

函数参数和按值传递

用于传递值的变量为形参(parameter),传递给函数的值为实参(argument)

多个参数用逗号隔开

#include <iostream>
using namespace std;
void n_chars(char, int);
int main()
{
    int times;
    char ch;

    cout << "Enter a character: ";
    cin >> ch;
    while (ch != 'q')
    {
        cout << "Enter an integer: ";
        cin >> times;
        cout << ch;
        n_chars(ch, times);
        cout << "\nEnter another character or press the q-key to quit: ";
        cin >> ch;
    }
    cout << "The value of time is " << times << ". \n";
    cout << "Bye\n";
    return 0;
}
void n_chars(char c, int n)
{
    while (n-- > 0)
        cout << c;
}

另外一个接受两个参数的的函数(抽奖概率)

#include <iostream>

long double probability(unsigned numbers, unsigned picks);
using namespace std;
int main()
{
    double total, choices;
    cout << "Enter the total number of choices on the game card and\n"
            "the number of picks allowed:\n";
    while ((cin >> total >> choices) && choices <= total)
    {
        cout << "You have one chance in ";
        cout << probability(total, choices);
        cout << " of winning.\n";
        cout << "Next two numbers (q to quit): ";
    }
    cout << "Bye\n";
    return 0;
}
long double probability(unsigned numbers, unsigned picks)
{
    long double result = 1.0;
    long double n;
    unsigned p;

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

函数和数组

int sum_arr(int arr[], int n)

// // list 7.5
#include <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
// int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
    int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
    // C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
    //  对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
    //  int arr[] 在函数头与 int *arr 等价
    cout << cookies << " = array address, ";
    // int sum;
    int sum = sum_arr(cookies, ArSize); // 指针减法是整数值
    cout << "Total cookies eaten: " << sum << endl;
    return 0;
}
int sum_arr(int arr[], int n)
{
    int total = 0;
    cout << arr << " = arr, ";
    cout << sizeof arr << "= sizeof arr\n"; // wrong
    for (int i = 0; i < n; i++)
        total += arr[i];
    return total;
}

函数通过指针来处理数据

其中输入arr[] 是一个指针

将数组作为参数

C++ 将数组名解释为其第一个元素的地址

函数将数组的地址赋给指针变量

nclude <iostream>
const int ArSize = 8;
int sum_arr(int arr[], int n);
// int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
    int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
    // C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
    //  对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
    //  int arr[] 在函数头与 int *arr 等价
    cout << cookies << " = array address, ";
    // int sum;
    int sum = sum_arr(cookies, ArSize); // 指针减法是整数值
    cout << "Total cookies eaten: " << sum << endl;
    sum = sum_arr(cookies, 3);
    cout << "First three eaters ate " << sum << " cookies.\n";
    sum = sum_arr(cookies + 4, 4);
    cout << "Last four eaters ate " << sum << " cookies.\n";
    return 0;
}

int sum_arr(int arr[], int n)
{
    int total = 0;
    cout << arr << " = arr, ";
    cout << sizeof arr << "= sizeof arr\n"; // wrong
    for (int i = 0; i < n; i++)
        total += arr[i];
    return total;
}

填充数组

const保护数组

修改数组

结合代码

#include <iostream>
const int Max = 5;
int fill_array(double arr[], int limit);
void show_array(const double arr[], int n);
void revalue(double r, double ar[], int n);
using namespace std;
int main()
{
    double properties[Max];

    int size = fill_array(properties, Max);
    show_array(properties, size);
    cout << "Enter revaluation factor:";
    double factor;
    cin >> factor;
    revalue(factor, properties, size);
    show_array(properties, size);
    cout << "Done.\n";
    return 0;
}
int fill_array(double arr[], 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;
        arr[i] = temp;
    }
    return i;
}
// 展示数组
void show_array(const double arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << "Property #" << (i + 1) << " : $";
        cout << arr[i] << endl;
    }
}
// 修改数组
void revalue(double r, double ar[], int n)
{
    for (int i = 0; i < n; i++)
        ar[i] *= r;
}

使用数组区间的函数

#include <iostream>
const int ArSize = 8;
int sum_arr(const int *begin, const int *end);
using namespace std;
int main()
{
    int cookies[ArSize] = {1, 2, 4, 8, 16, 32, 64, 128};
    // C++ 将数组名解释为其第一个元素的地址 cookies = &cookies[0]
    //  对数组名使用sizeof()将得到整个数组的长度(以字节为单位)
    //  int arr[] 在函数头与 int *arr 等价
    cout << cookies << " = array address, ";
    // int sum;
    int sum = sum_arr(cookies, cookies + ArSize); // 指针减法是整数值
    cout << "Total cookies eaten: " << sum << endl;
    sum = sum_arr(cookies, cookies + 3);
    cout << "First three eaters ate " << sum << " cookies.\n";
    sum = sum_arr(cookies + 4, cookies + 8);
    cout << "Last four eaters ate " << sum << " cookies.\n";
    return 0;
}
int sum_arr(const int *begin, const int *end)
{
    const int *pt;
    int total = 0;
    // cout << arr << " = arr, ";
    // cout << sizeof arr << "= sizeof arr\n"; // wrong
    for (pt = begin; pt != end; pt++)
        total += *pt;
    return total;
}

指针和const

指针指向常数对象,防止指针修改指向的值; 指针本身声明为常亮,防止指针改变指向的位置

int age = 30;

const int *pt = &age;

不能通过pt对age进行修改,但是可以通过age来修改

函数和二维数组

二维数组属于指向指针的指针

函数和C-风格字符串

 表示字符串的方式

 1. char数组

 2. 有引号括起来的字符串常量

 3. 被设置为字符串的地址的char指针

include <iostream>
int c_in_str(const char *str, char ch);
using namespace std;
int main()
{
    char mmm[15] = "minimum";
    char *wail = "ululate";

    int ms = c_in_str(mmm, 'm');
    int us = c_in_str(wail, 'u');
    cout << ms << "m characters in " << mmm << endl;
    cout << us << "u characters in " << wail << endl;
}

int c_in_str(const char *str, char ch)
{
    int count = 0;
    while (*str)
    {
        if (*str == ch)
            count++;
        str++;
    }
    return count;
}

返回C-风格字符串的函数

#include <iostream>
char *build(char c, int n);
using namespace std;
int main()
{
    int times;
    char ch;
    cout << "Enter a character: ";
    cin >> ch;
    cout << "Enter an integer: ";
    cin >> times;
    char *ps = build(ch, times);
    cout << ps << endl;

    delete[] ps;
    ps = build('+', 20);
    cout << ps << "-DONE-" << ps << endl;
    delete[] ps;
    return 0;
}
char *build(char c, int n)
{
    char *pstr = new char[n + 1];
    pstr[n] = '\0';
    while (n-- > 0)
        pstr[n] = c;
    return pstr;
}

函数和结构

传递和返回结构

#include <iostream>
struct travel_time
{
    int hours;
    int mins;
};
const int Mins_per_hr = 60;
travel_time sum(travel_time t1, travel_time t2);
void show_time(travel_time t1);
using namespace std;
int main()
{
    travel_time day1 = {5, 45};
    travel_time day2 = {4, 55};

    travel_time trip = sum(day1, day2);
    cout << "Two-day total: ";
    show_time(trip);

    travel_time day3 = {4, 32};
    cout << "Three-day total:";
    show_time(sum(trip, day3));

    return 0;
}
travel_time sum(travel_time t1, travel_time t2)
{
    travel_time total;

    total.mins = (t1.mins + t2.mins) % Mins_per_hr;
    total.hours = t1.hours + t2.hours + (t1.mins + t2.mins) / Mins_per_hr;
    return total;
}
void show_time(travel_time t)
{
    cout << t.hours << " hours, ";
    cout << t.mins << "minutes.\n";
}

另一个处理结构的函数范例

#include <iostream>
#include <cmath>
struct rect
{
    double x;
    double y;
};
struct polar
{
    double distance;
    double angle;
};
void show_polar(polar dapos);
polar rect_to_polar(rect xypos);
using namespace std;
int main()
{
    rect rplace;
    polar pplace;

    cout << "Enter the x and the y values: ";
    while (cin >> rplace.x >> rplace.y)
    {
        pplace = rect_to_polar(rplace);
        show_polar(pplace);
        cout << "Next two numbers (q to quit):";
    }
    cout << "Done.\n";
    return 0;
}

void show_polar(polar dapos)
{
    const double Rad_to_deg = 57.29577951;

    cout << "distance = " << dapos.distance;
    cout << ", angle = " << dapos.angle * Rad_to_deg;
    cout << " degrees\n";
}
polar rect_to_polar(rect xypos)
{
    polar answer;

    answer.distance =
        sqrt(xypos.x * xypos.x + xypos.y * xypos.y);
    answer.angle = atan2(xypos.y, xypos.x);
    return answer;
}

传递结构的地址

形参是指针使用间接操作符,结构使用成员操作符

间接成员操作符(->)  直接成员操作符(.)

#include <iostream>
#include <cmath>
struct rect
{
    double x;
    double y;
};
struct polar
{
    double distance;
    double angle;
};
void show_polar(const polar *pda);
void rect_to_polar(const rect *pxy, polar *pda);
using namespace std;

int main()
{
    rect rplace;
    polar pplace;

    cout << "Enter the x and the y values: ";
    while (cin >> rplace.x >> rplace.y)
    {
        rect_to_polar(&rplace, &pplace);
        show_polar(&pplace);
        cout << "Next two numbers (q to quit):";
    }
    cout << "Done.\n";
    return 0;
}
void show_polar(const polar *pda)
{
    const double Rad_to_deg = 57.29577951;

    cout << "distance = " << pda->distance;
    cout << ", angle = " << pda->angle * Rad_to_deg;
    cout << " degrees\n";
}

void rect_to_polar(const rect *pxy, polar *pda)
{
    pda->distance = sqrt(pxy->x * pxy->x + pxy->y * pxy->y);
    pda->angle = atan2(pxy->y, pxy->x);
}

函数和string对象

可以用string 类型对象数组代替二维char数组;

#include <iostream>
#include <string>
using namespace std;
const int SIZE = 5;
void display(const string sa[], int n);

int main()
{
    string list[SIZE];
    cout << "Enter your " << SIZE << "favorite astronomical sights: \n";
    for (int i = 0; i < SIZE; i++)
    {
        cout << i + 1 << ": ";
        getline(cin, list[i]);
    }

    cout << "Your list: \n";
    display(list, SIZE);
    return 0;
}
void display(const string sa[], int n)
{
    for (int i = 0; i < n; i++)
        cout << i + 1 << ": " << sa[i] << endl;
}

sa 是一个指向sring对象的指针,sa[i] 是一个string对象。

递归

包含一个递归调用的递归

void recurs(argumentlist)

{

    statements1;

    if (test)

        recurs(arguments)

    statements2

}

#include <iostream>
void countdown(int n);
using namespace std;
int main()
{
    countdown(4);
    return 0;
}

void countdown(int n)
{
    cout << "Counting down ..." << n << "(n at" << &n << ")" << endl;
    if (n > 0)
        countdown(n - 1);
    cout << n << ": Kaboom!\n";
}

改变代码显示n的地址和值

#include <iostream>
void countdown(int n);
using namespace std;
int main()
{
    countdown(4);
    return 0;
}

void countdown(int n)
{
    cout << "Counting down ..." << n << "(n at" << &n << ")" << endl;
    if (n > 0)
        countdown(n - 1);
    cout << n << ": Kaboom!" << "(n at " << &n << ") " << endl;
    ;
}

包含多个递归调用的递归

#include <iostream>
const int Len = 66;
const int Divs = 6;
using namespace std;
void subdivide(char ar[], int low, int high, int level);
int main()
{
    char ruler[Len];
    int i;
    for (i = 1; i < Len - 2; i++)
        ruler[i] = ' ';
    ruler[Len - 1] = '\0';
    int max = Len - 2;
    int min = 0;
    ruler[min] = ruler[max] = '|';
    cout << ruler << endl;
    for (i = 1; i <= Divs; i++)
    {
        subdivide(ruler, min, max, i);
        cout << ruler << endl;
        for (int j = 1; j < Len - 2; j++)
            ruler[j] = ' ';
    }
    return 0;
}
void subdivide(char ar[], int low, int high, int level)
{
    if (level == 0)
        return;
    int mid = (high + low) / 2;
    ar[mid] = '|';
    subdivide(ar, low, mid, level - 1);
    subdivide(ar, mid, high, level - 1);
}

函数指针

要声明指向特定类型的函数的指针,可以首先编写这种函数的原型,然后用(*pf)替换函数名,这样pf就是这类函数的指针

函数指针的基本知识

函数指针的机制

  • 获取函数的地址
  • 声明一个函数指针
  • 使用函数指针来调用函数

 获取函数地址

获取函数地址只用使用函数名,如果think()是一个函数,则think就是函数的地址

声明函数指针

要声明指向特定类型的函数的指针,可以首先编写这种函数的原型,然后用(*pf)替换函数名,这样pf就是这类函数的指针,例如

double pam (int);

double (*pf) (int);

pf = pam;

使用函数指针来调用函数

使用(*pf),将它看作函数名

函数指针示例

#include <iostream>
double betsy(int);
double pam(int);

void estimate(int lines, double (*pf)(int));
using namespace std;

int main()
{
    int code;

    cout << "How many lines of code do you need? ";
    cin >> code;
    cout << "Here's Betsy's estimate: \n";
    estimate(code, betsy);
    cout << "Here's Pam's estimate: \n";
    estimate(code, pam);
    return 0;
}

double betsy(int Lns)
{
    return 0.05 * Lns;
}
double pam(int Lns)
{
    return 0.03 * Lns + 0.0004 * Lns * Lns;
}

void estimate(int lines, double (*pf)(int))
{
    cout << lines << "lines will take ";
    cout << (*pf)(lines) << "hour(s)\n";
}

标签:include,const,cout,int,double,c++,第七章,primer,函数
From: https://blog.csdn.net/weixin_48442204/article/details/142225727

相关文章

  • 南沙C++信奥老师解一本通题:1337:【例3-2】单词查找树
    ​【题目描述】在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表里。为了提高查找和定位的速度,通常都画出与单词列表所对应的单词查找树,其特点如下:1.根结点不包含字母,除根结点外每一个结点都仅包含一个大写英文字母;2.从根结点到某一结点,路径上经过的字母依次连起......
  • 精读《C Primer Plus》——作用域(scope)
    作用域(scope)参考:CPrimerPlus第6版第12章存储类别、链接和内存管理1.分类2.blockscope/块作用域2.1.定义block/块是用一块花括号括起来的代码区域块作用域变量的范围是从定义处到包含该定义块的末尾声明在内层块中的变量,其作用域仅局限于该声明所在的块......
  • java.lang.UnsatisfiedLinkError: dlopen failed: library "libc++_shared.so" not fo
    一、概述在AndroidStudio中集成opencv,使用其native函数时报的一个错误 二、解决办法opencv提供的native文件夹中提供的是动态库但是在gradle中的配置中,配置的stl是静态的,将其改为shared就行了externalNativeBuild{cmake{cp......
  • C++ vector 列表初始化
    vector<int>vl(10);//v1有10个元素,每个的值都是0vector<int>v2{10};//v2有1个元素,该元素的值是10vector<int>v3(10,1);//v3有10个元素,每个的值都是1vector<int>v4{10,1};//v4有2个元素,值分别是10和1如果初始化时使用了花括号的形式但是提供的值又不能......
  • 【C++】多态的认识和理解
    个人主页文章目录⭐一、多态的概念......
  • C++浮点数半精度与单精度的相互转换
    代码//单精度转半精度unsignedshortcpu_float2half(floatf){unsignedshortret;unsignedx=*((int*)(void*)(&f));unsignedu=(x&0x7fffffff),remainder,shift,lsb,lsb_s1,lsb_m1;unsignedsign,exponent,mantissa;//Getrid......
  • C++14的一些新特性
    记录一些C++14的一些特性: 函数返回值类型推导:C++14对函数返回类型推导规则做了优化:#include<iostream>usingnamespacestd;autofunc(inti){returni;}intmain(){cout<<func(4)<<endl;return0;}返回值类型推导也可以用在模板中:#include......
  • Rust中的&运算符取一个变量的地址与C/C++中意义相同么?如果不同又有什么区别呢?
    Rust中的&运算符与C/C++中的&运算符有相似之处,但它们的行为和作用有一些关键区别,特别是在所有权、内存安全和编译期检查方面。1.相似之处在Rust和C/C++中,&运算符都用于获取变量的地址,即生成一个指针或引用。它们的作用可以概括为:将一个值的引用或地址作为结果,而不......
  • C++中一般指针,指针数组,数组指针
    凤凰台上凤凰游,凤去台空江自流。吴宫花草埋幽径,晋代衣冠成古丘。三山半落青天外,二水中分白鹭洲。总为浮云能蔽日,长安不见使人愁。                            ——《登金陵凤凰台》【唐】李白 今天是中秋节,小......
  • C++11的一些特性
    记录一下使用过的C++11的一些特性,大致分为三部分:并发相关,智能指针相关,chrono。 并发相关:std::thread相关:#include<iostream>#include<thread>usingnamespacestd;intmain(){autofunc=[](){for(inti=0;i<10;++i){cout<<i<......