天天看點

C++ Printer Plus學習筆記 第七章 函數與string 函數與array 遞歸 函數指針

函數與對象: 沒啥内容 直接上示例吧

#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;
}
           

函數與array

#include <iostream>
#include <string>
#include <array>
const int Seasons = 4;
const std::array<std::string, Seasons> Snames = 
  {"Spring", "Summer", "Fall", "Winter"};

void fill(std::array<double, Seasons>* pa);
void show(std::array<double, Seasons> da);

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

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

void show(std::array<double, Seasons> da)
{
  using namespace std;
  double total = 0.0;
  cout << "\nEXPENSES\n";
  for (int i = 0; i < Seasons; i++)
  {
    cout << Snames[i] << ": $" << da[i] << endl;
    total += da[i];
  }
  cout << "Total Expenses: $" << total << endl;
}
           

留意 傳入的是位址還是array的值 

遞歸:

簡單遞歸調用:

#include <iostream>
void countdown(int n);

int main()
{
  countdown(4);
  return 0;
}

void countdown(int n)
{
  using namespace std;
  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;
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] = '|';
  std::cout << ruler << std::endl;
  for (i = 1; i <= Divs; i++)
  {
    subdivide(ruler,min,max, i);
    std::cout << ruler << std::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);
}
           

輸出結果

C++ Printer Plus學習筆記 第七章 函數與string 函數與array 遞歸 函數指針

函數指針:

double pam (int)

函數名:位址

函數名():函數的傳回值

double *pf(int) 表示的是一個傳回double類型指針的函數

double(*pf)(int) 表示 函數的指針

将函數指派給函數指針  傳回類型一定要與指針類型相同

pf = pam

通過函數指針來調用函數:

double y = (*pf)(5) 或者 pf(5)

示例:

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

void estimate(int lines, double (*pf)(int));

int main()
{
  using namespace std;
  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))
{
  using namespace std;
  cout << lines << " lines will take ";
  cout << (*pf)(lines) << " hour(s)\n";
}
           

奇怪 為毛沒有顔色 算了不管他

嗯 深入函數指針(變态來一波)

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

const double* f2(const double [], int n) 

const double* f3(const double*, int n)

這三個函數聲明是同一個意思 

 改成用函數指針表示(直接初始化):

const double* (*p1)(const double*, int n) = f1;

可以使用 auto自動推斷類型

auto p2 = f2;

那麼 如下調用函數都是OK的 (*p1)(av, 2) , p2(av, 2) (av是一個double數組)

然後:

造門搞一個函數指針數組 指向這3個函數

const double* (*pa[3])(const double*, int) = {f1, f2, f3};

這裡表示3個指針元素的函數數組 指向3個函數并傳回const double指針

這裡不能使用auto 因為auto不能用于初始化清單 隻能用于單值初始化

但可以這樣 auto pb = pa;

是以 現在pb和pa 都是指向函數指針數組第一個元素的指針(f1)

那麼 , 如何用呢?

比如使用數組第二個元素

const double* px = pa[1[(av, 3)(傳參)

或者 (*pb[1])(av, 3)(我感覺 (*(pb + 1))(av, 3)也行)

如果要擷取傳回資料的值

const double x = *pa[1[(av, 3)

const double x = *(*pb[1])(av, 3)

然後再來一個  建立一個指向該函數指針數組的指針

阿西吧~

自動的辦法: auto pc = &pa;

手動的辦法:

const double* (*(*pd)[3])(const double *, int) = &pa;

解釋下

(*pd)[3]表示的是一個數組指針, 指向3個函數指針的數組 

*(*pd)[3]表示的是該數組的指針, 

const double* 表示的是函數傳回的資料類型 因為函數指針必須要跟函數的傳回值類型一緻

那麼在解引用方面

*pd表示的是該函數指針數組,* (*pd)[i](av, 3) 表示的是第i元素所指向的函數(要傳參)的傳回值資料(const double *)

*(*(*pd)[i])(av, 3) 是得到傳回值資料的值(const double)

然後針對數組指針:

**&pa == *pa == pa[0]

因為&pa代表的是整個數組的位址

卧槽 終于理順了 有點想吐了

示例:

#include <iostream>

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

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

  const double* (*p1)(const double*, int) = f1;
  auto p2 = f2;
  cout << "Using pointers to functions:\n";
  cout << " Address Value\n";
  cout << (*p1)(av, 3) << ": " << *(*p1)(av, 3) << endl;
  cout << p2(av, 3) << ": " << *p2(av, 3) << endl;

  const double* (*pa[3])(const double*, int) = {f1, f2, f3};
  auto pb = pa;
  cout << "\nUsing an array of pointers to functions:\n";
  cout << " Address Vlue\n";
  for (int i = 0; i < 3; i++)
    cout << pa[i](av, 3) << ": " << *pa[i](av, 3) << endl;
  cout << "\nUsing a pointer to a pointer to a function:\n";
  cout << " Address Value\n";
  for (int i = 0; i < 3; i++)
    cout << pb[i](av, 3) << ": " << *pb[i](av, 3) << endl;

  cout << "\nUsing pointers to an array of pointers:\n";
  cout << " Address Value\n";
  auto pc = &pa;
  cout << (*pc)[0](av, 3) << ": " << *(*pc)[0](av, 3) << endl;
  const double* (*(*pd)[3])(const double*, int) = &pa;
  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;
}
           

除了使用auto來簡化定義變量外還可以使用typedef

typedef const double* (*p_fun)(const double *, int) 

p_fun = f1

p_fun pa[3] = {f1, f2, f3}

p_fun (*pd)[3] = &pa

第七章完結。我腦袋可能要休息下

繼續閱讀