0%

C++之函数

C++之函数……

函数与数组

1.参数传递

  • 传递常规变量时,函数将使用该变量的拷贝;但传递数组时,函数将使用原来的数组

  • 为将数组类型和元素个数告诉数组处理函数,需通过两个不同的参数来传递它们,一个是数组的首地址,一个是数组的大小

  • 函数中的数组名实际上是一个指向数组的指针

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include<iostream>
    using namespace std;

    const int ArSize=8;

    int sum_arr(int arr[],int size);

    int main(void)
    {
    int cookies[ArSize]={1,2,4,8,16,32,64,128};
    cout<<"cookies address:"<<cookies<<endl;
    cout<<"size of cookies:"<<sizeof(cookies)<<endl;

    int sum=sum_arr(cookies,ArSize);
    cout<<"The sum of cookies is:"<<sum<<endl;
    return 0;
    }

    int sum_arr(int arr[],int size)
    {
    int total=0;
    cout<<"arr address:"<<arr<<endl;
    cout<<"size of arr:"<<sizeof(arr)<<endl;
    for(int i=0;i<size;i++)
    {
    total+=arr[i];
    }
    return total;
    }

    结果如下:

    image-20221216184155698

2.数组与指针

  • 参数入口有数组的函数的声明,通常用const修饰,这是为了在函数中无法通过指针修改数组中的值

  • 例如下例中的const double arr[]

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include<iostream>
    using namespace std;

    const int Max=5;

    int fill_array(double arr[],int size);
    void show_array(const double arr[],int size);

    int main(void)
    {
    double properties[Max];

    int number=fill_array(properties,Max);//number表示成功输入的个数
    show_array(properties,number);
    return 0;
    }

    int fill_array(double arr[],int size)
    {
    double temp;
    int i;
    for(i=0;i<size;i++)
    {
    cout<<"Enter value #"<<i+1<<":";
    cin>>temp;
    if(!cin)//当输入出现错误:类型不匹配
    {
    cin.clear();
    while(cin.get()!='\n');
    cout<<"Bad input:input process terminated!"<<endl;
    break;
    }
    else if(temp<0)
    {
    break;
    }
    else
    arr[i]=temp;
    }
    return i;
    }

    void show_array(const double arr[],int size)
    {
    cout<<"-------------------"<<endl;
    for(int i=0;i<size;i++)
    {
    cout<<"Property #"<<i+1<<":$"<<arr[i]<<endl;
    }
    }

    结果如下:

    image-20221216221816394

3.使用数组区间的函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
using namespace std;

const int ArSize=8;

int sum_arr(const int *begin,const int *end);

int main(void)
{
int cookies[ArSize]={1,2,4,8,16,32,64,128};

int sum=sum_arr(cookies,cookies+ArSize);
cout<<"The sum of cookies is:"<<sum<<endl;
return 0;
}

int sum_arr(const int *begin,const int *end)
{
int total=0;
const int *pt;
for(pt=begin;pt!=end;pt++)
{
total+=*pt;
}
return total;
}

结果如下:

1
The sum of cookies is:255

函数与C-type字符串

  • 函数的参数入口传递的是C-type字符串时,传入的值也是地址,即将地址传给了指针

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include<iostream>
    using namespace std;

    unsigned int ch_number(const char *arr,char ch);

    int main(void)
    {
    char c_array[]="milmimm";
    const char *pt="uloinuu";

    unsigned int m=ch_number(c_array,'m');
    unsigned int u=ch_number(pt,'u');

    cout<<"m happens "<<m<<" times"<<endl;
    cout<<"u happens "<<u<<" times"<<endl;
    return 0;
    }

    unsigned int ch_number(const char *arr,char ch)
    {
    unsigned int count=0;
    while(*arr)
    {
    if(*arr==ch)
    count++;
    arr++;
    }
    return count;
    }

    结果如下:

    image-20221218155231611

  • 函数返回字符串时返回的是地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    #include<iostream>
    using namespace std;

    char *buildstr(char ch,int n);

    int main(void)
    {
    char ch;
    int times;
    cout<<"Enther a character:";
    cin>>ch;
    cout<<"Enter an integer:";
    cin>>times;

    char *pt=buildstr(ch,times);
    cout<<pt<<endl;
    delete [] pt;
    return 0;
    }

    char *buildstr(char ch,int n)
    {
    char *pt=new char[n+1];
    pt[n]='\0';
    for(int i=0;i<n;i++)
    {
    pt[i]=ch;
    }
    return pt;
    }

    结果如下:

    image-20221218160254652


函数与结构体

  • 直接将结构体的名字当成一个数据类型,像传递整数等其他正常数据类型一样操作就行

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    #include<iostream>
    #include<cmath>
    using namespace std;
    //实现将直角坐标转化为极坐标
    struct polar
    {
    double distance;
    double angle;
    };

    struct rect
    {
    double x;
    double y;
    };

    polar rect_to_polar(rect xypos);
    void show_polar(polar pplace);

    int main(void)
    {
    rect rplace;
    polar pplace;
    cout<<"Please enter x and y(q for quit):";
    while(cin>>rplace.x>>rplace.y)
    {
    pplace=rect_to_polar(rplace);
    show_polar(pplace);
    cout<<"Please enter x and y(q for quit):";
    }
    return 0;
    }

    polar rect_to_polar(rect xypos)
    {
    polar pplace;
    pplace.distance=sqrt(xypos.x*xypos.x+xypos.y*xypos.y);
    pplace.angle=atan2(xypos.y,xypos.x);//返回的是弧度制
    return pplace;
    }

    void show_polar(polar pplace)
    {
    const double Rad_to_deg=57.29577951;
    cout<<"Distance="<<pplace.distance<<endl;
    //将弧度制转化为角度制
    cout<<"Angle="<<pplace.angle*Rad_to_deg<<" degree"<<endl;
    }

    结果如下:

    image-20221218173336809

  • 通常需要传递结构体的地址而不是整个结构体以节省时间和空间,故使用指向结构体的指针来传递参数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    #include<iostream>
    #include<cmath>
    using namespace std;
    //实现将直角坐标转化为极坐标
    struct polar
    {
    double distance;
    double angle;
    };

    struct rect
    {
    double x;
    double y;
    };

    void rect_to_polar(const rect *pxy,polar *pda);
    void show_polar(const polar *pda);

    int main(void)
    {
    rect rplace;
    polar pplace;
    cout<<"Please enter x and y(q for quit):";
    while(cin>>rplace.x>>rplace.y)
    {
    rect_to_polar(&rplace,&pplace);
    show_polar(&pplace);
    cout<<"Please enter x and y(q for quit):";
    }
    return 0;
    }

    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);//返回的是弧度制
    }

    void show_polar(const polar *pda)
    {
    const double Rad_to_deg=57.29577951;
    cout<<"Distance="<<pda->distance<<endl;
    //将弧度制转化为角度制
    cout<<"Angle="<<pda->angle*Rad_to_deg<<" degree"<<endl;
    }

    结果如下:

    image-20221218174215417


函数与string对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<iostream>
using namespace std;

const int SIZE=5;

void show_list(const string list[],int size);

int main(void)
{
string list[SIZE];
cout<<"Enter "<<SIZE<<" food"<<endl;
for(int i=0;i<SIZE;i++)
{
cout<<i+1<<":";
getline(cin,list[i]);
}
show_list(list,SIZE);
return 0;
}

void show_list(const string list[],int size)
{
cout<<"The list is:"<<endl;
for(int i=0;i<SIZE;i++)
{
cout<<i+1<<":"<<list[i]<<endl;
}
}

结果如下:

image-20221218180046573


函数与array对象

  • 在函数中对array对象进行传递时,若直接将array对象的名字传递给函数,那么传递的将是array对象的复制版本,并不是直接改变了array对象里面的值,所以下面例子中使用传递地址的方式对数据进行写入操作
  • 指向array对象的指针不能直接通过指针pa[i]去改变array对象中的值,只能通过(*pa)[i]的方式去访问array对象中的值
  • 函数中参数的形式为:array<double,Seasons> *pa
  • 其实有点类似于函数与结构体的使用,只是array对象不存在->与.的使用方式,但都可以通过(*pa)访问指针指向的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#include<array>
using namespace std;

const int Seasons=4;

const array<string,Seasons> Snames={"Spring","Summer","Fall","Winter"};

void fill(array<double,Seasons> *pa);
void show(array<double,Seasons> data_array);

int main(void)
{
array<double,Seasons> expenses;
fill(&expenses);
show(expenses);
return 0;
}

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

void show(array<double,Seasons> data_array)
{
double sum;
for(int i=0;i<Seasons;i++)
{
cout<<Snames[i]<<":$"<<data_array[i]<<endl;
sum+=data_array[i];
}
cout<<"The sum is:"<<sum<<endl;
}

/*或者通过指针的方式去访问数组也可
void show(const array<double,Seasons> *data_array)
{
double sum;
for(int i=0;i<Seasons;i++)
{
cout<<Snames[i]<<":$"<<(*data_array)[i]<<endl;
sum+=(*data_array)[i];
}
cout<<"The sum is:"<<sum<<endl;
}*/

结果如下:

image-20221218184518981


递归

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
using namespace std;

const int Lens=66;
const int Times=6;

void subdivide(char arr[],int min,int max,int levels);
int main(void)
{
char ruler[Lens];
for(int i=0;i<Lens;i++)
{
ruler[i]=' ';
}
int min=0;
int max=Lens-2;
ruler[Lens-1]='\0';//字符数组需要以'\0'结尾
// ruler[min]='|';
// ruler[max]='|';

for(int i=0;i<Times;i++)
{
subdivide(ruler,min,max,i);
cout<<ruler<<endl;
}
return 0;
}

void subdivide(char arr[],int min,int max,int levels)
{
int mid=(min+max)/2;
if(levels==0)
{
arr[min]='|';
arr[max]='|';
}
else
{
arr[mid]='|';
subdivide(arr,min,mid,levels-1);
subdivide(arr,mid,max,levels-1);
}
}

结果如下:

image-20221218220727018


函数指针

  • 函数指针:double (*pt)(int),可以指向输入参数为一个整数,输出为double类型的函数

  • 在函数中用(*pt)表示对应函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #include<iostream>
    using namespace std;

    double Jack(int L);
    double Rick(int L);
    void computes(int L,double (*pt)(int));

    int main(void)
    {
    int lines;
    cout<<"Please enter the Lines:";
    cin>>lines;
    cout<<"The times computes by Jack is:";
    computes(lines,Jack);
    cout<<"The times computes by Rick is:";
    computes(lines,Rick);
    return 0;
    }

    double Jack(int L)
    {
    return L*0.05;
    }

    double Rick(int L)
    {
    return L*0.03+0.0004*L*L;
    }

    void computes(int L,double (*pt)(int))
    {
    cout<<(*pt)(L)<<" seconds"<<endl;
    }

    结果如下:

    image-20221218223557271

  • 若想表达指向数组(数组中的元素为指向函数的指针)的指针:则例如const double *(*(*pd)[3])(const double *,int)=&pa;,其中(*pd)表示指针,[3]表示指向的是一个数组,*(*pd)[3]表示指向一个数组中有3个元素(每个元素为指向函数的指针)的指针,可以理解为指向指针的指针

  • 下例中:const double *(*(*pd)[3])(const double *,int)=&pa的&pa为取数组pa整体的首地址

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    #include<iostream>
    using namespace std;

    const double *f1(const double *ar,int n);
    const double *f2(const double ar[],int n);
    const double *f3(const double ar[],int n);

    int main(void)
    {
    double av[3]={1112.3,1542.6,2227.9};

    //Part1:
    //p1(p2):pointer to a function
    const double *(*p1)(const double *,int)=f1;
    auto p2=f2;//编译器会根据f2的值自己得出p2的数据类型,并将f2赋值给p2
    cout<<"Part1:----------------------"<<endl;
    cout<<"Address\t value"<<endl;
    cout<<(*p1)(av,3)<<":"<<*((*p1)(av,3))<<endl;//这里*((*p1)(av,3))不加最外层括号也可以,因为()的优先级高于*
    cout<<p2(av,3)<<":"<<*p2(av,3)<<endl;//*pt也可以直接用pt表示,故这里p2用最简单的形式表示出来了

    //Part2:
    //pa(pb) is an array of pointers
    const double *(*pa[3])(const double *,int)={f1,f2,f3};
    auto pb=pa;
    cout<<"Part2:----------------------"<<endl;
    cout<<"Address\t Value"<<endl;
    for(int i=0;i<3;i++)
    {
    cout<<pa[i](av,3)<<":"<<*pa[i](av,3)<<endl;
    }
    for(int i=0;i<3;i++)
    {
    cout<<pb[i](av,3)<<":"<<*pb[i](av,3)<<endl;
    }

    //Part3:
    //pc(pd) is a pointer to an array of function pointers
    auto pc=&pa;
    const double *(*(*pd)[3])(const double *,int)=&pa;
    cout<<"Part3:----------------------"<<endl;
    cout<<"Address\t Value"<<endl;
    cout<<(*pc)[0](av,3)<<":"<<*(*pc)[0](av,3)<<endl;
    const double *pdb=(*pd)[1](av,3);
    cout<<pdb<<":"<<*pdb<<endl;
    cout<<(*(*pd)[2])(av,3)<<":"<<*(*(*pd)[2])(av,3)<<endl;

    return 0;
    }

    const double *f1(const double *ar,int n)
    {
    return ar;
    }

    const double *f2(const double ar[],int n)
    {
    return ar+1;
    }

    const double *f3(const double ar[],int n)
    {
    return ar+2;
    }

    结果如下:

    image-20221219211422256

  • 使用typedef const double *(*p1)(const double *,int)后p1称为了指代此函数指针的数据类型

欢迎来到ssy的世界